SQLite

Check-in Differences
Login

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

Difference From 1b256d97b553a961 To 884b4b7e502b4e99

2021-05-11
11:25
Fixes for cksmvfs and rbu so that they work together. (Leaf check-in: ce8b589e user: dan tags: branch-3.35)
2021-04-19
19:07
Merge in the 3.35.5 patches. (check-in: 35d1c9a5 user: drh tags: reuse-schema-3.35)
18:32
Version 3.35.5 (check-in: 1b256d97 user: drh tags: release, branch-3.35, version-3.35.5)
12:05
Update the version number to 3.35.5. (check-in: d917b70a user: drh tags: branch-3.35)
2019-04-23
15:21
Minor simplification of NULL value handling for STAT4. Cherrypick of [69bad9257f8db6a2] from trunk. (check-in: 442c177d user: mistachkin tags: branch-3.28)
2019-04-17
11:34
Faster and smaller implementation of sqlite3StrICmp(). (check-in: 7ac500fb user: drh tags: trunk)
2019-04-16
19:49
Version 3.28.0 (check-in: 884b4b7e user: drh tags: trunk, release, version-3.28.0)
11:21
Avoid a sanitizer error (pointer arithmatic overflow) in vdbesort.c. (check-in: af61a2fc user: dan tags: trunk)

Changes to Makefile.in.

186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
186
187
188
189
190
191
192


193
194
195
196
197
198
199
200







-
-
+







         notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
         pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
         random.lo resolve.lo rowset.lo rtree.lo \
         sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
         table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
         update.lo userauth.lo upsert.lo util.lo vacuum.lo \
         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
         vdbetrace.lo vdbevtab.lo \
         wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
         vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
         window.lo utf.lo vtab.lo

# Object files for the amalgamation.
#
LIBOBJS1 = sqlite3.lo

# Determine the real value of LIBOBJ based on the 'configure' script
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
292
293
294
295
296
297
298

299
300
301
302
303
304
305







-







  $(TOP)/src/vdbe.h \
  $(TOP)/src/vdbeapi.c \
  $(TOP)/src/vdbeaux.c \
  $(TOP)/src/vdbeblob.c \
  $(TOP)/src/vdbemem.c \
  $(TOP)/src/vdbesort.c \
  $(TOP)/src/vdbetrace.c \
  $(TOP)/src/vdbevtab.c \
  $(TOP)/src/vdbeInt.h \
  $(TOP)/src/vtab.c \
  $(TOP)/src/vxworks.h \
  $(TOP)/src/wal.c \
  $(TOP)/src/wal.h \
  $(TOP)/src/walker.c \
  $(TOP)/src/where.c \
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
434
435
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 \
  $(TOP)/ext/misc/fileio.c \
  $(TOP)/ext/misc/fuzzer.c \
  $(TOP)/ext/fts5/fts5_tcl.c \
  $(TOP)/ext/fts5/fts5_test_mi.c \
  $(TOP)/ext/fts5/fts5_test_tok.c \
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
498
499
500
501
502
503
504

505
506
507
508
509
510
511







-







  $(TOP)/src/utf.c \
  $(TOP)/src/util.c \
  $(TOP)/src/vdbeapi.c \
  $(TOP)/src/vdbeaux.c \
  $(TOP)/src/vdbe.c \
  $(TOP)/src/vdbemem.c \
  $(TOP)/src/vdbetrace.c \
  $(TOP)/src/vdbevtab.c \
  $(TOP)/src/where.c \
  $(TOP)/src/wherecode.c \
  $(TOP)/src/whereexpr.c \
  $(TOP)/src/window.c \
  parse.c \
  $(TOP)/ext/fts3/fts3.c \
  $(TOP)/ext/fts3/fts3_aux.c \
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
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







-
-
-
+
+
+






-




-







#SHELL_OPT += -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS3_PARENTHESIS
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =

# 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.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
685
686
687
688
689
690
691

692
693
694
695
696
697
698







-








DBFUZZ2_OPTS = \
  -DSQLITE_THREADSAFE=0 \
  -DSQLITE_OMIT_LOAD_EXTENSION \
  -DSQLITE_ENABLE_DESERIALIZE \
  -DSQLITE_DEBUG \
  -DSQLITE_ENABLE_DBSTAT_VTAB \
  -DSQLITE_ENABLE_BYTECODE_VTAB \
  -DSQLITE_ENABLE_RTREE \
  -DSQLITE_ENABLE_FTS4 \
  -DSQLITE_ENABLE_FTS5

dbfuzz2$(TEXE):	$(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
	$(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \
		-DSTANDALONE -o dbfuzz2 \
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1001
1002
1003
1004
1005
1006
1007



1008
1009
1010
1011
1012
1013
1014







-
-
-








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

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

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

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

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

walker.lo:	$(TOP)/src/walker.c $(HDR)
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
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







-
+




-
-
-
-
-
-








-
-
+

-
+
-
-

-








# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h:	parse.c

parse.c:	$(TOP)/src/parse.y lemon$(BEXE)
	cp $(TOP)/src/parse.y .
	./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y
	./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y

sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION
	$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h

sqlite3rc.h:	$(TOP)/src/sqlite3.rc $(TOP)/VERSION
	echo '#ifndef SQLITE_RESOURCE_VERSION' >$@
	echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@
	cat $(TOP)/VERSION | $(TCLSH_CMD) $(TOP)/tool/replace.tcl exact . , >>$@
	echo '#endif' >>sqlite3rc.h

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

# Source files that go into making shell.c
SHELL_SRC = \
	$(TOP)/src/shell.c.in \
        $(TOP)/ext/misc/appendvfs.c \
	$(TOP)/ext/misc/completion.c \
        $(TOP)/ext/misc/decimal.c \
	$(TOP)/ext/misc/shathree.c \
	$(TOP)/ext/misc/fileio.c \
        $(TOP)/ext/misc/ieee754.c \
	$(TOP)/ext/misc/completion.c \
        $(TOP)/ext/misc/series.c \
	$(TOP)/ext/misc/shathree.c \
	$(TOP)/ext/misc/sqlar.c \
        $(TOP)/ext/misc/uint.c \
	$(TOP)/ext/expert/sqlite3expert.c \
	$(TOP)/ext/expert/sqlite3expert.h \
	$(TOP)/ext/misc/zipfile.c \
	$(TOP)/ext/misc/memtrace.c \
        $(TOP)/src/test_windirent.c

shell.c:	$(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
1196
1197
1198
1199
1200
1201
1202
1203

1204
1205
1206

1207
1208
1209
1210
1211
1212
1213
1174
1175
1176
1177
1178
1179
1180

1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191







-
+


-
+







   fts5parse.c fts5parse.h \
   $(TOP)/ext/fts5/fts5_storage.c \
   $(TOP)/ext/fts5/fts5_tokenize.c \
   $(TOP)/ext/fts5/fts5_unicode2.c \
   $(TOP)/ext/fts5/fts5_varint.c \
   $(TOP)/ext/fts5/fts5_vocab.c  \

fts5parse.c:	$(TOP)/ext/fts5/fts5parse.y lemon$(BEXE)
fts5parse.c:	$(TOP)/ext/fts5/fts5parse.y lemon
	cp $(TOP)/ext/fts5/fts5parse.y .
	rm -f fts5parse.h
	./lemon$(BEXE) $(OPTS) -S fts5parse.y
	./lemon$(BEXE) $(OPTS) fts5parse.y

fts5parse.h: fts5parse.c

fts5.c: $(FTS5_SRC)
	$(TCLSH_CMD) $(TOP)/ext/fts5/tool/mkfts5c.tcl
	cp $(TOP)/ext/fts5/fts5.h .

1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1207
1208
1209
1210
1211
1212
1213

1214

1215
1216
1217
1218
1219
1220
1221







-

-







TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
TESTFIXTURE_FLAGS += -DBUILD_sqlite
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DESERIALIZE
TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC

TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
TESTFIXTURE_SRC1 = sqlite3.c
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c
TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION))

testfixture$(TEXE):	$(TESTFIXTURE_SRC)
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
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








+
+
+
+

-
+















-
+














-
-
-







fulltestonly:	$(TESTPROGS) fuzztest
	./testfixture$(TEXE) $(TOP)/test/full.test

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

fastfuzztest:	fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
	./fuzzcheck$(TEXE) --limit-mem 100M $(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 ./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)

# Minimal testing that runs in less than 3 minutes
#
quicktest:	./testfixture$(TEXE)
	./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS)

# This is the common case.  Run many tests that do not take too long,
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
#
test:	fuzztest sourcetest $(TESTPROGS) tcltest
test:	fastfuzztest sourcetest $(TESTPROGS) tcltest

# Run a test using valgrind.  This can take a really long time
# because valgrind is so much slower than a native machine.
#
valgrindtest:	$(TESTPROGS) valgrindfuzz
	OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS)

# A very fast test that checks basic sanity.  The name comes from
# the 60s-era electronics testing:  "Turn it on and see if smoke
# comes out."
#
smoketest:	$(TESTPROGS) fuzzcheck$(TEXE)
	./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)

shelltest: $(TESTPROGS)
	./testfixture$(TEXT) $(TOP)/test/permutations.test shell

sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in
	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c

sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
	$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)

sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1352
1353
1354
1355
1356
1357
1358



1359
1360
1361
1362
1363
1364
1365







-
-
-








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)
1403
1404
1405
1406
1407
1408
1409
1410

1411
1412
1413

1414
1415
1416
1417
1418
1419
1420
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386

1387
1388
1389
1390
1391
1392
1393
1394







-
+


-
+







	nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0
	echo '0 errors out of 1 tests'

# Build the amalgamation-autoconf package.  The amalamgation-tarball target builds
# a tarball named for the version number.  Ex:  sqlite-autoconf-3110000.tar.gz.
# The snapshot-tarball target builds a tarball named by the SHA1 hash
#
amalgamation-tarball: sqlite3.c sqlite3rc.h
amalgamation-tarball: sqlite3.c
	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal

snapshot-tarball: sqlite3.c sqlite3rc.h
snapshot-tarball: sqlite3.c
	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot

# The next two rules are used to support the "threadtest" target. Building
# threadtest runs a few thread-safety tests that are implemented in C. This
# target is invoked by the releasetest.tcl script.
#
THREADTEST3_SRC = $(TOP)/test/threadtest3.c    \

Changes to Makefile.linux-gcc.

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







-
+


















-
-
+
+














-
-
-
+
+
+
+
+











-
+




















+
+
-
+
+
+




-
+
+
+







#    that contains this "Makefile.in" and the "configure.in" script.
#
TOP = ../sqlite

#### C Compiler and options for use in building executables that
#    will run on the platform that is doing the build.
#
BCC = gcc -g -O0
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0

#### If the target operating system supports the "usleep()" system
#    call, then define the HAVE_USLEEP macro for all C modules.
#
#USLEEP = 
USLEEP = -DHAVE_USLEEP=1

#### If you want the SQLite library to be safe for use within a 
#    multi-threaded program, then define the following macro
#    appropriately:
#
#THREADSAFE = -DTHREADSAFE=1
THREADSAFE = -DTHREADSAFE=0

#### Specify any extra linker options needed to make the library
#    thread safe
#
THREADLIB = -lpthread -lm -ldl
#THREADLIB = 
#THREADLIB = -lpthread
THREADLIB = 

#### Specify any extra libraries needed to access required functions.
#
#TLIBS = -lrt    # fdatasync on Solaris 8
TLIBS = 

#### Leave SQLITE_DEBUG undefined for maximum speed.  Use SQLITE_DEBUG=1
#    to check for memory leaks.  Use SQLITE_DEBUG=2 to print a log of all
#    malloc()s and free()s in order to track down memory leaks.
#    
#    SQLite uses some expensive assert() statements in the inner loop.
#    You can make the library go almost twice as fast if you compile
#    with -DNDEBUG=1
#
OPTS += -DSQLITE_DEBUG=1
OPTS += -DSQLITE_ENABLE_WHERETRACE
OPTS += -DSQLITE_ENABLE_SELECTTRACE
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS = 
OPTS = -DNDEBUG=1
OPTS += -DHAVE_FDATASYNC=1

#### The suffix to add to executable files.  ".exe" for windows.
#    Nothing for unix.
#
#EXE = .exe
EXE =

#### C Compile and options for use in building executables that 
#    will run on the target platform.  This is usually the same
#    as BCC, unless you are cross-compiling.
#
TCC = gcc -O0
TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive

#### Tools used to build a static library.
#
AR = ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib

MKSHLIB = gcc -shared
SO = so
SHPREFIX = lib
# SO = dll
# SHPREFIX =

#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcl/include/tcl8.6
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux

#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcl/lib/libtcl8.6.a -lm -lpthread -ldl -lz
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc

#### Additional objects for SQLite library when TCL support is enabled.
#TCLOBJ =
TCLOBJ = tclsqlite.o

#### Compiler options needed for programs that use the readline() library.
#

Changes to Makefile.msc.

69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+







# If necessary, create a list of harmless compiler warnings to disable when
# compiling the various tools.  For the SQLite source code itself, warnings,
# if any, will be disabled from within it.
#
!IFNDEF NO_WARN
!IF $(USE_FULLWARN)!=0
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
!ENDIF
!ENDIF

# Set this non-0 to use the library paths and other options necessary for
# Windows Phone 8.1.
#
!IFNDEF USE_WP81_OPTS
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
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







-
-
-
-
-
-
-
-
-














-
-
-
-
-
-







# 5 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
# 6 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
#
!IFNDEF DEBUG
DEBUG = 0
!ENDIF

# <<mark>>
# Disable use of the --linemacros argument to the mksqlite3c.tcl tool, which
# is used to build the amalgamation.
#
!IFNDEF NO_LINEMACROS
NO_LINEMACROS = 0
!ENDIF
# <</mark>>

# Enable use of available compiler optimizations?  Normally, this should be
# non-zero.  Setting this to zero, thus disabling all compiler optimizations,
# can be useful for testing.
#
!IFNDEF OPTIMIZATIONS
OPTIMIZATIONS = 2
!ENDIF

# Set this to non-0 to enable support for the session extension.
#
!IFNDEF SESSION
SESSION = 0
!ENDIF

# Set this to non-0 to enable support for the rbu extension.
#
!IFNDEF RBU
RBU = 0
!ENDIF

# Set the source code file to be used by executables and libraries when
# they need the amalgamation.
#
!IFNDEF SQLITE3C
!IF $(SPLIT_AMALGAMATION)!=0
SQLITE3C = sqlite3-all.c
!ELSE
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
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







-
+













-
-
-
-
-
-
-
-
-
-







OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF

# Should the session extension be enabled?  If so, add compilation options
# 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

# These are the "extended" SQLite compilation options used when compiling for
# the Windows 10 platform.
#
!IFNDEF EXT_FEATURE_FLAGS
!IF $(FOR_WIN10)!=0
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4=1
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_SYSTEM_MALLOC=1
784
785
786
787
788
789
790
791

792
793
794
795
796
797
798
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773







-
+







MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c-noext.tcl
!ELSE
MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c.tcl
!ENDIF
!ENDIF

!IFNDEF MKSQLITE3C_ARGS
!IF $(DEBUG)>1 && $(NO_LINEMACROS)==0
!IF $(DEBUG)>1
MKSQLITE3C_ARGS = --linemacros
!ELSE
MKSQLITE3C_ARGS =
!ENDIF
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
MKSQLITE3C_ARGS = $(MKSQLITE3C_ARGS) --useapicall
!ENDIF
1255
1256
1257
1258
1259
1260
1261
1262

1263
1264
1265
1266
1267
1268
1269
1270
1230
1231
1232
1233
1234
1235
1236

1237

1238
1239
1240
1241
1242
1243
1244







-
+
-







         notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
         pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
         random.lo resolve.lo rowset.lo rtree.lo \
         sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
         table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
         update.lo upsert.lo util.lo vacuum.lo \
         vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
         vdbetrace.lo vdbevtab.lo wal.lo walker.lo where.lo wherecode.lo \
         vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
         whereexpr.lo \
         window.lo utf.lo vtab.lo
# <</mark>>

# Object files for the amalgamation.
#
LIBOBJS1 = sqlite3.lo

1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1337
1338
1339
1340
1341
1342
1343

1344
1345
1346
1347
1348
1349
1350







-







  $(TOP)\src\vdbe.c \
  $(TOP)\src\vdbeapi.c \
  $(TOP)\src\vdbeaux.c \
  $(TOP)\src\vdbeblob.c \
  $(TOP)\src\vdbemem.c \
  $(TOP)\src\vdbesort.c \
  $(TOP)\src\vdbetrace.c \
  $(TOP)\src\vdbevtab.c \
  $(TOP)\src\vtab.c \
  $(TOP)\src\wal.c \
  $(TOP)\src\walker.c \
  $(TOP)\src\where.c \
  $(TOP)\src\wherecode.c \
  $(TOP)\src\whereexpr.c \
  $(TOP)\src\window.c
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
1467
1468
1469
1470
1471
1472
1473

1474
1475
1476
1477
1478
1479
1480
1481







-
+







  $(SQLITETCLDECLSH)
!ELSE
SRC12 =
!ENDIF

# All source code files.
#
SRC = $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11) $(SRC12)
SRC = $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11)

# Source code to the test files.
#
TESTSRC = \
  $(TOP)\src\test1.c \
  $(TOP)\src\test2.c \
  $(TOP)\src\test3.c \
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1529
1530
1531
1532
1533
1534
1535

1536

1537
1538

1539
1540
1541
1542
1543
1544
1545







-

-


-








# 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 \
  $(TOP)\ext\misc\fileio.c \
  $(TOP)\ext\misc\fuzzer.c \
  $(TOP)\ext\fts5\fts5_tcl.c \
  $(TOP)\ext\fts5\fts5_test_mi.c \
  $(TOP)\ext\fts5\fts5_test_tok.c \
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1668
1669
1670
1671
1672
1673
1674

1675
1676
1677
1678
1679
1680
1681







-







FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB

FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0

1770
1771
1772
1773
1774
1775
1776
1777

1778
1779
1780
1781
1782
1783
1784
1739
1740
1741
1742
1743
1744
1745

1746
1747
1748
1749
1750
1751
1752
1753







-
+







$(SQLITE3DLL):	$(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)

# <<block2>>
sqlite3.def:	libsqlite3.lib
	echo EXPORTS > sqlite3.def
	dumpbin /all libsqlite3.lib \
		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@]*)(?:@\d+)?$$" \1 \
		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@]*)(?:@\d+)?$$" \1 \
		| sort >> sqlite3.def
# <</block2>>

$(SQLITE3EXE):	shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) shell.c $(SHELL_CORE_SRC) \
		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)

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







-

-





-
+

+














-
+
-







	for %i in ($(SRC07)) do copy /Y %i tsrc
	for %i in ($(SRC08)) do copy /Y %i tsrc
	for %i in ($(SRC09)) do copy /Y %i tsrc
	for %i in ($(SRC10)) do copy /Y %i tsrc
	for %i in ($(SRC11)) do copy /Y %i tsrc
	for %i in ($(SRC12)) do copy /Y %i tsrc
	copy /Y fts5.c tsrc
	copy /B tsrc\fts5.c +,,
	copy /Y fts5.h tsrc
	copy /B tsrc\fts5.h +,,
	del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL
	$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new
	move vdbe.new tsrc\vdbe.c
	echo > .target_source

sqlite3.c:	.target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL)
sqlite3.c:	.target_source sqlite3ext.h $(MKSQLITE3C_TOOL)
	$(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS)
	copy $(TOP)\ext\session\sqlite3session.h .

sqlite3-all.c:	sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
	$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
# <</mark>>

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

# <<mark>>
# Rules to build the LEMON compiler generator
#
lempar.c:	$(TOP)\tool\lempar.c
	copy /Y $(TOP)\tool\lempar.c .
	copy $(TOP)\tool\lempar.c .
	copy /B lempar.c +,,

lemon.exe:	$(TOP)\tool\lemon.c lempar.c
	$(BCC) $(NO_WARN) -Daccess=_access \
		-Fe$@ $(TOP)\tool\lemon.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)

# <<mark>>
# Rules to build the source-id generator tool
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2093
2094
2095
2096
2097
2098
2099



2100
2101
2102
2103
2104
2105
2106







-
-
-








vdbesort.lo:	$(TOP)\src\vdbesort.c $(HDR)
	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vdbesort.c

vdbetrace.lo:	$(TOP)\src\vdbetrace.c $(HDR)
	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vdbetrace.c

vdbevtab.lo:	$(TOP)\src\vdbevtab.c $(HDR)
	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vdbevtab.c

vtab.lo:	$(TOP)\src\vtab.c $(HDR)
	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vtab.c

wal.lo:	$(TOP)\src\wal.c $(HDR)
	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\wal.c

walker.lo:	$(TOP)\src\walker.c $(HDR)
2173
2174
2175
2176
2177
2178
2179
2180

2181
2182

2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213

2214
2215
2216
2217
2218

2219
2220
2221
2222
2223
2224
2225
2137
2138
2139
2140
2141
2142
2143

2144


2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156

2157
2158




2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169


2170
2171




2172
2173
2174
2175
2176
2177
2178
2179







-
+
-
-
+











-


-
-
-
-











-
-
+

-
-
-
-
+








# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h:	parse.c

parse.c:	$(TOP)\src\parse.y lemon.exe
	del /Q parse.y parse.h parse.h.temp 2>NUL
	copy /Y $(TOP)\src\parse.y .
	copy $(TOP)\src\parse.y .
	copy /B parse.y +,,
	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S parse.y
	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y

$(SQLITE3H):	$(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION
	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS)

sqlite3ext.h:	.target_source
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
	type tsrc\sqlite3ext.h | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*\)" "(SQLITE_CALLBACK *)" \
		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_APICALL *" > sqlite3ext.h
	copy /Y sqlite3ext.h tsrc\sqlite3ext.h
!ELSE
	copy /Y tsrc\sqlite3ext.h sqlite3ext.h
	copy /B sqlite3ext.h +,,
!ENDIF

sqlite3session.h:	$(TOP)\ext\session\sqlite3session.h
	copy /Y $(TOP)\ext\session\sqlite3session.h .
	copy /B sqlite3session.h +,,

mkkeywordhash.exe:	$(TOP)\tool\mkkeywordhash.c
	$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \
		$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)

keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
	.\mkkeywordhash.exe > keywordhash.h

# Source files that go into making shell.c
SHELL_SRC = \
	$(TOP)\src\shell.c.in \
	$(TOP)\ext\misc\appendvfs.c \
	$(TOP)\ext\misc\completion.c \
        $(TOP)\ext\misc\decimal.c \
	$(TOP)\ext\misc\shathree.c \
	$(TOP)\ext\misc\fileio.c \
        $(TOP)\ext\misc\ieee754.c \
        $(TOP)\ext\misc\series.c \
	$(TOP)\ext\misc\shathree.c \
	$(TOP)\ext\misc\uint.c \
	$(TOP)\ext\misc\completion.c \
	$(TOP)\ext\expert\sqlite3expert.c \
	$(TOP)\ext\expert\sqlite3expert.h \
	$(TOP)\ext\misc\memtrace.c \
	$(TOP)\src\test_windirent.c

# If use of zlib is enabled, add the "zipfile.c" source file.
#
2342
2343
2344
2345
2346
2347
2348
2349

2350
2351
2352

2353
2354
2355
2356
2357
2358

2359
2360
2361
2362
2363

2364
2365
2366
2367
2368
2369
2370
2371
2296
2297
2298
2299
2300
2301
2302

2303

2304

2305
2306
2307
2308
2309
2310

2311

2312
2313
2314

2315

2316
2317
2318
2319
2320
2321
2322







-
+
-

-
+





-
+
-



-
+
-







   $(TOP)\ext\lsm1\lsm_tree.c \
   $(TOP)\ext\lsm1\lsm_unix.c \
   $(TOP)\ext\lsm1\lsm_varint.c \
   $(TOP)\ext\lsm1\lsm_vtab.c \
   $(TOP)\ext\lsm1\lsm_win32.c

fts5parse.c:	$(TOP)\ext\fts5\fts5parse.y lemon.exe
	copy /Y $(TOP)\ext\fts5\fts5parse.y .
	copy $(TOP)\ext\fts5\fts5parse.y .
	copy /B fts5parse.y +,,
	del /Q fts5parse.h 2>NUL
	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S fts5parse.y
	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) fts5parse.y

fts5parse.h:	fts5parse.c

fts5.c:	$(FTS5_SRC)
	$(TCLSH_CMD) $(TOP)\ext\fts5\tool\mkfts5c.tcl
	copy /Y $(TOP)\ext\fts5\fts5.h .
	copy $(TOP)\ext\fts5\fts5.h .
	copy /B fts5.h +,,

lsm1.c:	$(LSM1_SRC)
	$(TCLSH_CMD) $(TOP)\ext\lsm1\tool\mklsm1c.tcl
	copy /Y $(TOP)\ext\lsm1\lsm.h .
	copy $(TOP)\ext\lsm1\lsm.h .
	copy /B lsm.h +,,

fts5.lo:	fts5.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c fts5.c

fts5_ext.lo:	fts5.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) $(NO_WARN) -c fts5.c

2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2336
2337
2338
2339
2340
2341
2342

2343
2344

2345
2346
2347
2348
2349
2350
2351







-


-







TESTFIXTURE_FLAGS = -DTCLSH_INIT_PROC=sqlite3TestInit -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CKSUMVFS_STATIC=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)

TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
!IF $(USE_AMALGAMATION)==0
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
!ELSE
2452
2453
2454
2455
2456
2457
2458



2459
2460
2461
2462
2463
2464
2465
2466
2467
2468

2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419

2420
2421
2422
2423
2424
2425
2426
2427



2428
2429
2430
2431
2432
2433
2434







+
+
+









-
+







-
-
-







queryplantest:	testfixture.exe shell
	@set PATH=$(LIBTCLPATH);$(PATH)
	.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)

fuzztest:	fuzzcheck.exe
	.\fuzzcheck.exe $(FUZZDATA)

fastfuzztest:	fuzzcheck.exe
	.\fuzzcheck.exe --limit-mem 100M $(FUZZDATA)

# Minimal testing that runs in less than 3 minutes (on a fast machine)
#
quicktest:	testfixture.exe sourcetest
	@set PATH=$(LIBTCLPATH);$(PATH)
	.\testfixture.exe $(TOP)\test\extraquick.test $(TESTOPTS)

# This is the common case.  Run many tests that do not take too long,
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
#
test:	$(TESTPROGS) sourcetest fuzztest
test:	$(TESTPROGS) sourcetest fastfuzztest
	@set PATH=$(LIBTCLPATH);$(PATH)
	.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)

smoketest:	$(TESTPROGS)
	@set PATH=$(LIBTCLPATH);$(PATH)
	.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)

shelltest: $(TESTPROGS)
	.\testfixture.exe $(TOP)\test\permutations.test shell

sqlite3_analyzer.c:	$(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(SQLITE_TCL_DEP)
	$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@

sqlite3_analyzer.exe:	sqlite3_analyzer.c $(LIBRESOBJS)
	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)

Changes to README.md.

302
303
304
305
306
307
308















309


310
311
312



313
314
315


316
317
318
319
320
321
322
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







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

-
-
+
+
+

-
-
+
+








There are many other source files.  Each has a succinct header comment that
describes its purpose and role within the larger system.

<a name="vauth"></a>
## Verifying Code Authenticity

If you obtained an SQLite source tree from a secondary source, such as a
GitHub mirror, and you want to verify that it has not been altered, there
are a couple of ways to do that.

If you have a release version of SQLite, and you are using the
`sqlite3.c` amalgamation, then SHA3-256 hashes for the amalgamation are
available in the [change log](https://www.sqlite.org/changes.html) on
the official website.  After building the `sqlite3.c` file, you can check
that it is authentic by comparing the hash.  This does not ensure that the
test scripts are unaltered, but it does validate the deliverable part of
the code and the verification process only involves computing and
comparing a single hash.

For versions other than an official release, or if you are building the
`sqlite3.c` amalgamation using non-standard build options, the verification
The `manifest` file at the root directory of the source tree
process is a little more involved.  The `manifest` file at the root directory
of the source tree
contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for 
older files) for every source file in the repository.
The SHA3-256 hash of the `manifest`
older files) for every source file in the repository.  You can write a script
to extracts hashes from `manifest` and verifies the hashes against the 
corresponding files in the source tree.  The SHA3-256 hash of the `manifest`
file itself is the official name of the version of the source tree that you
have. The `manifest.uuid` file should contain the SHA3-256 hash of the
`manifest` file. If all of the above hash comparisons are correct, then
have.  The `manifest.uuid` file should contain the SHA3-256 hash of the
`manifest` file.  If all of the above hash comparisons are correct, then
you can be confident that your source tree is authentic and unadulterated.

The format of the `manifest` file should be mostly self-explanatory, but
if you want details, they are available
[here](https://fossil-scm.org/fossil/doc/trunk/www/fileformat.wiki#manifest).

## Contacts

Changes to VERSION.

1


1
-
+
3.35.5
3.28.0

Changes to autoconf/Makefile.am.

9
10
11
12
13
14
15
16

17
18
19
20
9
10
11
12
13
14
15

16
17
18
19
20







-
+




EXTRA_sqlite3_SOURCES = sqlite3.c
sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@
sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS)

include_HEADERS = sqlite3.h sqlite3ext.h

EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc sqlite3rc.h README.txt Replace.cs Makefile.fallback
EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback
pkgconfigdir = ${libdir}/pkgconfig
pkgconfig_DATA = sqlite3.pc

man_MANS = sqlite3.1

Changes to autoconf/Makefile.msc.

69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+







# If necessary, create a list of harmless compiler warnings to disable when
# compiling the various tools.  For the SQLite source code itself, warnings,
# if any, will be disabled from within it.
#
!IFNDEF NO_WARN
!IF $(USE_FULLWARN)!=0
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
!ENDIF
!ENDIF

# Set this non-0 to use the library paths and other options necessary for
# Windows Phone 8.1.
#
!IFNDEF USE_WP81_OPTS
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
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







-














-
-
-
-
-
-







# 5 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
# 6 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
#
!IFNDEF DEBUG
DEBUG = 0
!ENDIF


# Enable use of available compiler optimizations?  Normally, this should be
# non-zero.  Setting this to zero, thus disabling all compiler optimizations,
# can be useful for testing.
#
!IFNDEF OPTIMIZATIONS
OPTIMIZATIONS = 2
!ENDIF

# Set this to non-0 to enable support for the session extension.
#
!IFNDEF SESSION
SESSION = 0
!ENDIF

# Set this to non-0 to enable support for the rbu extension.
#
!IFNDEF RBU
RBU = 0
!ENDIF

# Set the source code file to be used by executables and libraries when
# they need the amalgamation.
#
!IFNDEF SQLITE3C
!IF $(SPLIT_AMALGAMATION)!=0
SQLITE3C = sqlite3-all.c
!ELSE
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
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







-
+













-
-
-
-
-
-
-
-
-
-







OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF

# Should the session extension be enabled?  If so, add compilation options
# 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

# These are the "extended" SQLite compilation options used when compiling for
# the Windows 10 platform.
#
!IFNDEF EXT_FEATURE_FLAGS
!IF $(FOR_WIN10)!=0
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4=1
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_SYSTEM_MALLOC=1
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
974
975
976
977
978
979
980

981
982
983
984
985
986
987
988







-
+








Replace.exe:
	$(CSC) /target:exe $(TOP)\Replace.cs

sqlite3.def:	Replace.exe $(LIBOBJ)
	echo EXPORTS > sqlite3.def
	dumpbin /all $(LIBOBJ) \
		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
		| sort >> sqlite3.def

$(SQLITE3EXE):	shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) shell.c $(SHELL_CORE_SRC) \
		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)


Changes to autoconf/configure.ac.

83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
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
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
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
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
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-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"
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE"
  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/configure.ac.

15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29







-
+







# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided.  These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
#-----------------------------------------------------------------------

AC_INIT([sqlite], [3.32.0])
AC_INIT([sqlite], [3.7.4])

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------

Changes to autoconf/tea/win/makefile.vc.

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







-
+

-
+






+
+
+








-
+








# 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]
!endif
# get project version from row "AC_INIT([sqlite], [3.x.y])"
# get project version from row "AC_INIT([sqlite], [3.7.14])"
!if [echo DOTVERSION = \>> versions.vc] \
   && [nmakehlp -V ..\configure.ac AC_INIT >> versions.vc]
   && [nmakehlp -V ..\configure.in AC_INIT >> versions.vc]
!endif
!include "versions.vc"

VERSION         = $(DOTVERSION:.=)
STUBPREFIX      = $(PROJECT)stub

DLLOBJS = \
	$(TMP_DIR)\tclsqlite3.obj

#-------------------------------------------------------------------------
# Target names and paths ( shouldn't need changing )
#-------------------------------------------------------------------------

BINROOT		= .
ROOT            = ..

PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME	= $(PROJECT).$(EXT)
PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)

PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)

### Make sure we use backslash only.
PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
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
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







-
-
-
-
-
-
-
-
-
-
-



















-
+















-
-
+
+







GENERICDIR	= $(ROOT)\generic
WINDIR		= $(ROOT)\win
LIBDIR          = $(ROOT)\library
DOCDIR		= $(ROOT)\doc
TOOLSDIR	= $(ROOT)\tools
COMPATDIR	= $(ROOT)\compat

### Figure out where the primary source code file(s) is/are.
!if exist("$(ROOT)\..\..\sqlite3.c") && exist("$(ROOT)\..\..\src\tclsqlite.c")
SQL_INCLUDES = -I"$(ROOT)\..\.."
SQLITE_SRCDIR = $(ROOT)\..\..
TCLSQLITE_SRCDIR = $(ROOT)\..\..\src
DLLOBJS = $(TMP_DIR)\sqlite3.obj $(TMP_DIR)\tclsqlite.obj
!else
TCLSQLITE_SRCDIR = $(ROOT)\generic
DLLOBJS = $(TMP_DIR)\tclsqlite3.obj
!endif

#---------------------------------------------------------------------
# Compile flags
#---------------------------------------------------------------------

!if !$(DEBUG)
!if $(OPTIMIZING)
### This cranks the optimization level to maximize speed
cdebug	= -O2 -Op -Gs
!else
cdebug	=
!endif
!else if "$(MACHINE)" == "IA64"
### Warnings are too many, can't support warnings into errors.
cdebug	= -Z7 -Od -GZ
!else
cdebug	= -Z7 -WX -Od -GZ
!endif

### Declarations common to all compiler options
cflags = -nologo -c -W3 -D_CRT_SECURE_NO_WARNINGS -YX -Fp$(TMP_DIR)^\
cflags = -nologo -c -W3 -YX -Fp$(TMP_DIR)^\

!if $(MSVCRT)
!if $(DEBUG)
crt = -MDd
!else
crt = -MD
!endif
!else
!if $(DEBUG)
crt = -MTd
!else
crt = -MT
!endif
!endif

INCLUDES	= $(SQL_INCLUDES) $(TCL_INCLUDES) -I"$(WINDIR)" \
                  -I"$(GENERICDIR)" -I"$(ROOT)\.."
INCLUDES	= $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)" \
                  -I"$(ROOT)\.."
BASE_CLFAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES) \
                  -DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \
                  -DSQLITE_ENABLE_FTS3=1 -DSQLITE_OMIT_DEPRECATED=1
CON_CFLAGS	= $(cflags) $(cdebug) $(crt) -DCONSOLE -DSQLITE_ENABLE_FTS3=1
TCL_CFLAGS	= -DBUILD_sqlite -DUSE_TCL_STUBS \
                  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" $(BASE_CLFAGS) \
                  $(OPTDEFINES)
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
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







-
-
-
+
+
+
+

-
-
+
+
-
+
+

-
-
+
+
-
+
+







$(PRJSTUBLIB): $(PRJSTUBOBJS)
	$(lib32) -nologo -out:$@ $(PRJSTUBOBJS)

#---------------------------------------------------------------------
# Implicit rules
#---------------------------------------------------------------------

$(TMP_DIR)\sqlite3.obj:		$(SQLITE_SRCDIR)\sqlite3.c
	$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
		-c $(SQLITE_SRCDIR)\sqlite3.c
{$(WINDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
$<
<<

$(TMP_DIR)\tclsqlite.obj:	$(TCLSQLITE_SRCDIR)\tclsqlite.c
	$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
		-c $(TCLSQLITE_SRCDIR)\tclsqlite.c
$<
<<

$(TMP_DIR)\tclsqlite3.obj:	$(TCLSQLITE_SRCDIR)\tclsqlite3.c
	$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
		-c $(TCLSQLITE_SRCDIR)\tclsqlite3.c
$<
<<

{$(WINDIR)}.rc{$(TMP_DIR)}.res:
	$(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
!if $(DEBUG)
	-d DEBUG \
!endif
!if $(TCL_THREADS)

Changes to config.guess.

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


+
-
+
+

-
+



-
+








-
+
+
+




-
-
+
+
-
-
-
+
+
+
+

-
+
-
+
+

-
-
+
+








-
+










+
-
+







#! /bin/sh
# Attempt to guess a canonical system name.
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
#   Copyright 1992-2019 Free Software Foundation, Inc.
#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
#   Inc.

timestamp='2019-05-28'
timestamp='2007-07-22'

# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://www.gnu.org/licenses/>.
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program.  This Exception is an additional permission under section 7
# the same distribution terms that you use for the rest of that program.

# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.

# Originally written by Per Bothner <per@bothner.com>.
# Please send patches to <config-patches@gnu.org>.  Submit a context
# diff and a properly formatted ChangeLog entry.
#
# You can get the latest version of this script from:
# This script attempts to guess a canonical system name similar to
# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
# config.sub.  If it succeeds, it prints the system name on stdout, and
# exits with 0.  Otherwise, it exits with 1.
#
# Please send patches to <config-patches@gnu.org>.

# The plan is that this can be called by configure scripts if you
# don't specify an explicit build system type.

me=`echo "$0" | sed -e 's,.*/,,'`

usage="\
Usage: $0 [OPTION]

Output the configuration name of the system \`$me' is run on.

Options:
Operation modes:
  -h, --help         print this help, then exit
  -t, --time-stamp   print date of last modification, then exit
  -v, --version      print version number, then exit

Report bugs and patches to <config-patches@gnu.org>."

version="\
GNU config.guess ($timestamp)

Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright 1992-2019 Free Software Foundation, Inc.
Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."

help="
Try \`$me --help' for more information."

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







+
+











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


-
+








-
+
-
-
-
-
-
-
-
+
+

-
+
+
+
+

-
-
+



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



-
+


-
+









-
+
-
-
-
-
+
+





-
-
-
-
-
-
+


-
-
+
+
-
-
-

-
+

-
+









-
+
-
-
-
-
-
-
-







-
+




-
+





-
+
-
-
-
-



-
-
-
-
+
-

-
-
-

-
+


-
+


-
+


-
-
-
-
+

-
-
-
-
-
-






-
+









-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+






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




-
+


-
+








-
+


-
+

-
+







  esac
done

if test $# != 0; then
  echo "$me: too many arguments$help" >&2
  exit 1
fi

trap 'exit 1' 1 2 15

# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.

# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.

# Portable tmp directory creation inspired by the Autoconf team.

tmp=
# shellcheck disable=SC2172
trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15

set_cc_for_build() {
    : "${TMPDIR=/tmp}"
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
    # shellcheck disable=SC2039
    { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
    dummy=$tmp/dummy
    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
	,,)    echo "int x;" > "$dummy.c"
	       for driver in cc gcc c89 c99 ; do
		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
		       CC_FOR_BUILD="$driver"
 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
 { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
 { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
 { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
 ,,)    echo "int x;" > $dummy.c ;
	for c in cc gcc c89 c99 ; do
	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
	     CC_FOR_BUILD="$c"; break ;
		       break
		   fi
	       done
	       if test x"$CC_FOR_BUILD" = x ; then
		   CC_FOR_BUILD=no_compiler_found
	       fi
	       ;;
	,,*)   CC_FOR_BUILD=$CC ;;
	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
    esac
}
	  fi ;
	done ;
	if test x"$CC_FOR_BUILD" = x ; then
	  CC_FOR_BUILD=no_compiler_found ;
	fi
	;;
 ,,*)   CC_FOR_BUILD=$CC ;;
 ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
esac ; set_cc_for_build= ;'


# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if test -f /.attbin/uname ; then
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
	PATH=$PATH:/.attbin ; export PATH
fi

UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown

case "$UNAME_SYSTEM" in
if [ "${UNAME_SYSTEM}" = "Linux" ] ; then
Linux|GNU|GNU/*)
	# If the system lacks a compiler, then just pick glibc.
	# We could probably try harder.
	LIBC=gnu

	set_cc_for_build
	cat <<-EOF > "$dummy.c"
	eval $set_cc_for_build
	cat << EOF > $dummy.c
	#include <features.h>
	#if defined(__UCLIBC__)
	#ifdef __UCLIBC__
	# ifdef __UCLIBC_CONFIG_VERSION__
	LIBC=uclibc __UCLIBC_CONFIG_VERSION__
	# else
	LIBC=uclibc
	#elif defined(__dietlibc__)
	LIBC=dietlibc
	# endif
	#else
	LIBC=gnu
	#endif
	EOF
EOF
	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"

	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep LIBC= | sed -e 's: ::g'`
	# If ldd exists, use it to detect musl libc.
	if command -v ldd >/dev/null && \
		ldd --version 2>&1 | grep -q ^musl
	then
	    LIBC=musl
	fi
fi
	;;
esac

# Note: order is significant - the case branches are not exclusive.

case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
    *:NetBSD:*:*)
	# NetBSD (nbsd) targets should (where applicable) match one or
	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
	# switched to ELF, *-*-netbsd* would select the old
	# object file format.  This provides both forward
	# compatibility and a consistent mechanism for selecting the
	# object file format.
	#
	# Note: NetBSD doesn't particularly care about the vendor
	# portion of the name.  We always set it to "unknown".
	sysctl="sysctl -n hw.machine_arch"
	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
	    "/sbin/$sysctl" 2>/dev/null || \
	    "/usr/sbin/$sysctl" 2>/dev/null || \
	    echo unknown)`
	case "$UNAME_MACHINE_ARCH" in
	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
	case "${UNAME_MACHINE_ARCH}" in
	    armeb) machine=armeb-unknown ;;
	    arm*) machine=arm-unknown ;;
	    sh3el) machine=shl-unknown ;;
	    sh3eb) machine=sh-unknown ;;
	    sh5el) machine=sh5le-unknown ;;
	    earmv*)
		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
		machine="${arch}${endian}"-unknown
		;;
	    *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
	esac
	# The Operating System including object format, if it has switched
	# to ELF recently (or will in the future) and ABI.
	case "$UNAME_MACHINE_ARCH" in
	# to ELF recently, or will in the future.
	case "${UNAME_MACHINE_ARCH}" in
	    earm*)
		os=netbsdelf
		;;
	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
		set_cc_for_build
		eval $set_cc_for_build
		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
			| grep -q __ELF__
			| grep __ELF__ >/dev/null
		then
		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
		    # Return netbsd for either.  FIX?
		    os=netbsd
		else
		    os=netbsdelf
		fi
		;;
	    *)
		os=netbsd
	        os=netbsd
		;;
	esac
	# Determine ABI tags.
	case "$UNAME_MACHINE_ARCH" in
	    earm*)
		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
		;;
	esac
	# The OS release
	# Debian GNU/NetBSD machines have a different userland, and
	# thus, need a distinct triplet. However, they do not need
	# kernel version information, so it can be replaced with a
	# suitable tag, in the style of linux-gnu.
	case "$UNAME_VERSION" in
	case "${UNAME_VERSION}" in
	    Debian*)
		release='-gnu'
		;;
	    *)
		release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
		;;
	esac
	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
	# contains redundant information, the shorter form:
	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
	echo "$machine-${os}${release}${abi-}"
	echo "${machine}-${os}${release}"
	exit ;;
    *:Bitrig:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
	echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
	exit ;;
    *:OpenBSD:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
	echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
	exit ;;
    *:LibertyBSD:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
	echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
	exit ;;
    *:MidnightBSD:*:*)
	echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
	exit ;;
    *:ekkoBSD:*:*)
	echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
	exit ;;
    *:SolidBSD:*:*)
	echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
	exit ;;
    macppc:MirBSD:*:*)
	echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
	exit ;;
    *:MirBSD:*:*)
	echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
	exit ;;
    *:Sortix:*:*)
	echo "$UNAME_MACHINE"-unknown-sortix
	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
	exit ;;
    *:Redox:*:*)
	echo "$UNAME_MACHINE"-unknown-redox
	exit ;;
    mips:OSF1:*.*)
        echo mips-dec-osf1
        exit ;;
    alpha:OSF1:*:*)
	case $UNAME_RELEASE in
	*4.0)
		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
		;;
	*5.*)
		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
		;;
	esac
	# According to Compaq, /usr/sbin/psrinfo has been available on
	# OSF/1 and Tru64 systems produced since 1995.  I hope that
	# covers most systems running today.  This code pipes the CPU
	# types through head -n 1, so we only detect the type of CPU 0.
	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
	case "$ALPHA_CPU_TYPE" in
	    "EV4 (21064)")
		UNAME_MACHINE=alpha ;;
		UNAME_MACHINE="alpha" ;;
	    "EV4.5 (21064)")
		UNAME_MACHINE=alpha ;;
		UNAME_MACHINE="alpha" ;;
	    "LCA4 (21066/21068)")
		UNAME_MACHINE=alpha ;;
		UNAME_MACHINE="alpha" ;;
	    "EV5 (21164)")
		UNAME_MACHINE=alphaev5 ;;
		UNAME_MACHINE="alphaev5" ;;
	    "EV5.6 (21164A)")
		UNAME_MACHINE=alphaev56 ;;
		UNAME_MACHINE="alphaev56" ;;
	    "EV5.6 (21164PC)")
		UNAME_MACHINE=alphapca56 ;;
		UNAME_MACHINE="alphapca56" ;;
	    "EV5.7 (21164PC)")
		UNAME_MACHINE=alphapca57 ;;
		UNAME_MACHINE="alphapca57" ;;
	    "EV6 (21264)")
		UNAME_MACHINE=alphaev6 ;;
		UNAME_MACHINE="alphaev6" ;;
	    "EV6.7 (21264A)")
		UNAME_MACHINE=alphaev67 ;;
		UNAME_MACHINE="alphaev67" ;;
	    "EV6.8CB (21264C)")
		UNAME_MACHINE=alphaev68 ;;
		UNAME_MACHINE="alphaev68" ;;
	    "EV6.8AL (21264B)")
		UNAME_MACHINE=alphaev68 ;;
		UNAME_MACHINE="alphaev68" ;;
	    "EV6.8CX (21264D)")
		UNAME_MACHINE=alphaev68 ;;
		UNAME_MACHINE="alphaev68" ;;
	    "EV6.9A (21264/EV69A)")
		UNAME_MACHINE=alphaev69 ;;
		UNAME_MACHINE="alphaev69" ;;
	    "EV7 (21364)")
		UNAME_MACHINE=alphaev7 ;;
		UNAME_MACHINE="alphaev7" ;;
	    "EV7.9 (21364A)")
		UNAME_MACHINE=alphaev79 ;;
		UNAME_MACHINE="alphaev79" ;;
	esac
	# A Pn.n version is a patched version.
	# A Vn.n version is a released version.
	# A Tn.n version is a released field test version.
	# A Xn.n version is an unreleased experimental baselevel.
	# 1.2 uses "1.2" for uname -r.
	echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
	exitcode=$?
	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
	exit ;;
    Alpha\ *:Windows_NT*:*)
	# How do we know it's Interix rather than the generic POSIX subsystem?
	# Should we change UNAME_MACHINE based on the output of uname instead
	# of the specific Alpha model?
	echo alpha-pc-interix
	exit ;;
	trap '' 0
	exit $exitcode ;;
    21064:Windows_NT:50:3)
	echo alpha-dec-winnt3.5
	exit ;;
    Amiga*:UNIX_System_V:4.0:*)
	echo m68k-unknown-sysv4
	exit ;;
    *:[Aa]miga[Oo][Ss]:*:*)
	echo "$UNAME_MACHINE"-unknown-amigaos
	echo ${UNAME_MACHINE}-unknown-amigaos
	exit ;;
    *:[Mm]orph[Oo][Ss]:*:*)
	echo "$UNAME_MACHINE"-unknown-morphos
	echo ${UNAME_MACHINE}-unknown-morphos
	exit ;;
    *:OS/390:*:*)
	echo i370-ibm-openedition
	exit ;;
    *:z/VM:*:*)
	echo s390-ibm-zvmoe
	exit ;;
    *:OS400:*:*)
	echo powerpc-ibm-os400
        echo powerpc-ibm-os400
	exit ;;
    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
	echo arm-acorn-riscix"$UNAME_RELEASE"
	echo arm-acorn-riscix${UNAME_RELEASE}
	exit ;;
    arm*:riscos:*:*|arm*:RISCOS:*:*)
    arm:riscos:*:*|arm:RISCOS:*:*)
	echo arm-unknown-riscos
	exit ;;
    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
	echo hppa1.1-hitachi-hiuxmpp
	exit ;;
    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
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
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







-
-
-

-
+


-
+

-
-
-

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





-
+








-
+


-
+



-
+


-
+


-
+




-
+










-
+


-
-
+
+

-
+


-
-
+
+

-
-
+
+

-
-
+
+

-
+


-
+





-
+


-
+


-
+


-
-
+
+








-
+


-
+


-
+





-
-
-
+
+
+

-
+







    DRS?6000:unix:4.0:6*)
	echo sparc-icl-nx6
	exit ;;
    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
	case `/usr/bin/uname -p` in
	    sparc) echo sparc-icl-nx7; exit ;;
	esac ;;
    s390x:SunOS:*:*)
	echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
	exit ;;
    sun4H:SunOS:5.*:*)
	echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
	exit ;;
    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
	echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
	exit ;;
    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
	echo i386-pc-auroraux"$UNAME_RELEASE"
	exit ;;
    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
	set_cc_for_build
	SUN_ARCH=i386
	# If there is a compiler, see if it is configured for 64-bit objects.
	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
	# This test works for both compilers.
	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
		grep IS_64BIT_ARCH >/dev/null
	    then
		SUN_ARCH=x86_64
	    fi
	fi
	echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
	exit ;;
    sun4*:SunOS:6*:*)
	# According to config.sub, this is the proper way to canonicalize
	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
	# it's likely to be more like Solaris than SunOS4.
	echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
	exit ;;
    sun4*:SunOS:*:*)
	case "`/usr/bin/arch -k`" in
	    Series*|S4*)
		UNAME_RELEASE=`uname -v`
		;;
	esac
	# Japanese Language versions have a version number like `4.1.3-JL'.
	echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
	exit ;;
    sun3*:SunOS:*:*)
	echo m68k-sun-sunos"$UNAME_RELEASE"
	echo m68k-sun-sunos${UNAME_RELEASE}
	exit ;;
    sun*:*:4.2BSD:*)
	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
	case "`/bin/arch`" in
	    sun3)
		echo m68k-sun-sunos"$UNAME_RELEASE"
		echo m68k-sun-sunos${UNAME_RELEASE}
		;;
	    sun4)
		echo sparc-sun-sunos"$UNAME_RELEASE"
		echo sparc-sun-sunos${UNAME_RELEASE}
		;;
	esac
	exit ;;
    aushp:SunOS:*:*)
	echo sparc-auspex-sunos"$UNAME_RELEASE"
	echo sparc-auspex-sunos${UNAME_RELEASE}
	exit ;;
    # The situation for MiNT is a little confusing.  The machine name
    # can be virtually everything (everything which is not
    # "atarist" or "atariste" at least should have a processor
    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
    # to the lowercase version "mint" (or "freemint").  Finally
    # the system name "TOS" denotes a system which is actually not
    # MiNT.  But MiNT is downward compatible to TOS, so this should
    # be no problem.
    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
	echo m68k-atari-mint"$UNAME_RELEASE"
        echo m68k-atari-mint${UNAME_RELEASE}
	exit ;;
    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
	echo m68k-atari-mint"$UNAME_RELEASE"
	exit ;;
	echo m68k-atari-mint${UNAME_RELEASE}
        exit ;;
    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
	echo m68k-atari-mint"$UNAME_RELEASE"
        echo m68k-atari-mint${UNAME_RELEASE}
	exit ;;
    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
	echo m68k-milan-mint"$UNAME_RELEASE"
	exit ;;
        echo m68k-milan-mint${UNAME_RELEASE}
        exit ;;
    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
	echo m68k-hades-mint"$UNAME_RELEASE"
	exit ;;
        echo m68k-hades-mint${UNAME_RELEASE}
        exit ;;
    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
	echo m68k-unknown-mint"$UNAME_RELEASE"
	exit ;;
        echo m68k-unknown-mint${UNAME_RELEASE}
        exit ;;
    m68k:machten:*:*)
	echo m68k-apple-machten"$UNAME_RELEASE"
	echo m68k-apple-machten${UNAME_RELEASE}
	exit ;;
    powerpc:machten:*:*)
	echo powerpc-apple-machten"$UNAME_RELEASE"
	echo powerpc-apple-machten${UNAME_RELEASE}
	exit ;;
    RISC*:Mach:*:*)
	echo mips-dec-mach_bsd4.3
	exit ;;
    RISC*:ULTRIX:*:*)
	echo mips-dec-ultrix"$UNAME_RELEASE"
	echo mips-dec-ultrix${UNAME_RELEASE}
	exit ;;
    VAX*:ULTRIX*:*:*)
	echo vax-dec-ultrix"$UNAME_RELEASE"
	echo vax-dec-ultrix${UNAME_RELEASE}
	exit ;;
    2020:CLIX:*:* | 2430:CLIX:*:*)
	echo clipper-intergraph-clix"$UNAME_RELEASE"
	echo clipper-intergraph-clix${UNAME_RELEASE}
	exit ;;
    mips:*:*:UMIPS | mips:*:*:RISCos)
	set_cc_for_build
	sed 's/^	//' << EOF > "$dummy.c"
	eval $set_cc_for_build
	sed 's/^	//' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h>  /* for printf() prototype */
	int main (int argc, char *argv[]) {
#else
	int main (argc, argv) int argc; char *argv[]; {
#endif
	#if defined (host_mips) && defined (MIPSEB)
	#if defined (SYSTYPE_SYSV)
	  printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
	#endif
	#if defined (SYSTYPE_SVR4)
	  printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
	#endif
	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
	  printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
	#endif
	#endif
	  exit (-1);
	}
EOF
	$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
	$CC_FOR_BUILD -o $dummy $dummy.c &&
	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
	  SYSTEM_NAME=`$dummy $dummyarg` &&
	    { echo "$SYSTEM_NAME"; exit; }
	echo mips-mips-riscos"$UNAME_RELEASE"
	echo mips-mips-riscos${UNAME_RELEASE}
	exit ;;
    Motorola:PowerMAX_OS:*:*)
	echo powerpc-motorola-powermax
	exit ;;
    Motorola:*:4.3:PL8-*)
	echo powerpc-harris-powermax
	exit ;;
530
531
532
533
534
535
536
537
538
539



540
541
542


543
544

545
546

547
548
549

550
551

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

567
568
569
570
571
572
573
574
575
576
577
578

579
580

581
582
583
584
585


586
587
588
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
604
605
606
607
608

609
610

611
612
613
614
615
616


617
618
619

620
621

622
623
624
625
626

627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648




649
650
651
652
653
654
655
656
657
658
659
660
661
662











663
664
665
666



667
668
669
670



671
672
673
674
675
676
677






678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697



















698
699

700
701
702
703

704
705

706
707
708
709
710
711
712
713
714
715
716
717


718
719

720
721

722
723
724

725
726
727
728


729
730
731
732


733
734
735
736
737
738
739
474
475
476
477
478
479
480



481
482
483
484


485
486
487

488
489

490
491
492

493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
517
518
519
520
521

522
523

524
525
526
527


528
529
530
531
532
533
534
535
536
537
538
539

540
541
542
543
544
545
546
547
548
549
550
551

552
553

554
555
556
557
558


559
560

561

562
563

564
565
566
567
568

569
570
571
572

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587




588
589
590
591
592
593
594











595
596
597
598
599
600
601
602
603
604
605
606



607
608
609
610



611
612
613
614






615
616
617
618
619
620
621



















622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641

642
643
644
645

646
647

648
649
650
651
652
653
654
655
656
657
658


659
660
661

662
663

664
665
666

667
668
669


670
671
672
673


674
675
676
677
678
679
680
681
682







-
-
-
+
+
+

-
-
+
+

-
+

-
+


-
+

-
+














-
+











-
+

-
+



-
-
+
+










-
+











-
+

-
+




-
-
+
+
-

-
+

-
+




-
+



-
+














-
-
-
-
+
+
+
+



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

-
-
-
+
+
+

-
-
-
+
+
+

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

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

-
+



-
+

-
+










-
-
+
+

-
+

-
+


-
+


-
-
+
+


-
-
+
+







    m88k:*:4*:R4*)
	echo m88k-motorola-sysv4
	exit ;;
    m88k:*:3*:R3*)
	echo m88k-motorola-sysv3
	exit ;;
    AViiON:dgux:*:*)
	# DG/UX returns AViiON for all architectures
	UNAME_PROCESSOR=`/usr/bin/uname -p`
	if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
        # DG/UX returns AViiON for all architectures
        UNAME_PROCESSOR=`/usr/bin/uname -p`
	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
	then
	    if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
	       [ "$TARGET_BINARY_INTERFACE"x = x ]
	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
	       [ ${TARGET_BINARY_INTERFACE}x = x ]
	    then
		echo m88k-dg-dgux"$UNAME_RELEASE"
		echo m88k-dg-dgux${UNAME_RELEASE}
	    else
		echo m88k-dg-dguxbcs"$UNAME_RELEASE"
		echo m88k-dg-dguxbcs${UNAME_RELEASE}
	    fi
	else
	    echo i586-dg-dgux"$UNAME_RELEASE"
	    echo i586-dg-dgux${UNAME_RELEASE}
	fi
	exit ;;
 	exit ;;
    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
	echo m88k-dolphin-sysv3
	exit ;;
    M88*:*:R3*:*)
	# Delta 88k system running SVR3
	echo m88k-motorola-sysv3
	exit ;;
    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
	echo m88k-tektronix-sysv3
	exit ;;
    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
	echo m68k-tektronix-bsd
	exit ;;
    *:IRIX*:*:*)
	echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
	exit ;;
    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
    i*86:AIX:*:*)
	echo i386-ibm-aix
	exit ;;
    ia64:AIX:*:*)
	if [ -x /usr/bin/oslevel ] ; then
		IBM_REV=`/usr/bin/oslevel`
	else
		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
	fi
	echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
	exit ;;
    *:AIX:2:3)
	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
		set_cc_for_build
		sed 's/^		//' << EOF > "$dummy.c"
		eval $set_cc_for_build
		sed 's/^		//' << EOF >$dummy.c
		#include <sys/systemcfg.h>

		main()
			{
			if (!__power_pc())
				exit(1);
			puts("powerpc-ibm-aix3.2.5");
			exit(0);
			}
EOF
		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
		then
			echo "$SYSTEM_NAME"
		else
			echo rs6000-ibm-aix3.2.5
		fi
	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
		echo rs6000-ibm-aix3.2.4
	else
		echo rs6000-ibm-aix3.2
	fi
	exit ;;
    *:AIX:*:[4567])
    *:AIX:*:[45])
	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
		IBM_ARCH=rs6000
	else
		IBM_ARCH=powerpc
	fi
	if [ -x /usr/bin/lslpp ] ; then
		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
	if [ -x /usr/bin/oslevel ] ; then
		IBM_REV=`/usr/bin/oslevel`
			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
	else
		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
	fi
	echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
	exit ;;
    *:AIX:*:*)
	echo rs6000-ibm-aix
	exit ;;
    ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
	echo romp-ibm-bsd4.4
	exit ;;
    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
	echo romp-ibm-bsd"$UNAME_RELEASE"   # 4.3 with uname added to
	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
	exit ;;                             # report: romp-ibm BSD 4.3
    *:BOSX:*:*)
	echo rs6000-bull-bosx
	exit ;;
    DPX/2?00:B.O.S.:*:*)
	echo m68k-bull-sysv3
	exit ;;
    9000/[34]??:4.3bsd:1.*:*)
	echo m68k-hp-bsd
	exit ;;
    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
	echo m68k-hp-bsd4.4
	exit ;;
    9000/[34678]??:HP-UX:*:*)
	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
	case "$UNAME_MACHINE" in
	    9000/31?)            HP_ARCH=m68000 ;;
	    9000/[34]??)         HP_ARCH=m68k ;;
	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
	case "${UNAME_MACHINE}" in
	    9000/31? )            HP_ARCH=m68000 ;;
	    9000/[34]?? )         HP_ARCH=m68k ;;
	    9000/[678][0-9][0-9])
		if [ -x /usr/bin/getconf ]; then
		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
		    case "$sc_cpu_version" in
		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
		      532)                      # CPU_PA_RISC2_0
			case "$sc_kernel_bits" in
			  32) HP_ARCH=hppa2.0n ;;
			  64) HP_ARCH=hppa2.0w ;;
			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
			esac ;;
		    esac
                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
                    case "${sc_cpu_version}" in
                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
                      532)                      # CPU_PA_RISC2_0
                        case "${sc_kernel_bits}" in
                          32) HP_ARCH="hppa2.0n" ;;
                          64) HP_ARCH="hppa2.0w" ;;
			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
                        esac ;;
                    esac
		fi
		if [ "$HP_ARCH" = "" ]; then
		    set_cc_for_build
		    sed 's/^		//' << EOF > "$dummy.c"
		if [ "${HP_ARCH}" = "" ]; then
		    eval $set_cc_for_build
		    sed 's/^              //' << EOF >$dummy.c

		#define _HPUX_SOURCE
		#include <stdlib.h>
		#include <unistd.h>
              #define _HPUX_SOURCE
              #include <stdlib.h>
              #include <unistd.h>

		int main ()
		{
		#if defined(_SC_KERNEL_BITS)
		    long bits = sysconf(_SC_KERNEL_BITS);
		#endif
		    long cpu  = sysconf (_SC_CPU_VERSION);
              int main ()
              {
              #if defined(_SC_KERNEL_BITS)
                  long bits = sysconf(_SC_KERNEL_BITS);
              #endif
                  long cpu  = sysconf (_SC_CPU_VERSION);

		    switch (cpu)
			{
			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
			case CPU_PA_RISC2_0:
		#if defined(_SC_KERNEL_BITS)
			    switch (bits)
				{
				case 64: puts ("hppa2.0w"); break;
				case 32: puts ("hppa2.0n"); break;
				default: puts ("hppa2.0"); break;
				} break;
		#else  /* !defined(_SC_KERNEL_BITS) */
			    puts ("hppa2.0"); break;
		#endif
			default: puts ("hppa1.0"); break;
			}
		    exit (0);
		}
                  switch (cpu)
              	{
              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
              	case CPU_PA_RISC2_0:
              #if defined(_SC_KERNEL_BITS)
              	    switch (bits)
              		{
              		case 64: puts ("hppa2.0w"); break;
              		case 32: puts ("hppa2.0n"); break;
              		default: puts ("hppa2.0"); break;
              		} break;
              #else  /* !defined(_SC_KERNEL_BITS) */
              	    puts ("hppa2.0"); break;
              #endif
              	default: puts ("hppa1.0"); break;
              	}
                  exit (0);
              }
EOF
		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
		    test -z "$HP_ARCH" && HP_ARCH=hppa
		fi ;;
	esac
	if [ "$HP_ARCH" = hppa2.0w ]
	if [ ${HP_ARCH} = "hppa2.0w" ]
	then
	    set_cc_for_build
	    eval $set_cc_for_build

	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
	    # generating 64-bit code.  GNU and HP use different nomenclature:
	    #
	    # $ CC_FOR_BUILD=cc ./config.guess
	    # => hppa2.0w-hp-hpux11.23
	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
	    # => hppa64-hp-hpux11.23

	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
		grep -q __LP64__
	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
		grep __LP64__ >/dev/null
	    then
		HP_ARCH=hppa2.0w
		HP_ARCH="hppa2.0w"
	    else
		HP_ARCH=hppa64
		HP_ARCH="hppa64"
	    fi
	fi
	echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
	exit ;;
    ia64:HP-UX:*:*)
	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
	echo ia64-hp-hpux"$HPUX_REV"
	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
	echo ia64-hp-hpux${HPUX_REV}
	exit ;;
    3050*:HI-UX:*:*)
	set_cc_for_build
	sed 's/^	//' << EOF > "$dummy.c"
	eval $set_cc_for_build
	sed 's/^	//' << EOF >$dummy.c
	#include <unistd.h>
	int
	main ()
	{
	  long cpu = sysconf (_SC_CPU_VERSION);
	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
750
751
752
753
754
755
756
757

758
759
760
761

762
763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
778

779
780

781
782
783
784
785
786
787
788

789
790
791
792
793
794

795
796
797

798
799
800

801
802
803

804
805

806
807
808

809
810
811
812
813
814

815
816
817

818
819
820

821
822
823

824
825
826
827
828
829
830





831
832
833
834



835
836
837

838
839
840

841
842
843

844
845
846
847



848
849
850
851

852
853
854
855
856
857
858
859
860

861
862


863
864
865
866
867

868
869
870
871
872
873

874
875
876



877
878
879

880
881
882


883
884

885
886
887


888
889
890
891
892










893
894

895
896
897

898



899
900

901
902
903
904

905
906
907
908

909
910
911


912















913
914


915
916
917
918




























































919
920
921
922
923
924
925
926
927
928
929
930
931



932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037

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



1054
1055
1056
1057


1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072

1073
1074
1075

1076
1077
1078

1079
1080
1081

1082
1083
1084
1085
1086
1087

1088
1089
1090

1091
1092
1093


1094

































































1095
1096
1097
1098
1099
1100
1101
1102
1103
1104



1105
1106
1107


1108
1109
1110
1111
1112

1113
1114
1115

1116
1117
1118

1119
1120
1121

1122
1123
1124


1125
1126
1127

1128
1129
1130


1131
1132

1133
1134

1135
1136
1137
1138

1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159

1160
1161

1162
1163
1164
1165
1166
1167


1168
1169
1170
1171
1172


1173
1174
1175
1176
1177
1178
1179
1180
1181

1182
1183

1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203

1204
1205

1206
1207
1208


1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220

1221
1222
1223
1224
1225
1226

1227
1228
1229

1230
1231
1232


1233
1234
1235

1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
1254




1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273

1274
1275
1276
1277
1278
1279
1280

1281
1282

1283
1284

1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301

1302
1303
1304

1305
1306
1307

1308
1309
1310

1311
1312
1313

1314
1315
1316

1317
1318
1319
1320
1321
1322

1323
1324
1325

1326
1327
1328

1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356

1357
1358
1359
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370

1371
1372
1373
1374
1375

1376
1377
1378
1379

1380
1381
1382


1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404

1405
1406
1407
1408
1409

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

1431
1432
1433

1434
1435
1436
1437


1438
1439
1440
1441
1442
1443
1444
1445
1446

1447
1448
1449

1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467





1468
1469
1470


1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491

1492
1493

1494
1495

1496








1497
1498
1499
1500
1501
1502
1503
693
694
695
696
697
698
699

700
701
702
703

704
705
706
707
708
709
710
711
712

713
714
715
716
717
718
719
720

721
722

723
724
725
726
727
728
729
730

731
732
733
734
735
736

737
738
739

740
741
742

743
744
745

746
747

748
749
750

751
752
753
754
755
756

757
758
759

760
761
762

763
764
765

766
767
768





769
770
771
772
773
774



775
776
777
778
779

780
781
782

783
784
785

786
787



788
789
790




791







792

793


794
795
796

797
798

799
800



801

802
803


804
805
806
807
808

809
810


811
812
813

814
815


816
817
818




819
820
821
822
823
824
825
826
827
828
829

830
831
832

833
834
835
836
837
838

839
840
841
842

843
844
845
846

847
848


849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866


867
868
869



870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939



940
941
942










































































































943









944
945
946
947



948
949
950
951
952


953
954
955












956

957
958
959

960
961
962

963
964
965

966
967



968

969
970
971

972
973


974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048



1049
1050
1051
1052


1053
1054
1055
1056
1057
1058

1059
1060
1061

1062
1063
1064

1065
1066
1067

1068
1069


1070
1071
1072
1073

1074
1075


1076
1077
1078

1079
1080

1081
1082
1083
1084

1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103
1104
1105

1106
1107

1108
1109
1110
1111
1112


1113
1114





1115
1116
1117
1118
1119
1120
1121
1122
1123
1124

1125
1126

1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146

1147
1148

1149
1150


1151
1152










1153

1154
1155
1156
1157
1158
1159

1160
1161
1162

1163
1164


1165
1166
1167
1168

1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179

1180
1181
1182
1183
1184




1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199

1200
1201
1202
1203
1204
1205
1206

1207
1208
1209
1210
1211
1212
1213

1214
1215

1216
1217

1218
1219
1220
1221
1222
1223
1224
1225
1226
1227






1228

1229
1230
1231

1232
1233
1234

1235
1236
1237

1238
1239
1240

1241
1242
1243

1244
1245



1246

1247
1248
1249

1250
1251
1252

1253
1254
1255
1256

























1257






1258
1259
1260

1261
1262
1263
1264

1265
1266
1267
1268
1269

1270




1271
1272


1273
1274






1275
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288


1289
1290
1291
1292
1293

1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314

1315
1316
1317

1318
1319
1320


1321
1322
1323
1324
1325
1326
1327
1328
1329
1330

1331
1332
1333

1334












1335
1336
1337



1338
1339
1340
1341
1342
1343


1344
1345








1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357

1358
1359

1360
1361

1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378







-
+



-
+








-
+







-
+

-
+







-
+





-
+


-
+


-
+


-
+

-
+


-
+





-
+


-
+


-
+


-
+


-
-
-
-
-
+
+
+
+
+

-
-
-
+
+
+


-
+


-
+


-
+

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

-
+
-
-
+
+

-


-
+

-
-
-

-
+

-
-
+
+
+


-
+

-
-
+
+

-
+

-
-
+
+

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

-
+


-
+

+
+
+

-
+



-
+



-
+

-
-
+
+

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

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










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




-
-
-
+
+
+


-
-
+
+

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

-
+


-
+


-
+


-
+

-
-
-

-
+


-
+

-
-
+
+

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







-
-
-
+
+
+

-
-
+
+




-
+


-
+


-
+


-
+

-
-
+
+


-
+

-
-
+
+

-
+

-
+



-
+





-
+




-
+









-
+

-
+




-
-
+
+
-
-
-
-
-
+
+








-
+

-
+



















-
+

-
+

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

-
+





-
+


-
+

-
-
+
+


-
+










-
+




-
-
-
-
+
+
+
+











-
+






-
+






-
+

-
+

-
+









-
-
-
-
-
-

-
+


-
+


-
+


-
+


-
+


-
+

-
-
-

-
+


-
+


-
+



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



-
+



-
+




-
+
-
-
-
-
+

-
-
+
+
-
-
-
-
-
-








-
+





-
-
+




-
+




















-
+


-
+


-
-
+
+








-
+


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



-
-
-
+
+
+
+
+

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












-
+

-
+

-
+

+
+
+
+
+
+
+
+







	    }
	  else if (CPU_IS_HP_MC68K (cpu))
	    puts ("m68k-hitachi-hiuxwe2");
	  else puts ("unknown-hitachi-hiuxwe2");
	  exit (0);
	}
EOF
	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
		{ echo "$SYSTEM_NAME"; exit; }
	echo unknown-hitachi-hiuxwe2
	exit ;;
    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
	echo hppa1.1-hp-bsd
	exit ;;
    9000/8??:4.3bsd:*:*)
	echo hppa1.0-hp-bsd
	exit ;;
    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
	echo hppa1.0-hp-mpeix
	exit ;;
    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
	echo hppa1.1-hp-osf
	exit ;;
    hp8??:OSF1:*:*)
	echo hppa1.0-hp-osf
	exit ;;
    i*86:OSF1:*:*)
	if [ -x /usr/sbin/sysversion ] ; then
	    echo "$UNAME_MACHINE"-unknown-osf1mk
	    echo ${UNAME_MACHINE}-unknown-osf1mk
	else
	    echo "$UNAME_MACHINE"-unknown-osf1
	    echo ${UNAME_MACHINE}-unknown-osf1
	fi
	exit ;;
    parisc*:Lites*:*:*)
	echo hppa1.1-hp-lites
	exit ;;
    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
	echo c1-convex-bsd
	exit ;;
        exit ;;
    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
	if getsysinfo -f scalar_acc
	then echo c32-convex-bsd
	else echo c2-convex-bsd
	fi
	exit ;;
        exit ;;
    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
	echo c34-convex-bsd
	exit ;;
        exit ;;
    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
	echo c38-convex-bsd
	exit ;;
        exit ;;
    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
	echo c4-convex-bsd
	exit ;;
        exit ;;
    CRAY*Y-MP:*:*:*)
	echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
	exit ;;
    CRAY*[A-Z]90:*:*:*)
	echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
	      -e 's/\.[^.]*$/.X/'
	exit ;;
    CRAY*TS:*:*:*)
	echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
	exit ;;
    CRAY*T3E:*:*:*)
	echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
	exit ;;
    CRAY*SV1:*:*:*)
	echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
	exit ;;
    *:UNICOS/mp:*:*)
	echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
	exit ;;
    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
	exit ;;
	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
        exit ;;
    5000:UNIX_System_V:4.*:*)
	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
	exit ;;
    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
	echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
	exit ;;
    sparc*:BSD/OS:*:*)
	echo sparc-unknown-bsdi"$UNAME_RELEASE"
	echo sparc-unknown-bsdi${UNAME_RELEASE}
	exit ;;
    *:BSD/OS:*:*)
	echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
	exit ;;
    arm:FreeBSD:*:*)
	UNAME_PROCESSOR=`uname -p`
	set_cc_for_build
    *:FreeBSD:*:*)
	case ${UNAME_MACHINE} in
	    pc98)
	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
	    | grep -q __ARM_PCS_VFP
	then
	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi
		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
	else
	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf
	fi
	exit ;;
    *:FreeBSD:*:*)
	UNAME_PROCESSOR=`/usr/bin/uname -p`
	case "$UNAME_PROCESSOR" in
	    amd64)
		UNAME_PROCESSOR=x86_64 ;;
		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
	    i386)
		UNAME_PROCESSOR=i586 ;;
	    *)
		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
	esac
	echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
	exit ;;
    i*:CYGWIN*:*)
	echo "$UNAME_MACHINE"-pc-cygwin
	echo ${UNAME_MACHINE}-pc-cygwin
	exit ;;
    *:MINGW64*:*)
	echo "$UNAME_MACHINE"-pc-mingw64
	exit ;;
    *:MINGW*:*)
	echo "$UNAME_MACHINE"-pc-mingw32
	echo ${UNAME_MACHINE}-pc-mingw32
	exit ;;
    *:MSYS*:*)
	echo "$UNAME_MACHINE"-pc-msys
    i*:windows32*:*)
    	# uname -m includes "-pc" on this system.
    	echo ${UNAME_MACHINE}-mingw32
	exit ;;
    i*:PW*:*)
	echo "$UNAME_MACHINE"-pc-pw32
	echo ${UNAME_MACHINE}-pc-pw32
	exit ;;
    *:Interix*:*)
	case "$UNAME_MACHINE" in
    *:Interix*:[3456]*)
    	case ${UNAME_MACHINE} in
	    x86)
		echo i586-pc-interix"$UNAME_RELEASE"
		echo i586-pc-interix${UNAME_RELEASE}
		exit ;;
	    authenticamd | genuineintel | EM64T)
		echo x86_64-unknown-interix"$UNAME_RELEASE"
	    EM64T | authenticamd)
		echo x86_64-unknown-interix${UNAME_RELEASE}
		exit ;;
	    IA64)
		echo ia64-unknown-interix"$UNAME_RELEASE"
		exit ;;
	esac ;;
	esac ;;
    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
	echo i${UNAME_MACHINE}-pc-mks
	exit ;;
    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
	# How do we know it's Interix rather than the generic POSIX subsystem?
	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
	# UNAME_MACHINE based on the output of uname instead of i386?
	echo i586-pc-interix
	exit ;;
    i*:UWIN*:*)
	echo "$UNAME_MACHINE"-pc-uwin
	echo ${UNAME_MACHINE}-pc-uwin
	exit ;;
    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
	echo x86_64-pc-cygwin
	echo x86_64-unknown-cygwin
	exit ;;
    p*:CYGWIN*:*)
	echo powerpcle-unknown-cygwin
	exit ;;
    prep*:SunOS:5.*:*)
	echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
	exit ;;
    *:GNU:*:*)
	# the GNU system
	echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
	exit ;;
    *:GNU/*:*:*)
	# other systems with GNU libc and userland
	echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
	exit ;;
    *:Minix:*:*)
	echo "$UNAME_MACHINE"-unknown-minix
    i*86:Minix:*:*)
	echo ${UNAME_MACHINE}-pc-minix
	exit ;;
    arm*:Linux:*:*)
	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    avr32*:Linux:*:*)
	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    cris:Linux:*:*)
	echo cris-axis-linux-${LIBC}
	exit ;;
    crisv32:Linux:*:*)
	echo crisv32-axis-linux-${LIBC}
	exit ;;
    frv:Linux:*:*)
    	echo frv-unknown-linux-${LIBC}
	exit ;;
    aarch64:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
    ia64:Linux:*:*)
	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    aarch64_be:Linux:*:*)
	UNAME_MACHINE=aarch64_be
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
    m32r*:Linux:*:*)
	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    m68*:Linux:*:*)
	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    mips:Linux:*:*)
	eval $set_cc_for_build
	sed 's/^	//' << EOF >$dummy.c
	#undef CPU
	#undef mips
	#undef mipsel
	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
	CPU=mipsel
	#else
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
	CPU=mips
	#else
	CPU=
	#endif
	#endif
EOF
	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
	    /^CPU/{
		s: ::g
		p
	    }'`"
	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
	;;
    mips64:Linux:*:*)
	eval $set_cc_for_build
	sed 's/^	//' << EOF >$dummy.c
	#undef CPU
	#undef mips64
	#undef mips64el
	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
	CPU=mips64el
	#else
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
	CPU=mips64
	#else
	CPU=
	#endif
	#endif
EOF
	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
	    /^CPU/{
		s: ::g
		p
	    }'`"
	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
	;;
    or32:Linux:*:*)
	echo or32-unknown-linux-${LIBC}
	exit ;;
    ppc:Linux:*:*)
	echo powerpc-unknown-linux-${LIBC}
	exit ;;
    ppc64:Linux:*:*)
	echo powerpc64-unknown-linux-${LIBC}
	exit ;;
    alpha:Linux:*:*)
	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
	  EV5)   UNAME_MACHINE=alphaev5 ;;
	  EV56)  UNAME_MACHINE=alphaev56 ;;
	  PCA56) UNAME_MACHINE=alphapca56 ;;
	  PCA57) UNAME_MACHINE=alphapca56 ;;
	  EV6)   UNAME_MACHINE=alphaev6 ;;
	  EV67)  UNAME_MACHINE=alphaev67 ;;
	  EV68*) UNAME_MACHINE=alphaev68 ;;
	esac
	objdump --private-headers /bin/sh | grep -q ld.so.1
	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
        esac
	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    arc:Linux:*:* | arceb:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    arm*:Linux:*:*)
	set_cc_for_build
	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
	    | grep -q __ARM_EABI__
	then
	    echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	else
	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
		| grep -q __ARM_PCS_VFP
	    then
		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
	    else
		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
	    fi
	fi
	exit ;;
    avr32*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    cris:Linux:*:*)
	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
	exit ;;
    crisv32:Linux:*:*)
	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
	exit ;;
    e2k:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    frv:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    hexagon:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    i*86:Linux:*:*)
	echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
	exit ;;
    ia64:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    k1om:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    m32r*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    m68*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    mips:Linux:*:* | mips64:Linux:*:*)
	set_cc_for_build
	IS_GLIBC=0
	test x"${LIBC}" = xgnu && IS_GLIBC=1
	sed 's/^	//' << EOF > "$dummy.c"
	#undef CPU
	#undef mips
	#undef mipsel
	#undef mips64
	#undef mips64el
	#if ${IS_GLIBC} && defined(_ABI64)
	LIBCABI=gnuabi64
	#else
	#if ${IS_GLIBC} && defined(_ABIN32)
	LIBCABI=gnuabin32
	#else
	LIBCABI=${LIBC}
	#endif
	#endif

	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
	CPU=mipsisa64r6
	#else
	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
	CPU=mipsisa32r6
	#else
	#if defined(__mips64)
	CPU=mips64
	#else
	CPU=mips
	#endif
	#endif
	#endif

	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
	MIPS_ENDIAN=el
	#else
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
	MIPS_ENDIAN=
	#else
	MIPS_ENDIAN=
	#endif
	#endif
EOF
	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`"
	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
	;;
    mips64el:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    openrisc*:Linux:*:*)
	echo or1k-unknown-linux-"$LIBC"
	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    or32:Linux:*:* | or1k*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    padre:Linux:*:*)
	echo sparc-unknown-linux-"$LIBC"
	exit ;;
    parisc64:Linux:*:* | hppa64:Linux:*:*)
	echo hppa64-unknown-linux-"$LIBC"
	exit ;;
    parisc:Linux:*:* | hppa:Linux:*:*)
	# Look for CPU level
	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
	  PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
	  PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
	  *)    echo hppa-unknown-linux-"$LIBC" ;;
	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
	  *)    echo hppa-unknown-linux-${LIBC} ;;
	esac
	exit ;;
    ppc64:Linux:*:*)
	echo powerpc64-unknown-linux-"$LIBC"
    parisc64:Linux:*:* | hppa64:Linux:*:*)
	echo hppa64-unknown-linux-${LIBC}
	exit ;;
    ppc:Linux:*:*)
	echo powerpc-unknown-linux-"$LIBC"
	exit ;;
    ppc64le:Linux:*:*)
	echo powerpc64le-unknown-linux-"$LIBC"
	exit ;;
    ppcle:Linux:*:*)
	echo powerpcle-unknown-linux-"$LIBC"
	exit ;;
    riscv32:Linux:*:* | riscv64:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    s390:Linux:*:* | s390x:Linux:*:*)
	echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
	echo ${UNAME_MACHINE}-ibm-linux
	exit ;;
    sh64*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
    	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    sh*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    sparc:Linux:*:* | sparc64:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
	exit ;;
    tile*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    vax:Linux:*:*)
	echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
	exit ;;
    x86_64:Linux:*:*)
	echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
	echo x86_64-unknown-linux-${LIBC}
	exit ;;
    xtensa*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
    xtensa:Linux:*:*)
    	echo xtensa-unknown-linux-${LIBC}
	exit ;;
    i*86:Linux:*:*)
	# The BFD linker knows what the default object file format is, so
	# first see if it will tell us. cd to the root directory to prevent
	# problems with other programs or directories called `ld' in the path.
	# Set LC_ALL=C to ensure ld outputs messages in English.
	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
			 | sed -ne '/supported targets:/!d
				    s/[ 	][ 	]*/ /g
				    s/.*supported targets: *//
				    s/ .*//
				    p'`
        case "$ld_supported_targets" in
	  elf32-i386)
		TENTATIVE="${UNAME_MACHINE}-pc-linux-${LIBC}"
		;;
	  a.out-i386-linux)
		echo "${UNAME_MACHINE}-pc-linux-${LIBC}aout"
		exit ;;
	  coff-i386)
		echo "${UNAME_MACHINE}-pc-linux-${LIBC}coff"
		exit ;;
	  "")
		# Either a pre-BFD a.out linker (linux-gnuoldld) or
		# one that does not give us useful --help.
		echo "${UNAME_MACHINE}-pc-linux-${LIBC}oldld"
		exit ;;
	esac
	# This should get integrated into the C code below, but now we hack
	if [ "$LIBC" != "gnu" ] ; then echo "$TENTATIVE" && exit 0 ; fi
	# Determine whether the default compiler is a.out or elf
	eval $set_cc_for_build
	sed 's/^	//' << EOF >$dummy.c
	#include <features.h>
	#ifdef __ELF__
	# ifdef __GLIBC__
	#  if __GLIBC__ >= 2
	LIBC=gnu
	#  else
	LIBC=gnulibc1
	#  endif
	# else
	LIBC=gnulibc1
	# endif
	#else
	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
	LIBC=gnu
	#else
	LIBC=gnuaout
	#endif
	#endif
	#ifdef __dietlibc__
	LIBC=dietlibc
	#endif
EOF
	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
	    /^LIBC/{
		s: ::g
		p
	    }'`"
	test x"${LIBC}" != x && {
		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
		exit
	}
	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
	;;
    i*86:DYNIX/ptx:4*:*)
	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
	# earlier versions are messed up and put the nodename in both
	# sysname and nodename.
	echo i386-sequent-sysv4
	exit ;;
    i*86:UNIX_SV:4.2MP:2.*)
	# Unixware is an offshoot of SVR4, but it has its own version
	# number series starting with 2...
	# I am not positive that other SVR4 systems won't match this,
        # Unixware is an offshoot of SVR4, but it has its own version
        # number series starting with 2...
        # I am not positive that other SVR4 systems won't match this,
	# I just have to hope.  -- rms.
	# Use sysv4.2uw... so that sysv4* matches it.
	echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
        # Use sysv4.2uw... so that sysv4* matches it.
	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
	exit ;;
    i*86:OS/2:*:*)
	# If we were able to find `uname', then EMX Unix compatibility
	# is probably installed.
	echo "$UNAME_MACHINE"-pc-os2-emx
	echo ${UNAME_MACHINE}-pc-os2-emx
	exit ;;
    i*86:XTS-300:*:STOP)
	echo "$UNAME_MACHINE"-unknown-stop
	echo ${UNAME_MACHINE}-unknown-stop
	exit ;;
    i*86:atheos:*:*)
	echo "$UNAME_MACHINE"-unknown-atheos
	echo ${UNAME_MACHINE}-unknown-atheos
	exit ;;
    i*86:syllable:*:*)
	echo "$UNAME_MACHINE"-pc-syllable
	echo ${UNAME_MACHINE}-pc-syllable
	exit ;;
    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
	echo i386-unknown-lynxos"$UNAME_RELEASE"
    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
	echo i386-unknown-lynxos${UNAME_RELEASE}
	exit ;;
    i*86:*DOS:*:*)
	echo "$UNAME_MACHINE"-pc-msdosdjgpp
	echo ${UNAME_MACHINE}-pc-msdosdjgpp
	exit ;;
    i*86:*:4.*:*)
	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
		echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
	else
		echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
	fi
	exit ;;
    i*86:*:5:[678]*)
	# UnixWare 7.x, OpenUNIX and OpenServer 6.
    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
	case `/bin/uname -X | grep "^Machine"` in
	    *486*)	     UNAME_MACHINE=i486 ;;
	    *Pentium)	     UNAME_MACHINE=i586 ;;
	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
	esac
	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
	exit ;;
    i*86:*:3.2:*)
	if test -f /usr/options/cb.name; then
		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
		echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
	elif /bin/uname -X 2>/dev/null >/dev/null ; then
		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
			&& UNAME_MACHINE=i586
		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
			&& UNAME_MACHINE=i686
		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
			&& UNAME_MACHINE=i686
		echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
	else
		echo "$UNAME_MACHINE"-pc-sysv32
		echo ${UNAME_MACHINE}-pc-sysv32
	fi
	exit ;;
    pc:*:*:*)
	# Left here for compatibility:
	# uname -m prints for DJGPP always 'pc', but it prints nothing about
	# the processor, so we play safe by assuming i586.
        # uname -m prints for DJGPP always 'pc', but it prints nothing about
        # the processor, so we play safe by assuming i386.
	# Note: whatever this is, it MUST be the same as what config.sub
	# prints for the "djgpp" host, or else GDB configure will decide that
	# this is a cross-build.
	echo i586-pc-msdosdjgpp
	exit ;;
	echo i386-pc-msdosdjgpp
        exit ;;
    Intel:Mach:3*:*)
	echo i386-pc-mach3
	exit ;;
    paragon:*:*:*)
	echo i860-intel-osf1
	exit ;;
    i860:*:4.*:*) # i860-SVR4
	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
	  echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
	else # Add other i860-SVR4 vendors below as they are discovered.
	  echo i860-unknown-sysv"$UNAME_RELEASE"  # Unknown i860-SVR4
	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
	fi
	exit ;;
    mini*:CTIX:SYS*5:*)
	# "miniframe"
	echo m68010-convergent-sysv
	exit ;;
    mc68k:UNIX:SYSTEM5:3.51m)
	echo m68k-convergent-sysv
	exit ;;
    M680?0:D-NIX:5.3:*)
	echo m68k-diab-dnix
	exit ;;
    M68*:*:R3V[5678]*:*)
	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
	OS_REL=''
	test -r /etc/.relid \
	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
	  && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
	  && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
	  && { echo i486-ncr-sysv4; exit; } ;;
        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
          && { echo i486-ncr-sysv4; exit; } ;;
    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
	OS_REL='.3'
	test -r /etc/.relid \
	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
	    && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
	echo m68k-unknown-lynxos"$UNAME_RELEASE"
	echo m68k-unknown-lynxos${UNAME_RELEASE}
	exit ;;
    mc68030:UNIX_System_V:4.*:*)
	echo m68k-atari-sysv4
	exit ;;
    TSUNAMI:LynxOS:2.*:*)
	echo sparc-unknown-lynxos"$UNAME_RELEASE"
	echo sparc-unknown-lynxos${UNAME_RELEASE}
	exit ;;
    rs6000:LynxOS:2.*:*)
	echo rs6000-unknown-lynxos"$UNAME_RELEASE"
	echo rs6000-unknown-lynxos${UNAME_RELEASE}
	exit ;;
    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
	echo powerpc-unknown-lynxos"$UNAME_RELEASE"
    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
	echo powerpc-unknown-lynxos${UNAME_RELEASE}
	exit ;;
    SM[BE]S:UNIX_SV:*:*)
	echo mips-dde-sysv"$UNAME_RELEASE"
	echo mips-dde-sysv${UNAME_RELEASE}
	exit ;;
    RM*:ReliantUNIX-*:*:*)
	echo mips-sni-sysv4
	exit ;;
    RM*:SINIX-*:*:*)
	echo mips-sni-sysv4
	exit ;;
    *:SINIX-*:*:*)
	if uname -p 2>/dev/null >/dev/null ; then
		UNAME_MACHINE=`(uname -p) 2>/dev/null`
		echo "$UNAME_MACHINE"-sni-sysv4
		echo ${UNAME_MACHINE}-sni-sysv4
	else
		echo ns32k-sni-sysv
	fi
	exit ;;
    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
			# says <Richard.M.Bartel@ccMail.Census.GOV>
	echo i586-unisys-sysv4
	exit ;;
    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
                      # says <Richard.M.Bartel@ccMail.Census.GOV>
        echo i586-unisys-sysv4
        exit ;;
    *:UNIX_System_V:4*:FTX*)
	# From Gerald Hewes <hewes@openmarket.com>.
	# How about differentiating between stratus architectures? -djm
	echo hppa1.1-stratus-sysv4
	exit ;;
    *:*:*:FTX*)
	# From seanf@swdc.stratus.com.
	echo i860-stratus-sysv4
	exit ;;
    i*86:VOS:*:*)
	# From Paul.Green@stratus.com.
	echo "$UNAME_MACHINE"-stratus-vos
	echo ${UNAME_MACHINE}-stratus-vos
	exit ;;
    *:VOS:*:*)
	# From Paul.Green@stratus.com.
	echo hppa1.1-stratus-vos
	exit ;;
    mc68*:A/UX:*:*)
	echo m68k-apple-aux"$UNAME_RELEASE"
	echo m68k-apple-aux${UNAME_RELEASE}
	exit ;;
    news*:NEWS-OS:6*:*)
	echo mips-sony-newsos6
	exit ;;
    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
	if [ -d /usr/nec ]; then
		echo mips-nec-sysv"$UNAME_RELEASE"
	        echo mips-nec-sysv${UNAME_RELEASE}
	else
		echo mips-unknown-sysv"$UNAME_RELEASE"
	        echo mips-unknown-sysv${UNAME_RELEASE}
	fi
	exit ;;
        exit ;;
    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
	echo powerpc-be-beos
	exit ;;
    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
	echo powerpc-apple-beos
	exit ;;
    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
	echo i586-pc-beos
	exit ;;
    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
	echo i586-pc-haiku
	exit ;;
    x86_64:Haiku:*:*)
	echo x86_64-unknown-haiku
	exit ;;
    SX-4:SUPER-UX:*:*)
	echo sx4-nec-superux"$UNAME_RELEASE"
	echo sx4-nec-superux${UNAME_RELEASE}
	exit ;;
    SX-5:SUPER-UX:*:*)
	echo sx5-nec-superux"$UNAME_RELEASE"
	echo sx5-nec-superux${UNAME_RELEASE}
	exit ;;
    SX-6:SUPER-UX:*:*)
	echo sx6-nec-superux"$UNAME_RELEASE"
	echo sx6-nec-superux${UNAME_RELEASE}
	exit ;;
    SX-7:SUPER-UX:*:*)
	echo sx7-nec-superux"$UNAME_RELEASE"
	echo sx7-nec-superux${UNAME_RELEASE}
	exit ;;
    SX-8:SUPER-UX:*:*)
	echo sx8-nec-superux"$UNAME_RELEASE"
	echo sx8-nec-superux${UNAME_RELEASE}
	exit ;;
    SX-8R:SUPER-UX:*:*)
	echo sx8r-nec-superux"$UNAME_RELEASE"
	echo sx8r-nec-superux${UNAME_RELEASE}
	exit ;;
    SX-ACE:SUPER-UX:*:*)
	echo sxace-nec-superux"$UNAME_RELEASE"
	exit ;;
    Power*:Rhapsody:*:*)
	echo powerpc-apple-rhapsody"$UNAME_RELEASE"
	echo powerpc-apple-rhapsody${UNAME_RELEASE}
	exit ;;
    *:Rhapsody:*:*)
	echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
	exit ;;
    *:Darwin:*:*)
	UNAME_PROCESSOR=`uname -p`
	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
	case $UNAME_PROCESSOR in
	    unknown) UNAME_PROCESSOR=powerpc ;;
	esac
	if command -v xcode-select > /dev/null 2> /dev/null && \
		! xcode-select --print-path > /dev/null 2> /dev/null ; then
	    # Avoid executing cc if there is no toolchain installed as
	    # cc will be a stub that puts up a graphical alert
	    # prompting the user to install developer tools.
	    CC_FOR_BUILD=no_compiler_found
	else
	    set_cc_for_build
	fi
	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
		   grep IS_64BIT_ARCH >/dev/null
	    then
		case $UNAME_PROCESSOR in
		    i386) UNAME_PROCESSOR=x86_64 ;;
		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
		esac
	    fi
	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
		   grep IS_PPC >/dev/null
	    then
		UNAME_PROCESSOR=powerpc
	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
	    fi
	elif test "$UNAME_PROCESSOR" = i386 ; then
	    # uname -m returns i386 or x86_64
	    UNAME_PROCESSOR=$UNAME_MACHINE
	fi
	echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
	exit ;;
    *:procnto*:*:* | *:QNX:[0123456789]*:*)
	UNAME_PROCESSOR=`uname -p`
	if test "$UNAME_PROCESSOR" = x86; then
	if test "$UNAME_PROCESSOR" = "x86"; then
		UNAME_PROCESSOR=i386
		UNAME_MACHINE=pc
	fi
	echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
	exit ;;
    *:QNX:*:4*)
	echo i386-pc-qnx
	exit ;;
    NEO-*:NONSTOP_KERNEL:*:*)
    NSE-?:NONSTOP_KERNEL:*:*)
	echo neo-tandem-nsk"$UNAME_RELEASE"
	exit ;;
    NSE-*:NONSTOP_KERNEL:*:*)
	echo nse-tandem-nsk"$UNAME_RELEASE"
	echo nse-tandem-nsk${UNAME_RELEASE}
	exit ;;
    NSR-*:NONSTOP_KERNEL:*:*)
	echo nsr-tandem-nsk"$UNAME_RELEASE"
    NSR-?:NONSTOP_KERNEL:*:*)
	echo nsr-tandem-nsk${UNAME_RELEASE}
	exit ;;
    NSV-*:NONSTOP_KERNEL:*:*)
	echo nsv-tandem-nsk"$UNAME_RELEASE"
	exit ;;
    NSX-*:NONSTOP_KERNEL:*:*)
	echo nsx-tandem-nsk"$UNAME_RELEASE"
	exit ;;
    *:NonStop-UX:*:*)
	echo mips-compaq-nonstopux
	exit ;;
    BS2000:POSIX*:*:*)
	echo bs2000-siemens-sysv
	exit ;;
    DS/*:UNIX_System_V:*:*)
	echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
	exit ;;
    *:Plan9:*:*)
	# "uname -m" is not consistent, so use $cputype instead. 386
	# is converted to i386 for consistency with other x86
	# operating systems.
	# shellcheck disable=SC2154
	if test "$cputype" = 386; then
	if test "$cputype" = "386"; then
	    UNAME_MACHINE=i386
	else
	    UNAME_MACHINE="$cputype"
	fi
	echo "$UNAME_MACHINE"-unknown-plan9
	echo ${UNAME_MACHINE}-unknown-plan9
	exit ;;
    *:TOPS-10:*:*)
	echo pdp10-unknown-tops10
	exit ;;
    *:TENEX:*:*)
	echo pdp10-unknown-tenex
	exit ;;
    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
	echo pdp10-dec-tops20
	exit ;;
    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
	echo pdp10-xkl-tops20
	exit ;;
    *:TOPS-20:*:*)
	echo pdp10-unknown-tops20
	exit ;;
    *:ITS:*:*)
	echo pdp10-unknown-its
	exit ;;
    SEI:*:*:SEIUX)
	echo mips-sei-seiux"$UNAME_RELEASE"
        echo mips-sei-seiux${UNAME_RELEASE}
	exit ;;
    *:DragonFly:*:*)
	echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
	exit ;;
    *:*VMS:*:*)
	UNAME_MACHINE=`(uname -p) 2>/dev/null`
	case "$UNAME_MACHINE" in
    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
	case "${UNAME_MACHINE}" in
	    A*) echo alpha-dec-vms ; exit ;;
	    I*) echo ia64-dec-vms ; exit ;;
	    V*) echo vax-dec-vms ; exit ;;
	esac ;;
    *:XENIX:*:SysV)
	echo i386-pc-xenix
	exit ;;
    i*86:skyos:*:*)
	echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
	exit ;;
    i*86:rdos:*:*)
	echo "$UNAME_MACHINE"-pc-rdos
	echo ${UNAME_MACHINE}-pc-rdos
	exit ;;
    i*86:AROS:*:*)
	echo "$UNAME_MACHINE"-pc-aros
	exit ;;
    x86_64:VMkernel:*:*)
	echo "$UNAME_MACHINE"-unknown-esx
	exit ;;
    amd64:Isilon\ OneFS:*:*)
	echo x86_64-unknown-onefs
	exit ;;
    *:Unleashed:*:*)
	echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
	exit ;;
esac

# No uname command or uname output not recognized.
set_cc_for_build
cat > "$dummy.c" <<EOF
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2

eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
#include <sys/types.h>
#include <sys/utsname.h>
# include <sys/types.h>
# include <sys/utsname.h>
#endif
#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
#include <signal.h>
#if defined(_SIZE_T_) || defined(SIGLOST)
#include <sys/utsname.h>
#endif
#endif
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
     I don't know....  */
  printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
  printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
  "4"
          "4"
#else
  ""
	  ""
#endif
  ); exit (0);
         ); exit (0);
#endif
#endif

#if defined (__arm) && defined (__acorn) && defined (__unix)
  printf ("arm-acorn-riscix\n"); exit (0);
#endif

#if defined (hp300) && !defined (hpux)
  printf ("m68k-hp-bsd\n"); exit (0);
#endif

#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
  int version;
1531
1532
1533
1534
1535
1536
1537
1538

1539
1540
1541
1542
1543
1544
1545
1546
1547










1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
















1567
1568
1569
1570
1571
1572
1573


1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596

1597
1598
1599
1600
1601
1602

1603
1604
1605
1606
1607

1608
1609
1610


1611
1612
1613





















1614
1615

1616
1617
1618
1619



1620
1621

1622
1623

1624

1625
1626
1627



1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649




1650
1651
1652
1653
1654
1655

1656
1657
1658
1659
1406
1407
1408
1409
1410
1411
1412

1413
1414








1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
















1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443







1444
1445












1446
1447
1448
1449
1450
1451
1452
1453
1454
1455

1456
1457
1458
1459

1460

1461
1462




1463
1464


1465
1466



1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491



1492
1493
1494
1495

1496
1497

1498
1499
1500



1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521




1522
1523
1524
1525
1526
1527
1528
1529
1530

1531
1532
1533
1534
1535







-
+

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



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










-
+



-

-
+

-
-
-
-
+

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


+

-
-
-
+
+
+

-
+

-
+

+
-
-
-
+
+
+


















-
-
-
-
+
+
+
+





-
+




#endif
#if defined (ns32000)
  printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif

#if defined (_SEQUENT_)
  struct utsname un;
    struct utsname un;

  uname(&un);
  if (strncmp(un.version, "V2", 2) == 0) {
    printf ("i386-sequent-ptx2\n"); exit (0);
  }
  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
    printf ("i386-sequent-ptx1\n"); exit (0);
  }
  printf ("i386-sequent-ptx\n"); exit (0);
    uname(&un);

    if (strncmp(un.version, "V2", 2) == 0) {
	printf ("i386-sequent-ptx2\n"); exit (0);
    }
    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
	printf ("i386-sequent-ptx1\n"); exit (0);
    }
    printf ("i386-sequent-ptx\n"); exit (0);

#endif

#if defined (vax)
#if !defined (ultrix)
#include <sys/param.h>
#if defined (BSD)
#if BSD == 43
  printf ("vax-dec-bsd4.3\n"); exit (0);
#else
#if BSD == 199006
  printf ("vax-dec-bsd4.3reno\n"); exit (0);
#else
  printf ("vax-dec-bsd\n"); exit (0);
#endif
#endif
#else
  printf ("vax-dec-bsd\n"); exit (0);
#endif
#else
# if !defined (ultrix)
#  include <sys/param.h>
#  if defined (BSD)
#   if BSD == 43
      printf ("vax-dec-bsd4.3\n"); exit (0);
#   else
#    if BSD == 199006
      printf ("vax-dec-bsd4.3reno\n"); exit (0);
#    else
      printf ("vax-dec-bsd\n"); exit (0);
#    endif
#   endif
#  else
    printf ("vax-dec-bsd\n"); exit (0);
#  endif
# else
#if defined(_SIZE_T_) || defined(SIGLOST)
  struct utsname un;
  uname (&un);
  printf ("vax-dec-ultrix%s\n", un.release); exit (0);
#else
  printf ("vax-dec-ultrix\n"); exit (0);
#endif
    printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#endif
#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
#if defined(_SIZE_T_) || defined(SIGLOST)
  struct utsname *un;
  uname (&un);
  printf ("mips-dec-ultrix%s\n", un.release); exit (0);
#else
  printf ("mips-dec-ultrix\n"); exit (0);
#endif
#endif
#endif

#if defined (alliant) && defined (i860)
  printf ("i860-alliant-bsd\n"); exit (0);
#endif

  exit (1);
}
EOF

$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` &&
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
	{ echo "$SYSTEM_NAME"; exit; }

# Apollos put the system type in the environment.
test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }

echo "$0: unable to guess system type" >&2
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }

case "$UNAME_MACHINE:$UNAME_SYSTEM" in
    mips:Linux | mips64:Linux)
	# If we got here on MIPS GNU/Linux, output extra information.
	cat >&2 <<EOF
# Convex versions that predate uname can use getsysinfo(1)

NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
the system type. Please install a C compiler and try again.
if [ -x /usr/convex/getsysinfo ]
then
EOF
	;;
esac
    case `getsysinfo -f cpu_type` in
    c1*)
	echo c1-convex-bsd
	exit ;;
    c2*)
	if getsysinfo -f scalar_acc
	then echo c32-convex-bsd
	else echo c2-convex-bsd
	fi
	exit ;;
    c34*)
	echo c34-convex-bsd
	exit ;;
    c38*)
	echo c38-convex-bsd
	exit ;;
    c4*)
	echo c4-convex-bsd
	exit ;;
    esac
fi

cat >&2 <<EOF
$0: unable to guess system type

This script (version $timestamp), has failed to recognize the
operating system you are using. If your script is old, overwrite *all*
copies of config.guess and config.sub with the latest versions from:
This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from

  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
and
  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub

If the version you run ($0) is already up to date, please
If $0 has already been updated, send the following data and any
information you think might be pertinent to config-patches@gnu.org to
provide the necessary information to handle your system.
send the following data and any information you think might be
pertinent to <config-patches@gnu.org> in order to provide the needed
information to handle your system.

config.guess timestamp = $timestamp

uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`

/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`

hostinfo               = `(hostinfo) 2>/dev/null`
/bin/universe          = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch              = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`

UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
UNAME_SYSTEM  = "$UNAME_SYSTEM"
UNAME_VERSION = "$UNAME_VERSION"
UNAME_MACHINE = ${UNAME_MACHINE}
UNAME_RELEASE = ${UNAME_RELEASE}
UNAME_SYSTEM  = ${UNAME_SYSTEM}
UNAME_VERSION = ${UNAME_VERSION}
EOF

exit 1

# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:

Changes to config.sub.

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


+
-
+
+

-
+

+
+
+
+
-
-
-
+
+
+


-
-
-
-
+
+
+
+


-
+
+
+




-
+
-
-


-
+
+






-
-
-


















-
+
+



-
+









+
-
+







#! /bin/sh
# Configuration validation subroutine script.
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
#   Copyright 1992-2019 Free Software Foundation, Inc.
#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
#   Inc.

timestamp='2019-05-23'
timestamp='2007-06-28'

# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine.  It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://www.gnu.org/licenses/>.
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# the same distribution terms that you use for the rest of that program.
# program.  This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").


# Please send patches to <config-patches@gnu.org>.
# Please send patches to <config-patches@gnu.org>.  Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.

# You can get the latest version of this script from:
# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub

# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support.  The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.

# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.

me=`echo "$0" | sed -e 's,.*/,,'`

usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Usage: $0 [OPTION] CPU-MFR-OPSYS
       $0 [OPTION] ALIAS

Canonicalize a configuration name.

Options:
Operation modes:
  -h, --help         print this help, then exit
  -t, --time-stamp   print date of last modification, then exit
  -v, --version      print version number, then exit

Report bugs and patches to <config-patches@gnu.org>."

version="\
GNU config.sub ($timestamp)

Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright 1992-2019 Free Software Foundation, Inc.
Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."

help="
Try \`$me --help' for more information."

85
86
87
88
89
90
91
92

93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134



135
136

137
138

139
140

141
142
143

144
145
146


147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165


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


180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214



215
216
217
218


219
220
221
222

223
224
225
226
227
228
229
230

231
232

233
234
235
236
237
238









239
240
241
242
243
244
245

246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

285
286

287
288
289

290
291

292
293
294
295


296
297
298
299
300

301
302

303
304
305

306
307
308
309
310
311

312
313
314

315
316
317
318

319
320
321
322
323
324
325

326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363
364
365

366
367
368

369
370

371
372
373

374
375
376
377
378


379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401

402
403
404
405
406
407
408

409
410
411


412
413

414
415
416

417
418
419


420
421

422
423
424

425
426

427
428
429
430
431
432
433
434
435
436
437


438
439
440
441
442
443
444

445
446

447
448
449
450
451

452
453
454
455
456


457
458

459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
491
492
493
494
495
496


497
498

499
500
501

502
503
504
505

506
507
508

509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528


529
530

531
532
533
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
549
550
551
552
553

554
555
556

557
558

559
560
561
562
563
564


565
566

567
568
569

570
571
572

573
574
575


576
577
578
579



580
581
582
583
584

585
586

587
588

589
590
591
592
593
594


595
596
597

598
599
600
601
602


603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629

630
631
632

633
634
635
636
637
638
639



640
641
642
643

644
645
646


647
648
649
650
651

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667

668
669
670
671



672
673
674
675

676
677
678
679
680
681
682

683
684
685
686
687

688
689
690
691

692
693

694
695
696


697
698
699

700
701
702
703

704
705
706
707
708
709
710
711

712
713
714
715
716
717
718




719
720
721
722
723
724
725
726

727
728

729
730
731
732
733
734
735
736
737
738


739
740
741
742
743
744
745


746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763

764
765
766
767

768
769
770
771
772



773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791

792
793
794
795
796
797


798
799

800
801
802
803
804
805

806
807
808
809
810
811
812
813

814
815
816
817



818
819
820
821
822
823
824
825




826
827
828
829
830
831
832
833
834
835
836
837
838


839
840
841


842
843
844
845
846
847
848
849

850
851
852
853
854
855
856


857

858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895


896
897
898
899
900
901
902
903
904
905
906
907
908
909
910


911
912
913
914
915
916

917
918
919
920


921
922
923
924
925
926
927
928
929
930
931
932
933

934
935

936
937



938
939

940
941
942
943
944
945
946
947
948









949
950
951
952
953
954
955
956
957
958
959
960
961




















962
963
964
965




966
967
968



969
970
971







972
973



974
975
976
977
978
979
980









981
982
983






984



985
986


987
988
989


990
991
992
993
994
995


996
997
998



999

1000

1001
1002
1003
1004
1005


1006
1007
1008
1009











1010
1011

1012


1013
1014

1015




1016
1017
1018






















1019





















































1020
1021

























1022
1023
1024












































1025












1026
1027










1028









































































1029
1030
1031




















































1032
1033


1034














1035
1036
1037

1038
1039
1040
1041



1042
1043
1044
1045
1046
1047

1048
1049
1050
1051


1052
1053
1054
1055
1056
1057
1058
1059
1060

1061
1062
1063
1064
1065
1066


1067
1068
1069

1070
1071


1072
1073


1074

1075
1076
1077
1078
1079
1080
1081



1082
1083
1084



1085
1086

1087
1088
1089


1090
1091
1092
1093



1094
1095
1096
1097
1098
1099
1100
1101






1102
1103


1104
1105

1106

1107

1108
1109
1110
1111

1112
1113
1114
1115



1116
1117
1118
1119



1120
1121
1122



1123

1124
1125


1126
1127
1128
1129


1130
1131
1132
1133
1134








1135
1136
1137
1138











1139
1140
1141
1142










1143















1144
1145
1146








1147









1148
1149
1150







1151







1152

1153

1154











1155
1156


















1157
1158
1159
1160
1161









1162
1163

1164
1165
1166
1167
1168
1169



1170
1171
1172
1173
1174
1175



























1176
1177
1178




1179
1180
1181
1182
1183


1184
1185
1186
1187
1188















1189
1190

1191
1192
1193
1194
1195



1196
1197
1198
1199
1200














1201
1202
1203
1204




1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219


























































1220
1221










1222
1223
1224
1225
1226
1227



















1228
1229
1230
1231
1232
1233
1234
1235
1236





























1237
1238
1239
1240
1241
1242
1243















1244
1245
1246




1247
1248
1249









1250
1251
1252









1253
1254
1255
1256
1257
1258
1259
1260
1261





























1262
1263
1264
1265
1266
1267
1268
1269
1270



1271
1272
1273


1274
1275
1276
1277
1278
1279
1280
1281

1282
1283
1284
1285
1286



1287
1288
1289
1290
1291
1292
1293

1294
1295
1296
1297


1298
1299
1300

1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311

1312
1313
1314


1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326


1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340

1341
1342
1343
1344
1345




1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359













1360
1361
1362
1363
1364
1365
1366
1367
1368
1369









1370
1371
1372
1373
1374
1375
1376



1377
1378
1379

1380
1381
1382
1383
1384
1385
1386

1387
1388

1389
1390
1391
1392
1393



1394



1395
1396


1397
1398

1399
1400













1401
1402
1403
1404
1405

1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1425
1426


1427
1428
1429


1430
1431
1432


1433
1434
1435


1436
1437
1438


1439
1440
1441


1442
1443
1444


1445
1446
1447


1448
1449
1450


1451
1452
1453


1454
1455
1456


1457
1458
1459

1460






1461
1462
1463
1464
1465
1466
1467
1468
1469


1470
1471
1472


1473
1474
1475


1476
1477
1478


1479
1480
1481


1482
1483
1484


1485
1486
1487


1488
1489
1490


1491
1492
1493


1494
1495
1496


1497
1498

1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509






1510
1511
1512
1513

1514
1515

1516
1517
1518
1519


1520

1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538



1539
1540
1541


1542
1543
1544

1545
1546
1547

1548
1549
1550

1551
1552
1553


1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575

1576
1577
1578

1579
1580
1581

1582
1583
1584

1585
1586
1587

1588
1589
1590




1591
1592
1593

1594
1595
1596


1597
1598
1599

1600
1601
1602

1603
1604
1605

1606
1607
1608

1609
1610
1611

1612
1613
1614
1615
1616
1617

1618



1619
1620

1621
1622
1623


1624
1625
1626

1627
1628
1629

1630
1631
1632

1633
1634
1635

1636
1637
1638

1639
1640
1641

1642
1643
1644

1645
1646
1647

1648
1649
1650

1651
1652
1653

1654
1655
1656

1657
1658
1659


1660
1661
1662

1663
1664
1665

1666
1667
1668

1669
1670
1671

1672



1673
1674

1675
1676
1677

1678
1679
1680

1681
1682
1683

1684
1685
1686

1687
1688
1689

1690
1691
1692

1693
1694
1695

1696
1697
1698

1699
1700
1701

1702
1703
1704

1705
1706
1707
1708
1709
1710

1711
1712
1713
1714
1715
1716
1717
1718



1719
1720

1721
1722
1723

1724
1725
1726

1727
1728
1729

1730
1731
1732

1733
1734
1735

1736
1737
1738

1739
1740
1741

1742
1743
1744

1745
1746
1747

1748
1749
1750

1751
1752
1753
1754
1755
1756

1757
1758
1759

1760
1761
1762

1763
1764
1765

1766
1767
1768

1769
1770
1771

1772
1773
1774

1775
1776
1777

1778
1779
1780

1781
1782
1783

1784
1785
1786

1787
1788
1789
1790

1791
1792
1793
1794

1795
1796
1797
1798
91
92
93
94
95
96
97

98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118






119












120




121
122
123


124


125


126



127



128
129










130









131
132














133
134





135






























136
137
138




139
140




141








142


143






144
145
146
147
148
149
150
151
152







153


154





































155


156



157


158




159
160





161


162



163






164



165




166







167


168


































169




170



171


172



173





174
175



















176




177







178



179
180


181



182



183
184


185



186


187











188
189







190


191





192





193
194


195

























196













197
198


199



200




201



202


203


















204
205


206











207












208



209


210






211
212


213



214



215



216
217




218
219
220





221


222


223






224
225



226





227
228



























229



230







231
232
233


234

235
236


237
238





239
















240




241
242
243




244







245





246




247


248



249
250



251




252








253







254
255
256
257








258


259










260
261







262
263








264










265




266





267
268
269



















270






271
272


273






274








275




276
277
278








279
280
281
282













283
284



285
286








287







288
289

290
291





































292
293















294
295


296



297
298



299
300
301
302






303
304
305
306

307


308


309
310
311


312

313







314
315
316
317
318
319
320
321
322













323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342




343
344
345
346



347
348
349



350
351
352
353
354
355
356


357
358
359







360
361
362
363
364
365
366
367
368



369
370
371
372
373
374
375
376
377
378


379
380
381


382
383
384





385
386
387


388
389
390
391
392

393


394


395
396




397
398
399
400
401
402
403
404
405
406
407
408

409

410
411
412

413
414
415
416
417
418



419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494


495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520


521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577


578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661



662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717

718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

734
735



736
737
738
739





740




741
742
743








744






745
746
747


748


749
750

751
752
753

754

755





756
757
758
759


760
761
762
763

764



765
766

767


768
769
770








771
772
773
774
775
776


777
778


779
780
781

782




783
784



785
786
787
788



789
790
791
792


793
794
795
796
797


798
799

800


801
802

803
804


805
806
807
808
809
810
811
812
813



814
815
816
817
818
819
820
821
822
823
824
825



826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851



852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869



870
871
872
873
874
875
876
877
878
879
880
881
882
883
884

885

886
887
888
889
890
891
892
893
894
895
896
897
898


899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916





917
918
919
920
921
922
923
924
925


926






927
928
929






930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956



957
958
959
960





961
962





963
964
965
966
967
968
969
970
971
972
973
974
975
976
977


978





979
980
981





982
983
984
985
986
987
988
989
990
991
992
993
994
995




996
997
998
999















1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057


1058
1059
1060
1061
1062
1063
1064
1065
1066
1067






1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086









1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115







1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130



1131
1132
1133
1134



1135
1136
1137
1138
1139
1140
1141
1142
1143



1144
1145
1146
1147
1148
1149
1150
1151
1152









1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181


1182
1183
1184
1185



1186
1187
1188
1189


1190
1191
1192
1193
1194
1195
1196
1197
1198

1199
1200
1201



1202
1203
1204







1205
1206
1207


1208
1209
1210


1211











1212
1213


1214
1215
1216











1217
1218
1219













1220
1221




1222
1223
1224
1225














1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238










1239
1240
1241
1242
1243
1244
1245
1246
1247


1248
1249



1250
1251
1252
1253
1254

1255
1256
1257
1258




1259
1260

1261
1262
1263



1264
1265
1266
1267
1268
1269
1270


1271
1272
1273

1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289





1290
1291




1292







1293
1294








1295
1296
1297


1298
1299
1300


1301
1302
1303


1304
1305
1306


1307
1308
1309


1310
1311
1312


1313
1314
1315


1316
1317
1318


1319
1320
1321


1322
1323
1324


1325
1326
1327
1328

1329
1330
1331
1332
1333
1334
1335
1336
1337








1338
1339
1340


1341
1342
1343


1344
1345
1346


1347
1348
1349


1350
1351
1352


1353
1354
1355


1356
1357
1358


1359
1360
1361


1362
1363
1364


1365
1366
1367

1368











1369
1370
1371
1372
1373
1374




1375
1376

1377
1378


1379
1380
1381

1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397



1398
1399
1400
1401


1402
1403
1404
1405

1406
1407
1408

1409
1410
1411

1412
1413


1414
1415
1416


















1417
1418

1419
1420
1421

1422
1423
1424

1425
1426
1427

1428
1429
1430

1431
1432
1433

1434
1435
1436
1437
1438
1439

1440
1441


1442
1443
1444
1445

1446
1447
1448

1449
1450
1451

1452
1453
1454

1455
1456
1457

1458



1459
1460

1461
1462
1463
1464
1465
1466

1467
1468


1469
1470
1471
1472

1473
1474
1475

1476
1477
1478

1479
1480
1481

1482
1483
1484

1485
1486
1487

1488
1489
1490

1491
1492
1493

1494
1495
1496

1497
1498
1499

1500
1501
1502

1503
1504


1505
1506
1507
1508

1509
1510
1511

1512
1513
1514

1515
1516
1517

1518
1519
1520
1521
1522
1523

1524
1525
1526

1527
1528
1529

1530
1531
1532

1533
1534
1535

1536
1537
1538

1539
1540
1541

1542
1543
1544

1545
1546
1547

1548
1549
1550

1551
1552
1553

1554
1555



1556

1557
1558
1559
1560
1561
1562
1563


1564
1565
1566
1567

1568
1569
1570

1571
1572
1573

1574
1575
1576

1577
1578
1579

1580
1581
1582

1583
1584
1585

1586
1587
1588

1589
1590
1591

1592
1593
1594

1595
1596
1597

1598
1599
1600




1601
1602
1603

1604
1605
1606

1607
1608
1609

1610
1611
1612

1613
1614
1615

1616
1617
1618

1619
1620
1621

1622
1623
1624

1625
1626
1627

1628
1629
1630
1631
1632
1633
1634
1635

1636
1637
1638
1639

1640
1641
1642
1643
1644







-
+




-
+















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

-
+

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

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

-
-
-
+

-
-
-
+
+


-
-
-
-
-
-




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

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

+
+
+
-
-
+
+

-
-
+
+

-
-
-
-
-
+
+

-
-
+
+
+

+
-
+
-
-

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

-
+
-
+
+

-
+

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

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

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

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

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


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


-
+

-
-
-
+
+
+

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

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

-
-
+
-
-
+
+
-

+
+
-
+
-

-
-
-
-
-
+
+
+

-
-
+
+
+

-
+
-
-
-
+
+
-

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

+
-
+
-
-
-
-
+

-
-
-
+
+
+

-
-
-
+
+
+

-
-
+
+
+

+
-
-
+
+
-

-
-
+
+
-


-
-
+
+
+
+
+
+
+
+

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

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

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

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

+
+
+
+
+
+
+
-
+
-
+

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




-
-
-
+
+
+

-
-
+
+







-
+


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


-
-
+
+

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

-
-
+
+

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

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

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


-
-
-
+
+
+


-
+



-
-
-
-
+

-
+


-
-
-
+
+
+

+
+
+
-
-
+
+

-
+


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

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

-
-
-
-
-
-
-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+


-
+

+
+
+
+
+
+

-
-
-
-
-
-
-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

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

-
+

-
-

+
+
-
+















-
-
-
+
+
+

-
-
+
+


-
+


-
+


-
+

-
-
+
+

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


-
+


-
+


-
+


-
+


-
+


-
+
+
+
+


-
+

-
-
+
+


-
+


-
+


-
+


-
+


-
+
-
-
-


-
+

+
+
+

-
+

-
-
+
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+

-
-
+
+


-
+


-
+


-
+


-
+

+
+
+

-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+

-
-
-

-
+






-
-
+
+
+

-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
-
-
-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+



+



-
+



-
+




    --help | --h* | -h )
       echo "$usage"; exit ;;
    -- )     # Stop option processing
       shift; break ;;
    - )	# Use stdin as input.
       break ;;
    -* )
       echo "$me: invalid option $1$help" >&2
       echo "$me: invalid option $1$help"
       exit 1 ;;

    *local*)
       # First pass through any local machine types.
       echo "$1"
       echo $1
       exit ;;

    * )
       break ;;
  esac
done

case $# in
 0) echo "$me: missing argument$help" >&2
    exit 1;;
 1) ;;
 *) echo "$me: too many arguments$help" >&2
    exit 1;;
esac

# Split fields of configuration type
# shellcheck disable=SC2162
IFS="-" read field1 field2 field3 field4 <<EOF
$1
EOF

# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Separate into logical components for further validation
case $1 in
	*-*-*-*-*)
		echo Invalid configuration \`"$1"\': more than four components >&2
		exit 1
		;;
	*-*-*-*)
		basic_machine=$field1-$field2
		os=$field3-$field4
		;;
	*-*-*)
		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
# Here we must recognize all the valid KERNEL-OS combinations.
		# parts
		maybe_os=$field2-$field3
		case $maybe_os in
			nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
			| linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
			| storm-chaos* | os2-emx* | rtmk-nova*)
  storm-chaos* | os2-emx* | rtmk-nova*)
				basic_machine=$field1
				os=$maybe_os
    os=-$maybe_os
				;;
			android-linux)
				basic_machine=$field1-unknown
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
				os=linux-android
				;;
			*)
    ;;
  *)
				basic_machine=$field1-$field2
				os=$field3
				;;
		esac
		;;
	*-*)
		# A lone config we happen to match not fitting any pattern
		case $field1-$field2 in
			decstation-3100)
				basic_machine=mips-dec
    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
				os=
				;;
			*-*)
				# Second component is usually, but not always the OS
				case $field2 in
					# Prevent following clause from handling this valid os
					sun*os*)
						basic_machine=$field1
						os=$field2
    if [ $basic_machine != $1 ]
    then os=`echo $1 | sed 's/.*-/-/'`
						;;
					# Manufacturers
					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
					| unicom* | ibm* | next | hp | isi* | apollo | altos* \
					| convergent* | ncr* | news | 32* | 3600* | 3100* \
					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
					| ultra | tti* | harris | dolphin | highlevel | gould \
					| cbm | ns | masscomp | apple | axis | knuth | cray \
					| microblaze* | sim | cisco \
					| oki | wec | wrs | winbond)
						basic_machine=$field1-$field2
						os=
						;;
    else os=; fi
    ;;
					*)
						basic_machine=$field1
						os=$field2
						;;
				esac
esac
			;;
		esac
		;;
	*)
		# Convert single-component short-hands not valid as part of
		# multi-component configurations.
		case $field1 in
			386bsd)
				basic_machine=i386-pc
				os=bsd
				;;
			a29khif)
				basic_machine=a29k-amd
				os=udi
				;;
			adobe68k)
				basic_machine=m68010-adobe
				os=scout
				;;
			alliant)
				basic_machine=fx80-alliant
				os=
				;;
			altos | altos3068)
				basic_machine=m68k-altos
				os=
				;;
			am29k)
				basic_machine=a29k-none
				os=bsd

### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work.  We also
				;;
			amdahl)
				basic_machine=580-amdahl
				os=sysv
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
				;;
			amiga)
				basic_machine=m68k-unknown
				os=
case $os in
				;;
			amigaos | amigados)
				basic_machine=m68k-unknown
				os=amigaos
				;;
			amigaunix | amix)
				basic_machine=m68k-unknown
				os=sysv4
	-sun*os*)
				;;
			apollo68)
		# Prevent following clause from handling this invalid input.
				basic_machine=m68k-apollo
				os=sysv
				;;
			apollo68bsd)
				basic_machine=m68k-apollo
				os=bsd
		;;
	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
	-apple | -axis | -knuth | -cray)
		os=
				;;
			aros)
				basic_machine=i386-pc
				os=aros
				;;
			aux)
				basic_machine=m68k-apple
		basic_machine=$1
				os=aux
				;;
		;;
			balance)
				basic_machine=ns32k-sequent
				os=dynix
				;;
			blackfin)
				basic_machine=bfin-unknown
				os=linux
				;;
			cegcc)
				basic_machine=arm-unknown
				os=cegcc
				;;
			convex-c1)
				basic_machine=c1-convex
				os=bsd
				;;
			convex-c2)
				basic_machine=c2-convex
				os=bsd
				;;
			convex-c32)
				basic_machine=c32-convex
				os=bsd
				;;
			convex-c34)
				basic_machine=c34-convex
				os=bsd
				;;
			convex-c38)
				basic_machine=c38-convex
				os=bsd
				;;
			cray)
				basic_machine=j90-cray
				os=unicos
				;;
			crds | unos)
	-sim | -cisco | -oki | -wec | -winbond)
				basic_machine=m68k-crds
				os=
		os=
				;;
			da30)
				basic_machine=m68k-da30
		basic_machine=$1
				os=
				;;
		;;
			decstation | pmax | pmin | dec3100 | decstatn)
				basic_machine=mips-dec
				os=
				;;
	-scout)
		;;
			delta88)
				basic_machine=m88k-motorola
				os=sysv3
				;;
			dicos)
	-wrs)
				basic_machine=i686-pc
				os=dicos
		os=-vxworks
				;;
			djgpp)
				basic_machine=i586-pc
		basic_machine=$1
				os=msdosdjgpp
				;;
			ebmon29k)
				basic_machine=a29k-amd
				os=ebmon
				;;
		;;
			es1800 | OSE68k | ose68k | ose | OSE)
				basic_machine=m68k-ericsson
				os=ose
	-chorusos*)
				;;
			gmicro)
				basic_machine=tron-gmicro
				os=sysv
		os=-chorusos
				;;
			go32)
				basic_machine=i386-pc
				os=go32
				;;
			h8300hms)
				basic_machine=h8300-hitachi
		basic_machine=$1
				os=hms
				;;
		;;
			h8300xray)
				basic_machine=h8300-hitachi
				os=xray
				;;
			h8500hms)
				basic_machine=h8500-hitachi
				os=hms
				;;
			harris)
				basic_machine=m88k-harris
				os=sysv3
				;;
			hp300)
				basic_machine=m68k-hp
				;;
			hp300bsd)
				basic_machine=m68k-hp
				os=bsd
				;;
			hp300hpux)
				basic_machine=m68k-hp
				os=hpux
				;;
			hppaosf)
				basic_machine=hppa1.1-hp
				os=osf
				;;
			hppro)
				basic_machine=hppa1.1-hp
				os=proelf
				;;
			i386mach)
				basic_machine=i386-mach
				os=mach
 	-chorusrdb)
				;;
			vsta)
				basic_machine=i386-pc
				os=vsta
 		os=-chorusrdb
				;;
			isi68 | isi)
				basic_machine=m68k-isi
		basic_machine=$1
				os=sysv
				;;
 		;;
			m68knommu)
				basic_machine=m68k-unknown
				os=linux
	-hiux*)
				;;
			magnum | m3230)
				basic_machine=mips-mips
				os=sysv
				;;
		os=-hiuxwe2
		;;
			merlin)
				basic_machine=ns32k-utek
				os=sysv
				;;
			mingw64)
				basic_machine=x86_64-pc
				os=mingw64
				;;
			mingw32)
				basic_machine=i686-pc
				os=mingw32
				;;
			mingw32ce)
				basic_machine=arm-unknown
				os=mingw32ce
				;;
			monitor)
				basic_machine=m68k-rom68k
				os=coff
	-sco6)
				;;
			morphos)
				basic_machine=powerpc-unknown
				os=morphos
		os=-sco5v6
				;;
			moxiebox)
				basic_machine=moxie-unknown
				os=moxiebox
				;;
			msdos)
				basic_machine=i386-pc
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=msdos
				;;
			msys)
		;;
	-sco5)
				basic_machine=i686-pc
				os=msys
		os=-sco3.2v5
				;;
			mvs)
				basic_machine=i370-ibm
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=mvs
				;;
			nacl)
		;;
	-sco4)
				basic_machine=le32-unknown
				os=nacl
		os=-sco3.2v4
				;;
			ncr3000)
				basic_machine=i486-ncr
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=sysv4
				;;
		;;
			netbsd386)
				basic_machine=i386-pc
				os=netbsd
				;;
			netwinder)
				basic_machine=armv4l-rebel
				os=linux
				;;
			news | news700 | news800 | news900)
				basic_machine=m68k-sony
				os=newsos
	-sco3.2.[4-9]*)
		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
				;;
			news1000)
				basic_machine=m68030-sony
				os=newsos
				;;
			necv70)
				basic_machine=v70-nec
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=sysv
				;;
		;;
			nh3000)
				basic_machine=m68k-harris
				os=cxux
				;;
			nh[45]000)
	-sco3.2v[4-9]*)
				basic_machine=m88k-harris
				os=cxux
				;;
			nindy960)
				basic_machine=i960-intel
		# Don't forget version if it is 3.2v4 or newer.
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=nindy
				;;
		;;
			mon960)
				basic_machine=i960-intel
				os=mon960
				;;
			nonstopux)
				basic_machine=mips-compaq
				os=nonstopux
				;;
			os400)
				basic_machine=powerpc-ibm
				os=os400
				;;
			OSE68000 | ose68000)
				basic_machine=m68000-ericsson
				os=ose
				;;
			os68k)
				basic_machine=m68k-none
				os=os68k
				;;
			paragon)
				basic_machine=i860-intel
				os=osf
				;;
			parisc)
	-sco5v6*)
				basic_machine=hppa-unknown
				os=linux
				;;
			pw32)
				basic_machine=i586-unknown
				os=pw32
				;;
			rdos | rdos64)
				basic_machine=x86_64-pc
				os=rdos
				;;
			rdos32)
				basic_machine=i386-pc
		# Don't forget version if it is 3.2v4 or newer.
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=rdos
				;;
		;;
			rom68k)
				basic_machine=m68k-rom68k
				os=coff
	-sco*)
				;;
			sa29200)
				basic_machine=a29k-amd
				os=udi
		os=-sco3.2v2
				;;
			sei)
				basic_machine=mips-sei
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=seiux
				;;
		;;
			sequent)
				basic_machine=i386-sequent
				os=
				;;
			sps7)
				basic_machine=m68k-bull
				os=sysv2
				;;
			st2000)
				basic_machine=m68k-tandem
				os=
				;;
			stratus)
				basic_machine=i860-stratus
				os=sysv4
				;;
			sun2)
				basic_machine=m68000-sun
	-udk*)
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=
				;;
		;;
			sun2os3)
				basic_machine=m68000-sun
				os=sunos3
				;;
			sun2os4)
				basic_machine=m68000-sun
				os=sunos4
				;;
			sun3)
				basic_machine=m68k-sun
				os=
	-isc)
				;;
			sun3os3)
				basic_machine=m68k-sun
				os=sunos3
				;;
			sun3os4)
				basic_machine=m68k-sun
				os=sunos4
				;;
			sun4)
				basic_machine=sparc-sun
				os=
		os=-isc2.2
				;;
			sun4os3)
				basic_machine=sparc-sun
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=sunos3
				;;
		;;
			sun4os4)
				basic_machine=sparc-sun
				os=sunos4
				;;
			sun4sol2)
				basic_machine=sparc-sun
	-clix*)
		basic_machine=clipper-intergraph
				os=solaris2
				;;
		;;
			sun386 | sun386i | roadrunner)
				basic_machine=i386-sun
				os=
	-isc*)
				;;
			sv1)
				basic_machine=sv1-cray
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
				os=unicos
				;;
			symmetry)
		;;
	-lynx*)
				basic_machine=i386-sequent
				os=dynix
				;;
			t3e)
		os=-lynxos
		;;
	-ptx*)
				basic_machine=alphaev5-cray
				os=unicos
				;;
			t90)
				basic_machine=t90-cray
		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
				os=unicos
				;;
		;;
			toad1)
				basic_machine=pdp10-xkl
	-windowsnt*)
				os=tops20
				;;
			tpf)
				basic_machine=s390x-ibm
				os=tpf
				;;
		os=`echo $os | sed -e 's/windowsnt/winnt/'`
		;;
			udi29k)
				basic_machine=a29k-amd
				os=udi
	-psos*)
				;;
			ultra3)
				basic_machine=a29k-nyu
				os=sym1
				;;
		os=-psos
		;;
			v810 | necv810)
				basic_machine=v810-nec
				os=none
				;;
			vaxv)
				basic_machine=vax-dec
				os=sysv
				;;
			vms)
				basic_machine=vax-dec
				os=vms
				;;
			vxworks960)
				basic_machine=i960-wrs
				os=vxworks
				;;
			vxworks68)
				basic_machine=m68k-wrs
				os=vxworks
				;;
			vxworks29k)
				basic_machine=a29k-wrs
				os=vxworks
				;;
			xbox)
				basic_machine=i686-pc
				os=mingw32
	-mint | -mint[0-9]*)
				;;
			ymp)
				basic_machine=ymp-cray
		basic_machine=m68k-atari
				os=unicos
				;;
			*)
				basic_machine=$1
				os=
				;;
		esac
		os=-mint
		;;
esac
		;;
esac

# Decode 1-component or ad-hoc basic machines
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
	# Here we handle the default manufacturer of certain CPU types.  It is in
	# some cases the only manufacturer, in others, it is the most popular.
	# Recognize the basic CPU types without company name.
	# Some are omitted here because they have special meanings below.
	w89k)
		cpu=hppa1.1
		vendor=winbond
		;;
	op50n)
	1750a | 580 \
		cpu=hppa1.1
		vendor=oki
		;;
	op60c)
		cpu=hppa1.1
		vendor=oki
		;;
	ibm*)
		cpu=i370
		vendor=ibm
		;;
	orion105)
		cpu=clipper
		vendor=highlevel
		;;
	mac | mpw | mac-mpw)
	| a29k \
		cpu=m68k
		vendor=apple
		;;
	pmac | pmac-mpw)
	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
	| am33_2.0 \
		cpu=powerpc
		vendor=apple
		;;

	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
	# Recognize the various machine names and aliases which stand
	# for a CPU type and a company and sometimes even an OS.
	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
		cpu=m68000
		vendor=att
		;;
	3b*)
	| bfin \
		cpu=we32k
		vendor=att
		;;
	bluegene*)
		cpu=powerpc
	| c4x | clipper \
		vendor=ibm
		os=cnk
		;;
	decsystem10* | dec10*)
	| d10v | d30v | dlx | dsp16xx | dvp \
		cpu=pdp10
		vendor=dec
	| fido | fr30 | frv \
		os=tops10
		;;
	decsystem20* | dec20*)
	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
	| i370 | i860 | i960 | ia64 \
		cpu=pdp10
		vendor=dec
		os=tops20
	| ip2k | iq2000 \
		;;
	delta | 3300 | motorola-3300 | motorola-delta \
	      | 3300-motorola | delta-motorola)
		cpu=m68k
	| m32c | m32r | m32rle | m68000 | m68k | m88k \
		vendor=motorola
		;;
	dpx2*)
		cpu=m68k
		vendor=bull
		os=sysv3
		;;
	encore | umax | mmax)
	| maxq | mb | microblaze | mcore | mep \
		cpu=ns32k
		vendor=encore
		;;
	elxsi)
		cpu=elxsi
		vendor=elxsi
		os=${os:-bsd}
	| mips | mipsbe | mipseb | mipsel | mipsle \
	| mips16 \
	| mips64 | mips64el \
	| mips64vr | mips64vrel \
		;;
	fx2800)
		cpu=i860
		vendor=alliant
		;;
	genix)
		cpu=ns32k
		vendor=ns
	| mips64orion | mips64orionel \
		;;
	h3050r* | hiux*)
	| mips64vr4100 | mips64vr4100el \
		cpu=hppa1.1
		vendor=hitachi
		os=hiuxwe2
		;;
	hp3k9[0-9][0-9] | hp9[0-9][0-9])
		cpu=hppa1.0
		vendor=hp
		;;
	hp9k2[0-9][0-9] | hp9k31[0-9])
		cpu=m68000
	| mips64vr4300 | mips64vr4300el \
	| mips64vr5000 | mips64vr5000el \
		vendor=hp
		;;
	hp9k3[2-9][0-9])
		cpu=m68k
		vendor=hp
		;;
	hp9k6[0-9][0-9] | hp6[0-9][0-9])
	| mips64vr5900 | mips64vr5900el \
	| mipsisa32 | mipsisa32el \
		cpu=hppa1.0
		vendor=hp
		;;
	hp9k7[0-79][0-9] | hp7[0-79][0-9])
		cpu=hppa1.1
		vendor=hp
		;;
	hp9k78[0-9] | hp78[0-9])
	| mipsisa32r2 | mipsisa32r2el \
		# FIXME: really hppa2.0-hp
		cpu=hppa1.1
		vendor=hp
		;;
	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
		# FIXME: really hppa2.0-hp
		cpu=hppa1.1
		vendor=hp
		;;
	hp9k8[0-9][13679] | hp8[0-9][13679])
	| mipsisa64 | mipsisa64el \
		cpu=hppa1.1
		vendor=hp
		;;
	hp9k8[0-9][0-9] | hp8[0-9][0-9])
	| mipsisa64r2 | mipsisa64r2el \
		cpu=hppa1.0
		vendor=hp
		;;
	i*86v32)
		cpu=`echo "$1" | sed -e 's/86.*/86/'`
	| mipsisa64sb1 | mipsisa64sb1el \
	| mipsisa64sr71k | mipsisa64sr71kel \
	| mipstx39 | mipstx39el \
		vendor=pc
		os=sysv32
		;;
	i*86v4*)
		cpu=`echo "$1" | sed -e 's/86.*/86/'`
		vendor=pc
		os=sysv4
		;;
	i*86v)
		cpu=`echo "$1" | sed -e 's/86.*/86/'`
		vendor=pc
		os=sysv
		;;
	i*86sol2)
		cpu=`echo "$1" | sed -e 's/86.*/86/'`
		vendor=pc
		os=solaris2
		;;
	j90 | j90-cray)
	| mn10200 | mn10300 \
		cpu=j90
		vendor=cray
		os=${os:-unicos}
		;;
	iris | iris4d)
		cpu=mips
	| mt \
	| msp430 \
		vendor=sgi
		case $os in
	| nios | nios2 \
		    irix*)
			;;
		    *)
			os=irix4
			;;
		esac
	| ns16k | ns32k \
		;;
	miniframe)
		cpu=m68000
		vendor=convergent
		;;
	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
		cpu=m68k
		vendor=atari
	| or32 \
		os=mint
		;;
	news-3600 | risc-news)
		cpu=mips
	| pdp10 | pdp11 | pj | pjl \
	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
	| pyramid \
		vendor=sony
		os=newsos
		;;
	next | m*-next)
		cpu=m68k
		vendor=next
		case $os in
		    openstep*)
	| score \
	| sh | sh[1234] | sh[24]a | sh[24]a*eb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
	| sh64 | sh64le \
	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
		        ;;
		    nextstep*)
			;;
		    ns2*)
		      os=nextstep2
			;;
		    *)
		      os=nextstep3
			;;
		esac
		;;
	np1)
		cpu=np1
	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
	| spu | strongarm \
		vendor=gould
		;;
	op50n-* | op60c-*)
	| tahoe | thumb | tic4x | tic80 | tron \
	| v850 | v850e \
		cpu=hppa1.1
		vendor=oki
		os=proelf
		;;
	pa-hitachi)
		cpu=hppa1.1
		vendor=hitachi
		os=hiuxwe2
	| we32k \
		;;
	pbd)
		cpu=sparc
		vendor=tti
		;;
	pbb)
		cpu=m68k
	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
	| z8k)
		vendor=tti
		basic_machine=$basic_machine-unknown
		;;
	pc532)
		cpu=ns32k
		vendor=pc532
		;;
	pn)
		cpu=pn
		vendor=gould
		;;
	power)
		cpu=power
		vendor=ibm
		;;
	ps2)
		cpu=i386
		vendor=ibm
		;;
	rm[46]00)
		cpu=mips
		vendor=siemens
		;;
	rtpc | rtpc-*)
		cpu=romp
		vendor=ibm
		;;
	sde)
		cpu=mipsisa32
		vendor=sde
		os=${os:-elf}
		;;
	simso-wrs)
		cpu=sparclite
		vendor=wrs
		os=vxworks
		;;
	tower | tower-32)
		cpu=m68k
		vendor=ncr
	m6811 | m68hc11 | m6812 | m68hc12)
		# Motorola 68HC11/12.
		;;
	vpp*|vx|vx-*)
		cpu=f301
		vendor=fujitsu
		;;
	w65)
		cpu=w65
		vendor=wdc
		;;
	w89k-*)
		cpu=hppa1.1
		vendor=winbond
		os=proelf
		;;
	none)
		basic_machine=$basic_machine-unknown
		os=-none
		cpu=none
		vendor=none
		;;
	leon|leon[3-9])
		cpu=sparc
		vendor=$basic_machine
	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
		;;
	leon-*|leon[3-9]-*)
		cpu=sparc
		vendor=`echo "$basic_machine" | sed 's/-.*//'`
	ms1)
		basic_machine=mt-unknown
		;;

	*-*)
		# shellcheck disable=SC2162
		IFS="-" read cpu vendor <<EOF
$basic_machine
EOF
		;;
	# We use `pc' rather than `unknown'
	# because (1) that's what they normally are, and
	# (2) the word "unknown" tends to confuse beginning users.
	i*86 | x86_64)
		cpu=$basic_machine
	  basic_machine=$basic_machine-pc
		vendor=pc
		;;
	  ;;
	# These rules are duplicated from below for sake of the special case above;
	# i.e. things that normalized to x86 arches should also default to "pc"
	# Object if more than one company name word.
	*-*-*)
		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
	pc98)
		cpu=i386
		exit 1
		vendor=pc
		;;
	x64 | amd64)
		cpu=x86_64
		vendor=pc
		;;
	# Recognize the basic CPU types without company name.
	*)
		cpu=$basic_machine
	# Recognize the basic CPU types with company name.
	580-* \
	| a29k-* \
	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
	| avr-* | avr32-* \
	| bfin-* | bs2000-* \
		vendor=unknown
		;;
esac

unset -v basic_machine

# Decode basic machines in the full and proper CPU-Company form.
case $cpu-$vendor in
	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
	# some cases the only manufacturer, in others, it is the most popular.
	craynv-unknown)
		vendor=cray
		os=${os:-unicosmp}
	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
	| clipper-* | craynv-* | cydra-* \
	| d10v-* | d30v-* | dlx-* \
	| elxsi-* \
	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
	| h8300-* | h8500-* \
	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
	| i*86-* | i860-* | i960-* | ia64-* \
	| ip2k-* | iq2000-* \
	| m32c-* | m32r-* | m32rle-* \
	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
	| m88110-* | m88k-* | maxq-* | mcore-* \
	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
	| mips16-* \
	| mips64-* | mips64el-* \
	| mips64vr-* | mips64vrel-* \
	| mips64orion-* | mips64orionel-* \
	| mips64vr4100-* | mips64vr4100el-* \
	| mips64vr4300-* | mips64vr4300el-* \
	| mips64vr5000-* | mips64vr5000el-* \
		;;
	c90-unknown | c90-cray)
		vendor=cray
		os=${os:-unicos}
	| mips64vr5900-* | mips64vr5900el-* \
	| mipsisa32-* | mipsisa32el-* \
	| mipsisa32r2-* | mipsisa32r2el-* \
	| mipsisa64-* | mipsisa64el-* \
		;;
	fx80-unknown)
		vendor=alliant
	| mipsisa64r2-* | mipsisa64r2el-* \
	| mipsisa64sb1-* | mipsisa64sb1el-* \
	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
		;;
	romp-unknown)
		vendor=ibm
	| mipstx39-* | mipstx39el-* \
	| mmix-* \
	| mt-* \
	| msp430-* \
	| nios-* | nios2-* \
	| none-* | np1-* | ns16k-* | ns32k-* \
	| orion-* \
		;;
	mmix-unknown)
	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
	| pyramid-* \
		vendor=knuth
		;;
	microblaze-unknown | microblazeel-unknown)
		vendor=xilinx
		;;
	rs6000-unknown)
		vendor=ibm
	| romp-* | rs6000-* \
	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]a*eb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
	| sparclite-* \
	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
	| tahoe-* | thumb-* \
	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
	| tron-* \
		;;
	vax-unknown)
		vendor=dec
	| v850-* | v850e-* | vax-* \
	| we32k-* \
	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
	| xstormy16-* | xtensa-* \
	| ymp-* \
	| z8k-*)
		;;
	# Recognize the various machine names and aliases which stand
	# for a CPU type and a company and sometimes even an OS.
	386bsd)
	pdp11-unknown)
		vendor=dec
		basic_machine=i386-unknown
		os=-bsd
		;;
	we32k-unknown)
		vendor=att
	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
		basic_machine=m68000-att
		;;
	cydra-unknown)
		vendor=cydrome
		;;
	i370-ibm*)
		vendor=ibm
	3b*)
		basic_machine=we32k-att
		;;
	orion-unknown)
		vendor=highlevel
	a29khif)
		basic_machine=a29k-amd
		os=-udi
		;;
    	abacus)
	xps-unknown | xps100-unknown)
		basic_machine=abacus-unknown
		cpu=xps100
		vendor=honeywell
		;;

	# Here we normalize CPU types with a missing or matching vendor
	adobe68k)
		basic_machine=m68010-adobe
	dpx20-unknown | dpx20-bull)
		cpu=rs6000
		vendor=bull
		os=${os:-bosx}
		os=-scout
		;;
	alliant | fx80)
		basic_machine=fx80-alliant
		;;
	altos | altos3068)
		basic_machine=m68k-altos
		;;
	am29k)
		basic_machine=a29k-none
		os=-bsd
		;;

	amd64)
	# Here we normalize CPU types irrespective of the vendor
		basic_machine=x86_64-pc
		;;
	amd64-*)
		cpu=x86_64
		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	amdahl)
		basic_machine=580-amdahl
		os=-sysv
		;;
	blackfin-*)
		cpu=bfin
		os=linux
	amiga | amiga-*)
		basic_machine=m68k-unknown
		;;
	amigaos | amigados)
		basic_machine=m68k-unknown
		os=-amigaos
		;;
	amigaunix | amix)
		basic_machine=m68k-unknown
		os=-sysv4
		;;
	apollo68)
		basic_machine=m68k-apollo
		os=-sysv
		;;
	apollo68bsd)
		basic_machine=m68k-apollo
		os=-bsd
		;;
	aux)
		basic_machine=m68k-apple
		os=-aux
		;;
	balance)
		basic_machine=ns32k-sequent
		os=-dynix
		;;
	c90)
		basic_machine=c90-cray
		os=-unicos
		;;
	convex-c1)
		basic_machine=c1-convex
		os=-bsd
		;;
	convex-c2)
		basic_machine=c2-convex
		os=-bsd
		;;
	convex-c32)
		basic_machine=c32-convex
		os=-bsd
		;;
	convex-c34)
		basic_machine=c34-convex
		os=-bsd
		;;
	convex-c38)
		basic_machine=c38-convex
		os=-bsd
		;;
	cray | j90)
		basic_machine=j90-cray
		os=-unicos
		;;
	craynv)
		basic_machine=craynv-cray
		os=-unicosmp
		;;
	cr16)
		basic_machine=cr16-unknown
		os=-elf
		;;
	crds | unos)
		basic_machine=m68k-crds
		;;
	crisv32 | crisv32-* | etraxfs*)
		basic_machine=crisv32-axis
		;;
	cris | cris-* | etrax*)
		basic_machine=cris-axis
		;;
	crx)
		basic_machine=crx-unknown
		os=-elf
		;;
	c54x-*)
		cpu=tic54x
	da30 | da30-*)
		basic_machine=m68k-da30
		;;
	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
		basic_machine=mips-dec
		;;
	decsystem10* | dec10*)
		basic_machine=pdp10-dec
		os=-tops10
		;;
	decsystem20* | dec20*)
		basic_machine=pdp10-dec
		os=-tops20
		;;
	delta | 3300 | motorola-3300 | motorola-delta \
	      | 3300-motorola | delta-motorola)
		basic_machine=m68k-motorola
		;;
	delta88)
		basic_machine=m88k-motorola
		os=-sysv3
		;;
	djgpp)
		basic_machine=i586-pc
		os=-msdosdjgpp
		;;
	c55x-*)
		cpu=tic55x
	dpx20 | dpx20-*)
		basic_machine=rs6000-bull
		os=-bosx
		;;
	dpx2* | dpx2*-bull)
		basic_machine=m68k-bull
		os=-sysv3
		;;
	ebmon29k)
		basic_machine=a29k-amd
		os=-ebmon
		;;
	elxsi)
		basic_machine=elxsi-elxsi
		os=-bsd
		;;
	encore | umax | mmax)
		basic_machine=ns32k-encore
		;;
	es1800 | OSE68k | ose68k | ose | OSE)
		basic_machine=m68k-ericsson
		os=-ose
		;;
	fx2800)
		basic_machine=i860-alliant
		;;
	genix)
		basic_machine=ns32k-ns
		;;
	gmicro)
		basic_machine=tron-gmicro
		os=-sysv
		;;
	go32)
		basic_machine=i386-pc
		os=-go32
		;;
	h3050r* | hiux*)
		basic_machine=hppa1.1-hitachi
		os=-hiuxwe2
		;;
	h8300hms)
		basic_machine=h8300-hitachi
		os=-hms
		;;
	h8300xray)
		basic_machine=h8300-hitachi
		os=-xray
		;;
	h8500hms)
		basic_machine=h8500-hitachi
		os=-hms
		;;
	harris)
		basic_machine=m88k-harris
		os=-sysv3
		;;
	c6x-*)
		cpu=tic6x
	hp300-*)
		basic_machine=m68k-hp
		;;
	hp300bsd)
		basic_machine=m68k-hp
		os=-bsd
		;;
	hp300hpux)
		basic_machine=m68k-hp
		os=-hpux
		;;
	hp3k9[0-9][0-9] | hp9[0-9][0-9])
		basic_machine=hppa1.0-hp
		;;
	hp9k2[0-9][0-9] | hp9k31[0-9])
		basic_machine=m68000-hp
		;;
	hp9k3[2-9][0-9])
		basic_machine=m68k-hp
		;;
	hp9k6[0-9][0-9] | hp6[0-9][0-9])
		basic_machine=hppa1.0-hp
		;;
	hp9k7[0-79][0-9] | hp7[0-79][0-9])
		basic_machine=hppa1.1-hp
		;;
	hp9k78[0-9] | hp78[0-9])
		# FIXME: really hppa2.0-hp
		basic_machine=hppa1.1-hp
		;;
	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
		# FIXME: really hppa2.0-hp
		basic_machine=hppa1.1-hp
		;;
	hp9k8[0-9][13679] | hp8[0-9][13679])
		basic_machine=hppa1.1-hp
		;;
	hp9k8[0-9][0-9] | hp8[0-9][0-9])
		basic_machine=hppa1.0-hp
		;;
	hppa-next)
		os=-nextstep3
		;;
	hppaosf)
		basic_machine=hppa1.1-hp
		os=-osf
		;;
	hppro)
		basic_machine=hppa1.1-hp
		os=-proelf
		;;
	i370-ibm* | ibm*)
		basic_machine=i370-ibm
		;;
# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
	i*86v32)
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
		os=-sysv32
		;;
	i*86v4*)
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
		os=-sysv4
		;;
	i*86v)
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
		os=-sysv
		;;
	i*86sol2)
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
		os=-solaris2
		;;
	i386mach)
		basic_machine=i386-mach
		os=-mach
		;;
	i386-vsta | vsta)
		basic_machine=i386-unknown
		os=-vsta
		;;
	iris | iris4d)
		basic_machine=mips-sgi
		case $os in
		    -irix*)
			;;
	e500v[12]-*)
		cpu=powerpc
		os=$os"spe"
		    *)
			os=-irix4
			;;
		esac
		;;
	isi68 | isi)
		basic_machine=m68k-isi
		os=-sysv
		;;
	m88k-omron*)
		basic_machine=m88k-omron
		;;
	magnum | m3230)
		basic_machine=mips-mips
		os=-sysv
		;;
	merlin)
		basic_machine=ns32k-utek
		os=-sysv
		;;
	mingw32)
		basic_machine=i386-pc
		os=-mingw32
		;;
	mingw32ce)
		basic_machine=arm-unknown
		os=-mingw32ce
		;;
	miniframe)
		basic_machine=m68000-convergent
		;;
	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
		basic_machine=m68k-atari
		os=-mint
		;;
	mipsEE* | ee | ps2)
		basic_machine=mips64r5900el-scei
		case $os in
		    -linux*)
			;;
		    *)
			os=-elf
			;;
		esac
		;;
	iop)
		basic_machine=mipsel-scei
		os=-irx
		;;
	dvp)
		basic_machine=dvp-scei
		os=-elf
		;;
	mips3*-*)
		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
		;;
		cpu=mips64
	mips3*)
		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
		;;
	monitor)
		basic_machine=m68k-rom68k
		os=-coff
		;;
	morphos)
		basic_machine=powerpc-unknown
		os=-morphos
		;;
	msdos)
		basic_machine=i386-pc
		os=-msdos
		;;
	ms1-*)
		cpu=mt
		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
		;;
	m68knommu-*)
		cpu=m68k
		os=linux
	mvs)
		basic_machine=i370-ibm
		os=-mvs
		;;
	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
		cpu=s12z
		;;
	openrisc-*)
		cpu=or32
	ncr3000)
		;;
	parisc-*)
		cpu=hppa
		os=linux
		basic_machine=i486-ncr
		os=-sysv4
		;;
	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
		cpu=i586
		;;
	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
		cpu=i686
		;;
	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
		cpu=i686
	netbsd386)
		;;
	pentium4-*)
		cpu=i786
		;;
	pc98-*)
		cpu=i386
		basic_machine=i386-unknown
		os=-netbsd
		;;
	ppc-* | ppcbe-*)
		cpu=powerpc
	netwinder)
		;;
	ppcle-* | powerpclittle-*)
		basic_machine=armv4l-rebel
		os=-linux
		cpu=powerpcle
		;;
	news | news700 | news800 | news900)
		basic_machine=m68k-sony
	ppc64-*)
		os=-newsos
		cpu=powerpc64
		;;
	ppc64le-* | powerpc64little-*)
		cpu=powerpc64le
		;;
	sb1-*)
		cpu=mipsisa64sb1
	news1000)
		basic_machine=m68030-sony
		os=-newsos
		;;
	sb1el-*)
		cpu=mipsisa64sb1el
	news-3600 | risc-news)
		basic_machine=mips-sony
		os=-newsos
		;;
	sh5e[lb]-*)
	necv70)
		cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
		;;
	spur-*)
		basic_machine=v70-nec
		os=-sysv
		cpu=spur
		;;
	strongarm-* | thumb-*)
		cpu=arm
	next | m*-next )
		basic_machine=m68k-next
		case $os in
		;;
	tx39-*)
		cpu=mipstx39
		;;
	tx39el-*)
		cpu=mipstx39el
		;;
	x64-*)
		    -nextstep* )
			;;
		    -ns2*)
		      os=-nextstep2
			;;
		    *)
		cpu=x86_64
		;;
		      os=-nextstep3
			;;
	xscale-* | xscalee[bl]-*)
		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
		esac
		;;
	nh3000)

		basic_machine=m68k-harris
	# Recognize the canonical CPU Types that limit and/or modify the
	# company names they are paired with.
	cr16-*)
		os=${os:-elf}
		os=-cxux
		;;
	crisv32-* | etraxfs*-*)
		cpu=crisv32
		vendor=axis
	nh[45]000)
		basic_machine=m88k-harris
		os=-cxux
		;;
	cris-* | etrax*-*)
		cpu=cris
		vendor=axis
	nindy960)
		basic_machine=i960-intel
		os=-nindy
		;;
	crx-*)
		os=${os:-elf}
	mon960)
		basic_machine=i960-intel
		os=-mon960
		;;
	nonstopux)
	neo-tandem)
		cpu=neo
		basic_machine=mips-compaq
		os=-nonstopux
		vendor=tandem
		;;
	nse-tandem)
		cpu=nse
	np1)
		basic_machine=np1-gould
		vendor=tandem
		;;
	nsr-tandem)
		cpu=nsr
		vendor=tandem
		basic_machine=nsr-tandem
		;;
	op50n-* | op60c-*)
		basic_machine=hppa1.1-oki
		os=-proelf
		;;
	openrisc | openrisc-*)
		basic_machine=or32-unknown
		;;
	nsv-tandem)
		cpu=nsv
		vendor=tandem
	os400)
		basic_machine=powerpc-ibm
		os=-os400
		;;
	OSE68000 | ose68000)
		basic_machine=m68000-ericsson
		os=-ose
		;;
	os68k)
		basic_machine=m68k-none
		os=-os68k
		;;
	nsx-tandem)
		cpu=nsx
		vendor=tandem
	pa-hitachi)
		basic_machine=hppa1.1-hitachi
		os=-hiuxwe2
		;;
	paragon)
		basic_machine=i860-intel
		os=-osf
		;;
	pbd)
		basic_machine=sparc-tti
		;;
	pbb)
		basic_machine=m68k-tti
		;;
	pc532 | pc532-*)
		basic_machine=ns32k-pc532
		;;
	pc98)
		basic_machine=i386-pc
		;;
	pc98-*)
		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	pentium | p5 | k5 | k6 | nexgen | viac3)
		basic_machine=i586-pc
		;;
	s390-*)
		cpu=s390
		vendor=ibm
	pentiumpro | p6 | 6x86 | athlon | athlon_*)
		basic_machine=i686-pc
		;;
	pentiumii | pentium2 | pentiumiii | pentium3)
		basic_machine=i686-pc
		;;
	pentium4)
		basic_machine=i786-pc
		;;
	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	pentiumpro-* | p6-* | 6x86-* | athlon-*)
		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	s390x-*)
		cpu=s390x
		vendor=ibm
	pentium4-*)
		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	pn)
		basic_machine=pn-gould
		;;
	power)	basic_machine=power-ibm
		;;
	ppc)	basic_machine=powerpc-unknown
		;;
	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	ppcle | powerpclittle | ppc-le | powerpc-little)
		basic_machine=powerpcle-unknown
		;;
	tile*-*)
	ppcle-* | powerpclittle-*)
		os=${os:-linux-gnu}
		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	ppc64)	basic_machine=powerpc64-unknown
		;;
	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
		basic_machine=powerpc64le-unknown
		;;
	ppc64le-* | powerpc64little-*)
		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
		;;
	ps2)

	*)
		basic_machine=i386-ibm
		;;
	pw32)
		basic_machine=i586-unknown
		os=-pw32
		;;
	rdos)
		basic_machine=i386-pc
		os=-rdos
		;;
	rom68k)
		basic_machine=m68k-rom68k
		os=-coff
		;;
	rm[46]00)
		basic_machine=mips-siemens
		;;
	rtpc | rtpc-*)
		# Recognize the canonical CPU types that are allowed with any
		# company name.
		case $cpu in
			1750a | 580 \
			| a29k \
		basic_machine=romp-ibm
		;;
	s390 | s390-*)
		basic_machine=s390-ibm
		;;
	s390x | s390x-*)
		basic_machine=s390x-ibm
		;;
	sa29200)
			| aarch64 | aarch64_be \
			| abacus \
		basic_machine=a29k-amd
			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
			| alphapca5[67] | alpha64pca5[67] \
			| am33_2.0 \
			| amdgcn \
			| arc | arceb \
		os=-udi
		;;
	sb1)
			| arm  | arm[lb]e | arme[lb] | armv* \
			| avr | avr32 \
			| asmjs \
			| ba \
			| be32 | be64 \
			| bfin | bpf | bs2000 \
		basic_machine=mipsisa64sb1-unknown
		;;
	sb1el)
		basic_machine=mipsisa64sb1el-unknown
		;;
	sde)
		basic_machine=mipsisa32-sde
		os=-elf
		;;
	sei)
		basic_machine=mips-sei
		os=-seiux
		;;
	sequent)
		basic_machine=i386-sequent
		;;
	sh)
		basic_machine=sh-hitachi
		os=-hms
		;;
	sh5el)
		basic_machine=sh5le-unknown
		;;
	sh64)
		basic_machine=sh64-unknown
		;;
	sparclite-wrs | simso-wrs)
			| c[123]* | c30 | [cjt]90 | c4x \
			| c8051 | clipper | craynv | csky | cydra \
			| d10v | d30v | dlx | dsp16xx \
		basic_machine=sparclite-wrs
		os=-vxworks
		;;
	sps7)
			| e2k | elxsi | epiphany \
			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
			| h8300 | h8500 \
			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
			| hexagon \
		basic_machine=m68k-bull
		os=-sysv2
			| i370 | i*86 | i860 | i960 | ia16 | ia64 \
			| ip2k | iq2000 \
			| k1om \
			| le32 | le64 \
			| lm32 \
		;;
	spur)
		basic_machine=spur-unknown
		;;
	st2000)
		basic_machine=m68k-tandem
		;;
	stratus)
		basic_machine=i860-stratus
		os=-sysv4
		;;
	sun2)
		basic_machine=m68000-sun
		;;
	sun2os3)
			| m32c | m32r | m32rle \
			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
		basic_machine=m68000-sun
			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
			| m88110 | m88k | maxq | mb | mcore | mep | metag \
			| microblaze | microblazeel \
			| mips | mipsbe | mipseb | mipsel | mipsle \
			| mips16 \
		os=-sunos3
		;;
	sun2os4)
			| mips64 | mips64eb | mips64el \
			| mips64octeon | mips64octeonel \
			| mips64orion | mips64orionel \
			| mips64r5900 | mips64r5900el \
			| mips64vr | mips64vrel \
		basic_machine=m68000-sun
		os=-sunos4
		;;
	sun3os3)
		basic_machine=m68k-sun
		os=-sunos3
		;;
	sun3os4)
		basic_machine=m68k-sun
		os=-sunos4
		;;
	sun4os3)
		basic_machine=sparc-sun
		os=-sunos3
			| mips64vr4100 | mips64vr4100el \
			| mips64vr4300 | mips64vr4300el \
			| mips64vr5000 | mips64vr5000el \
			| mips64vr5900 | mips64vr5900el \
		;;
	sun4os4)
		basic_machine=sparc-sun
		os=-sunos4
			| mipsisa32 | mipsisa32el \
			| mipsisa32r2 | mipsisa32r2el \
			| mipsisa32r6 | mipsisa32r6el \
			| mipsisa64 | mipsisa64el \
			| mipsisa64r2 | mipsisa64r2el \
			| mipsisa64r6 | mipsisa64r6el \
			| mipsisa64sb1 | mipsisa64sb1el \
			| mipsisa64sr71k | mipsisa64sr71kel \
			| mipsr5900 | mipsr5900el \
			| mipstx39 | mipstx39el \
			| mmix \
			| mn10200 | mn10300 \
			| moxie \
			| mt \
			| msp430 \
		;;
	sun4sol2)
		basic_machine=sparc-sun
		os=-solaris2
		;;
	sun3 | sun3-*)
		basic_machine=m68k-sun
		;;
	sun4)
		basic_machine=sparc-sun
		;;
	sun386 | sun386i | roadrunner)
		basic_machine=i386-sun
		;;
	sv1)
		basic_machine=sv1-cray
		os=-unicos
		;;
	symmetry)
		basic_machine=i386-sequent
		os=-dynix
		;;
	t3e)
		basic_machine=alphaev5-cray
		os=-unicos
		;;
	t90)
		basic_machine=t90-cray
		os=-unicos
		;;
	tic54x | c54x*)
		basic_machine=tic54x-unknown
		os=-coff
		;;
	tic55x | c55x*)
		basic_machine=tic55x-unknown
		os=-coff
		;;
	tic6x | c6x*)
		basic_machine=tic6x-unknown
		os=-coff
		;;
	tx39)
		basic_machine=mipstx39-unknown
		;;
	tx39el)
		basic_machine=mipstx39el-unknown
		;;
	toad1)
		basic_machine=pdp10-xkl
		os=-tops20
		;;
	tower | tower-32)
		basic_machine=m68k-ncr
		;;
	tpf)
		basic_machine=s390x-ibm
		os=-tpf
			| nds32 | nds32le | nds32be \
			| nfp \
		;;
	udi29k)
		basic_machine=a29k-amd
		os=-udi
		;;
	ultra3)
		basic_machine=a29k-nyu
		os=-sym1
		;;
	v810 | necv810)
			| nios | nios2 | nios2eb | nios2el \
			| none | np1 | ns16k | ns32k | nvptx \
			| open8 \
			| or1k* \
			| or32 \
			| orion \
		basic_machine=v810-nec
		os=-none
		;;
	vaxv)
		basic_machine=vax-dec
		os=-sysv
		;;
	vms)
		basic_machine=vax-dec
		os=-vms
		;;
	vpp*|vx|vx-*)
		basic_machine=f301-fujitsu
		;;
	vxworks960)
		basic_machine=i960-wrs
		os=-vxworks
		;;
	vxworks68)
			| picochip \
			| pdp10 | pdp11 | pj | pjl | pn | power \
			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
			| pru \
			| pyramid \
			| riscv | riscv32 | riscv64 \
			| rl78 | romp | rs6000 | rx \
			| score \
			| sh | shl \
		basic_machine=m68k-wrs
		os=-vxworks
		;;
	vxworks29k)
		basic_machine=a29k-wrs
		os=-vxworks
		;;
	w65*)
		basic_machine=w65-wdc
		os=-none
		;;
	w89k-*)
		basic_machine=hppa1.1-winbond
		os=-proelf
		;;
	xbox)
		basic_machine=i686-pc
		os=-mingw32
		;;
	xps | xps100)
		basic_machine=xps100-honeywell
		;;
	ymp)
		basic_machine=ymp-cray
		os=-unicos
		;;
	z8k-*-coff)
		basic_machine=z8k-unknown
		os=-sim
			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
			| sparclite \
			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
			| spu \
			| tahoe \
		;;
	none)
		basic_machine=none-none
		os=-none
		;;

# Here we handle the default manufacturer of certain CPU types.  It is in
# some cases the only manufacturer, in others, it is the most popular.
	w89k)
		basic_machine=hppa1.1-winbond
		;;
	op50n)
		basic_machine=hppa1.1-oki
		;;
	op60c)
			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
			| tron \
			| ubicom32 \
		basic_machine=hppa1.1-oki
		;;
	romp)
		basic_machine=romp-ibm
			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
			| vax \
			| visium \
		;;
	mmix)
		basic_machine=mmix-knuth
		;;
	rs6000)
		basic_machine=rs6000-ibm
		;;
	vax)
		basic_machine=vax-dec
			| w65 \
			| wasm32 | wasm64 \
			| we32k \
		;;
	pdp10)
		# there are many clones, so DEC is not a safe bet
		basic_machine=pdp10-unknown
		;;
	pdp11)
		basic_machine=pdp11-dec
		;;
	we32k)
			| x86 | x86_64 | xc16x | xgate | xps100 \
			| xstormy16 | xtensa* \
			| ymp \
			| z8k | z80)
				;;

			*)
				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
				exit 1
		basic_machine=we32k-att
		;;
	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
		basic_machine=sh-unknown
		;;
	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
		basic_machine=sparc-sun
		;;
	cydra)
		basic_machine=cydra-cydrome
		;;
	orion)
		basic_machine=orion-highlevel
		;;
	orion105)
		basic_machine=clipper-highlevel
		;;
	mac | mpw | mac-mpw)
		basic_machine=m68k-apple
		;;
	pmac | pmac-mpw)
		basic_machine=powerpc-apple
		;;
	*-unknown)
		# Make sure to match an already-canonicalized machine name.
		;;
	*)
		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
		exit 1
				;;
		esac
		;;
esac

# Here we canonicalize certain aliases for manufacturers.
case $vendor in
	digital*)
		vendor=dec
case $basic_machine in
	*-digital*)
		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
		;;
	commodore*)
		vendor=cbm
	*-commodore*)
		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
		;;
	*)
		;;
esac

# Decode manufacturer-specific aliases for certain operating systems.

if [ x$os != x ]
if [ x"$os" != x"" ]
then
case $os in
	# First match some system type aliases that might get confused
	# with valid system types.
	# solaris* is a basic system type, with this one exception.
        # First match some system type aliases
        # that might get confused with valid system types.
	# -solaris* is a basic system type, with this one exception.
	auroraux)
		os=auroraux
		;;
	bluegene*)
		os=cnk
		;;
	solaris1 | solaris1.*)
	-solaris1 | -solaris1.*)
		os=`echo $os | sed -e 's|solaris1|sunos4|'`
		;;
	solaris)
		os=solaris2
	-solaris)
		os=-solaris2
		;;
	unixware*)
		os=sysv4.2uw
	-svr4*)
		;;
	gnu/linux*)
		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
		;;
	# es1800 is here to avoid being matched by es* (a different OS)
	es1800*)
		os=ose
		;;
	# Some version numbers need modification
	chorusos*)
		os=chorusos
		os=-sysv4
		;;
	isc)
		os=isc2.2
	-unixware*)
		os=-sysv4.2uw
		;;
	sco6)
		os=sco5v6
		;;
	sco5)
		os=sco3.2v5
		;;
	sco4)
		os=sco3.2v4
		;;
	sco3.2.[4-9]*)
		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
	-gnu/linux*)
		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
		;;
	sco3.2v[4-9]* | sco5v6*)
		# Don't forget version if it is 3.2v4 or newer.
		;;
	scout)
		# Don't match below
		;;
	sco*)
		os=sco3.2v2
		;;
	psos*)
		os=psos
		;;
	# Now accept the basic system types.
	# First accept the basic system types.
	# The portable systems comes first.
	# Each alternative MUST end in a * to match a version number.
	# sysv* is not here because it comes later, after sysvr4.
	gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
	# Each alternative MUST END IN A *, to match a version number.
	# -sysv* is not here because it comes later, after sysvr4.
	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
	     | sym* | kopensolaris* | plan9* \
	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
	     | aos* | aros* | cloudabi* | sortix* \
	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
	     | knetbsd* | mirbsd* | netbsd* \
	     | bitrig* | openbsd* | solidbsd* | libertybsd* \
	     | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
	     | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
	     | chorusrdb* | cegcc* | glidix* \
	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
	      | -aos* \
	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
	      | -openbsd* | -solidbsd* \
	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
	      | -chorusos* | -chorusrdb* \
	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
	     | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
	     | linux-newlib* | linux-musl* | linux-uclibc* \
	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \
	     | interix* | uwin* | mks* | rhapsody* | darwin* \
	     | openstep* | oskit* | conix* | pw32* | nonstopux* \
	     | storm-chaos* | tops10* | tenex* | tops20* | its* \
	     | os2* | vos* | palmos* | uclinux* | nucleus* \
	     | morphos* | superux* | rtmk* | windiss* \
	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \
	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
	      | -uxpv* | -beos* | -mpeix* | -udk* \
	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -irx*)
	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
	     | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi*)
	# Remember, each alternative MUST END IN *, to match a version number.
		;;
	qnx*)
		case $cpu in
		    x86 | i*86)
	-qnx*)
		case $basic_machine in
		    x86-* | i*86-*)
			;;
		    *)
			os=nto-$os
			os=-nto$os
			;;
		esac
		;;
	hiux*)
		os=hiuxwe2
		;;
	nto-qnx*)
	-nto-qnx*)
		;;
	nto*)
	-nto*)
		os=`echo $os | sed -e 's|nto|nto-qnx|'`
		;;
	sim | xray | os68k* | v88r* \
	    | windows* | osx | abug | netware* | os9* \
	    | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
		;;
	-mac*)
		os=`echo $os | sed -e 's|mac|macos|'`
		;;
	linux-dietlibc)
		os=linux-dietlibc
	-linux-dietlibc)
		os=-linux-dietlibc
		;;
	linux*)
	-linux*)
		os=`echo $os | sed -e 's|linux|linux-gnu|'`
		;;
	-sunos5*)
		os=`echo $os | sed -e 's|sunos5|solaris2|'`
		;;
	-sunos6*)
		os=`echo $os | sed -e 's|sunos6|solaris3|'`
		;;
	-opened*)
		os=-openedition
		;;
        -os400*)
		os=-os400
		;;
	-wince*)
	lynx*178)
		os=lynxos178
		;;
	lynx*5)
		os=lynxos5
		os=-wince
		;;
	lynx*)
		os=lynxos
		;;
	mac*)
	-osfrose*)
		os=`echo "$os" | sed -e 's|mac|macos|'`
		;;
	opened*)
		os=openedition
		;;
	os400*)
		os=os400
		os=-osfrose
		;;
	sunos5*)
		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
		;;
	sunos6*)
		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
		;;
	wince*)
		os=wince
	-osf*)
		os=-osf
		;;
	utek*)
		os=bsd
	-utek*)
		os=-bsd
		;;
	dynix*)
		os=bsd
	-dynix*)
		os=-bsd
		;;
	acis*)
		os=aos
	-acis*)
		os=-aos
		;;
	atheos*)
		os=atheos
	-atheos*)
		os=-atheos
		;;
	syllable*)
		os=syllable
	-syllable*)
		os=-syllable
		;;
	386bsd)
		os=bsd
	-386bsd)
		os=-bsd
		;;
	ctix* | uts*)
		os=sysv
	-ctix* | -uts*)
		os=-sysv
		;;
	nova*)
		os=rtmk-nova
	-nova*)
		os=-rtmk-nova
		;;
	ns2)
		os=nextstep2
	-ns2 )
		os=-nextstep2
		;;
	nsk*)
		os=nsk
	-nsk*)
		os=-nsk
		;;
	# Preserve the version number of sinix5.
	sinix5.*)
	-sinix5.*)
		os=`echo $os | sed -e 's|sinix|sysv|'`
		;;
	-sinix*)
		os=-sysv4
		;;
        -tpf*)
		os=-tpf
		;;
	sinix*)
		os=sysv4
		;;
	tpf*)
		os=tpf
		;;
	triton*)
		os=sysv3
	-triton*)
		os=-sysv3
		;;
	oss*)
		os=sysv3
	-oss*)
		os=-sysv3
		;;
	svr4*)
		os=sysv4
	-svr4)
		os=-sysv4
		;;
	svr3)
		os=sysv3
	-svr3)
		os=-sysv3
		;;
	sysvr4)
		os=sysv4
	-sysvr4)
		os=-sysv4
		;;
	# This must come after sysvr4.
	sysv*)
	# This must come after -sysvr4.
	-sysv*)
		;;
	ose*)
		os=ose
	-ose*)
		os=-ose
		;;
	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
		os=mint
	-es1800*)
		os=-ose
		;;
	zvmoe)
		os=zvmoe
	-xenix)
		os=-xenix
		;;
	dicos*)
		os=dicos
	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
		os=-mint
		;;
	pikeos*)
	-aros*)
		# Until real need of OS specific support for
		# particular features comes up, bare metal
		# configurations are quite functional.
		case $cpu in
		    arm*)
			os=eabi
			;;
		    *)
			os=elf
			;;
		esac
		os=-aros
		;;
	-kaos*)
		os=-kaos
		;;
	-zvmoe)
		;;
	nacl*)
		;;
	ios)
		os=-zvmoe
		;;
	none)
	-none)
		;;
	*-eabi)
		;;
	*)
		# Get rid of the `-' at the beginning of $os.
		os=`echo $os | sed 's/[^-]*-//'`
		echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
		exit 1
		;;
esac
else

# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.

# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system.  Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.

case $cpu-$vendor in
	score-*)
		os=elf
case $basic_machine in
        score-*)
		os=-elf
		;;
	spu-*)
		os=elf
        spu-*)
		os=-elf
		;;
	*-acorn)
		os=riscix1.2
		os=-riscix1.2
		;;
	arm*-rebel)
		os=linux
		os=-linux
		;;
	arm*-semi)
		os=aout
		os=-aout
		;;
	c4x-* | tic4x-*)
		os=coff
        c4x-* | tic4x-*)
        	os=-coff
		;;
	c8051-*)
		os=elf
		;;
	clipper-intergraph)
		os=clix
		;;
	hexagon-*)
		os=elf
		;;
	tic54x-*)
		os=coff
		;;
	tic55x-*)
		os=coff
		;;
	tic6x-*)
		os=coff
		;;
	# This must come before the *-dec entry.
	pdp10-*)
		os=tops20
		os=-tops20
		;;
	pdp11-*)
		os=none
		os=-none
		;;
	*-dec | vax-*)
		os=ultrix4.2
		os=-ultrix4.2
		;;
	m68*-apollo)
		os=domain
		os=-domain
		;;
	i386-sun)
		os=sunos4.0.2
		os=-sunos4.0.2
		;;
	m68000-sun)
		os=sunos3
		os=-sunos3
		# This also exists in the configure program, but was not the
		# default.
		# os=-sunos4
		;;
	m68*-cisco)
		os=aout
		os=-aout
		;;
	mep-*)
		os=elf
        mep-*)
		os=-elf
		;;
	mips*-cisco)
		os=elf
		os=-elf
		;;
	mips*-*)
		os=elf
		os=-elf
		;;
	or32-*)
		os=coff
		os=-coff
		;;
	*-tti)	# must be before sparc entry or we get the wrong os.
		os=sysv3
		os=-sysv3
		;;
	sparc-* | *-sun)
		os=sunos4.1.1
		os=-sunos4.1.1
		;;
	pru-*)
		os=elf
		;;
	*-be)
		os=beos
		os=-beos
		;;
	*-haiku)
		os=-haiku
		;;
	*-ibm)
		os=aix
		os=-aix
		;;
	*-knuth)
		os=mmixware
    	*-knuth)
		os=-mmixware
		;;
	*-wec)
		os=proelf
		os=-proelf
		;;
	*-winbond)
		os=proelf
		os=-proelf
		;;
	*-oki)
		os=proelf
		os=-proelf
		;;
	*-hp)
		os=hpux
		os=-hpux
		;;
	*-hitachi)
		os=hiux
		os=-hiux
		;;
	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
		os=sysv
		os=-sysv
		;;
	*-cbm)
		os=amigaos
		os=-amigaos
		;;
	*-dg)
		os=dgux
		os=-dgux
		;;
	*-dolphin)
		os=sysv3
		os=-sysv3
		;;
	m68k-ccur)
		os=rtu
		os=-rtu
		;;
	m88k-omron*)
		os=luna
		os=-luna
		;;
	*-next)
		os=nextstep
	*-next )
		os=-nextstep
		;;
	*-sequent)
		os=ptx
		os=-ptx
		;;
	*-crds)
		os=unos
		os=-unos
		;;
	*-ns)
		os=genix
		os=-genix
		;;
	i370-*)
		os=mvs
		os=-mvs
		;;
	*-next)
		os=-nextstep3
		;;
	*-gould)
		os=sysv
		os=-sysv
		;;
	*-highlevel)
		os=bsd
		os=-bsd
		;;
	*-encore)
		os=bsd
		os=-bsd
		;;
	*-sgi)
		os=irix
		os=-irix
		;;
	*-siemens)
		os=sysv4
		os=-sysv4
		;;
	*-masscomp)
		os=rtu
		os=-rtu
		;;
	f30[01]-fujitsu | f700-fujitsu)
		os=uxpv
		os=-uxpv
		;;
	*-rom68k)
		os=coff
		os=-coff
		;;
	*-*bug)
		os=coff
		os=-coff
		;;
	*-apple)
		os=macos
		os=-macos
		;;
	*-atari*)
		os=mint
		os=-mint
		;;
	*-wrs)
		os=vxworks
		;;
	*)
		os=none
		os=-none
		;;
esac
fi

# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer.  We pick the logical manufacturer.
case $vendor in
	unknown)
vendor=unknown
case $basic_machine in
	*-unknown)
		case $os in
			riscix*)
			-riscix*)
				vendor=acorn
				;;
			sunos*)
			-sunos*)
				vendor=sun
				;;
			cnk*|-aix*)
			-aix*)
				vendor=ibm
				;;
			beos*)
			-beos*)
				vendor=be
				;;
			hpux*)
			-hpux*)
				vendor=hp
				;;
			mpeix*)
			-mpeix*)
				vendor=hp
				;;
			hiux*)
			-hiux*)
				vendor=hitachi
				;;
			unos*)
			-unos*)
				vendor=crds
				;;
			dgux*)
			-dgux*)
				vendor=dg
				;;
			luna*)
			-luna*)
				vendor=omron
				;;
			genix*)
			-genix*)
				vendor=ns
				;;
			clix*)
				vendor=intergraph
				;;
			mvs* | opened*)
			-mvs* | -opened*)
				vendor=ibm
				;;
			os400*)
			-os400*)
				vendor=ibm
				;;
			ptx*)
			-ptx*)
				vendor=sequent
				;;
			tpf*)
			-tpf*)
				vendor=ibm
				;;
			vxsim* | vxworks* | windiss*)
			-vxsim* | -vxworks* | -windiss*)
				vendor=wrs
				;;
			aux*)
			-aux*)
				vendor=apple
				;;
			hms*)
			-hms*)
				vendor=hitachi
				;;
			mpw* | macos*)
			-mpw* | -macos*)
				vendor=apple
				;;
			*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
				vendor=atari
				;;
			vos*)
			-vos*)
				vendor=stratus
				;;
		esac
		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
		;;
esac

echo "$cpu-$vendor-$os"
echo $basic_machine$os
exit

# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:

Changes to configure.

1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.35.5.
# Generated by GNU Autoconf 2.69 for sqlite 3.28.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
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.5'
PACKAGE_STRING='sqlite 3.35.5'
PACKAGE_VERSION='3.28.0'
PACKAGE_STRING='sqlite 3.28.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
795
796
797
798
799
800
801

802
803
804
805
806
807
808
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809







+







SQLITE_OS_WIN
SQLITE_OS_UNIX
BUILD_EXEEXT
TEMP_STORE
ALLOWRELEASE
SQLITE_THREADSAFE
BUILD_CC
VERSION_NUMBER
RELEASE
VERSION
program_prefix
TCLLIBDIR
TCLSH_CMD
INSTALL_DATA
INSTALL_SCRIPT
858
859
860
861
862
863
864

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







+







pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
901
902
903
904
905
906
907


908
909
910
911
912
913
914







-
-







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
961
962
963
964
965
966
967

968
969
970
971
972
973
974
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975







+







sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
pdfdir='${docdir}'
1212
1213
1214
1215
1216
1217
1218









1219
1220
1221
1222
1223
1224
1225
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235







+
+
+
+
+
+
+
+
+







    ac_prev=psdir ;;
  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
    psdir=$ac_optarg ;;

  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;

  -runstatedir | --runstatedir | --runstatedi | --runstated \
  | --runstate | --runstat | --runsta | --runst | --runs \
  | --run | --ru | --r)
    ac_prev=runstatedir ;;
  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
  | --run=* | --ru=* | --r=*)
    runstatedir=$ac_optarg ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir=$ac_optarg ;;

1350
1351
1352
1353
1354
1355
1356
1357

1358
1359
1360
1361
1362
1363
1364
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1374







-
+







  esac
fi

# Check all directory arguments for consistency.
for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
		datadir sysconfdir sharedstatedir localstatedir includedir \
		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
		libdir localedir mandir
		libdir localedir mandir runstatedir
do
  eval ac_val=\$$ac_var
  # Remove trailing slashes.
  case $ac_val in
    */ )
      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
      eval $ac_var=\$ac_val;;
1463
1464
1465
1466
1467
1468
1469
1470

1471
1472
1473
1474
1475
1476
1477
1473
1474
1475
1476
1477
1478
1479

1480
1481
1482
1483
1484
1485
1486
1487







-
+







#
# 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.5 to adapt to many kinds of systems.
\`configure' configures sqlite 3.28.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.
1503
1504
1505
1506
1507
1508
1509

1510
1511
1512
1513
1514
1515
1516
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527







+







Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
1528
1529
1530
1531
1532
1533
1534
1535

1536
1537
1538
1539
1540
1541
1542
1539
1540
1541
1542
1543
1544
1545

1546
1547
1548
1549
1550
1551
1552
1553







-
+







  --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.5:";;
     short | recursive ) echo "Configuration of sqlite 3.28.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]
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1565
1566
1567
1568
1569
1570
1571


1572
1573
1574
1575
1576
1577
1578







-
-







  --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
1656
1657
1658
1659
1660
1661
1662
1663

1664
1665
1666
1667
1668
1669
1670
1665
1666
1667
1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
1679







-
+







    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.5
sqlite configure 3.28.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
2075
2076
2077
2078
2079
2080
2081
2082

2083
2084
2085
2086
2087
2088
2089
2084
2085
2086
2087
2088
2089
2090

2091
2092
2093
2094
2095
2096
2097
2098







-
+







  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.5, which was
It was created by sqlite $as_me 3.28.0, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
3933
3934
3935
3936
3937
3938
3939
3940

3941
3942
3943

3944
3945
3946

3947
3948
3949
3950
3951
3952
3953
3942
3943
3944
3945
3946
3947
3948

3949
3950
3951

3952
3953
3954

3955
3956
3957
3958
3959
3960
3961
3962







-
+


-
+


-
+







{ $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 echo "\"\$as_me:3949: $ac_compile\"" >&5)
  (eval "$ac_compile" 2>conftest.err)
  cat conftest.err >&5
  (eval echo "\"\$as_me:3943: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
  (eval echo "\"\$as_me:3952: $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)
  (eval echo "\"\$as_me:3955: 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
5145
5146
5147
5148
5149
5150
5151
5152

5153
5154
5155
5156
5157
5158
5159
5154
5155
5156
5157
5158
5159
5160

5161
5162
5163
5164
5165
5166
5167
5168







-
+







	;;
    esac
  fi
  rm -rf conftest*
  ;;
*-*-irix6*)
  # Find out which ABI we are using.
  echo '#line 5152 "configure"' > conftest.$ac_ext
  echo '#line 5161 "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
6670
6671
6672
6673
6674
6675
6676
6677

6678
6679
6680
6681

6682
6683
6684
6685
6686
6687
6688
6679
6680
6681
6682
6683
6684
6685

6686
6687
6688
6689

6690
6691
6692
6693
6694
6695
6696
6697







-
+



-
+







   # 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 echo "\"\$as_me:6686: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>conftest.err)
   ac_status=$?
   cat conftest.err >&5
   echo "$as_me:6681: \$? = $ac_status" >&5
   echo "$as_me:6690: \$? = $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
7009
7010
7011
7012
7013
7014
7015
7016

7017
7018
7019
7020

7021
7022
7023
7024
7025
7026
7027
7018
7019
7020
7021
7022
7023
7024

7025
7026
7027
7028

7029
7030
7031
7032
7033
7034
7035
7036







-
+



-
+







   # 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 echo "\"\$as_me:7025: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>conftest.err)
   ac_status=$?
   cat conftest.err >&5
   echo "$as_me:7020: \$? = $ac_status" >&5
   echo "$as_me:7029: \$? = $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
7114
7115
7116
7117
7118
7119
7120
7121

7122
7123
7124
7125

7126
7127
7128
7129
7130
7131
7132
7123
7124
7125
7126
7127
7128
7129

7130
7131
7132
7133

7134
7135
7136
7137
7138
7139
7140
7141







-
+



-
+







   # (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 echo "\"\$as_me:7130: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>out/conftest.err)
   ac_status=$?
   cat out/conftest.err >&5
   echo "$as_me:7125: \$? = $ac_status" >&5
   echo "$as_me:7134: \$? = $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
7178
7179
7180
7181
7182
7183
7184

7185
7186
7187
7188

7189
7190
7191
7192
7193
7194
7195
7196







-
+



-
+







   # (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 echo "\"\$as_me:7185: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>out/conftest.err)
   ac_status=$?
   cat out/conftest.err >&5
   echo "$as_me:7180: \$? = $ac_status" >&5
   echo "$as_me:7189: \$? = $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
9549
9550
9551
9552
9553
9554
9555
9556

9557
9558
9559
9560
9561
9562
9563
9558
9559
9560
9561
9562
9563
9564

9565
9566
9567
9568
9569
9570
9571
9572







-
+







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"
#line 9565 "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
9654
9655
9656
9657
9658
9659
9660

9661
9662
9663
9664
9665
9666
9667
9668







-
+







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"
#line 9661 "configure"
#include "confdefs.h"

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

#include <stdio.h>
9994
9995
9996
9997
9998
9999
10000
10001

10002
10003
10004
10005
10006
10007
10008
10003
10004
10005
10006
10007
10008
10009

10010
10011
10012
10013
10014
10015
10016
10017







-
+







	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
 /* Check that off_t can represent 2**63 - 1 correctly.
    We can't simply define LARGE_OFF_T to be 9223372036854775807,
    since some C++ compilers masquerading as C compilers
    incorrectly reject 9223372036854775807.  */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
		       && LARGE_OFF_T % 2147483647 == 1)
		      ? 1 : -1];
int
main ()
{

10040
10041
10042
10043
10044
10045
10046
10047

10048
10049
10050
10051
10052
10053
10054
10049
10050
10051
10052
10053
10054
10055

10056
10057
10058
10059
10060
10061
10062
10063







-
+







  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
 /* Check that off_t can represent 2**63 - 1 correctly.
    We can't simply define LARGE_OFF_T to be 9223372036854775807,
    since some C++ compilers masquerading as C compilers
    incorrectly reject 9223372036854775807.  */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
		       && LARGE_OFF_T % 2147483647 == 1)
		      ? 1 : -1];
int
main ()
{

10064
10065
10066
10067
10068
10069
10070
10071

10072
10073
10074
10075
10076
10077
10078
10073
10074
10075
10076
10077
10078
10079

10080
10081
10082
10083
10084
10085
10086
10087







-
+







/* end confdefs.h.  */
#define _FILE_OFFSET_BITS 64
#include <sys/types.h>
 /* Check that off_t can represent 2**63 - 1 correctly.
    We can't simply define LARGE_OFF_T to be 9223372036854775807,
    since some C++ compilers masquerading as C compilers
    incorrectly reject 9223372036854775807.  */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
		       && LARGE_OFF_T % 2147483647 == 1)
		      ? 1 : -1];
int
main ()
{

10109
10110
10111
10112
10113
10114
10115
10116

10117
10118
10119
10120
10121
10122
10123
10118
10119
10120
10121
10122
10123
10124

10125
10126
10127
10128
10129
10130
10131
10132







-
+







  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
 /* Check that off_t can represent 2**63 - 1 correctly.
    We can't simply define LARGE_OFF_T to be 9223372036854775807,
    since some C++ compilers masquerading as C compilers
    incorrectly reject 9223372036854775807.  */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
		       && LARGE_OFF_T % 2147483647 == 1)
		      ? 1 : -1];
int
main ()
{

10133
10134
10135
10136
10137
10138
10139
10140

10141
10142
10143
10144
10145
10146
10147
10142
10143
10144
10145
10146
10147
10148

10149
10150
10151
10152
10153
10154
10155
10156







-
+







/* end confdefs.h.  */
#define _LARGE_FILES 1
#include <sys/types.h>
 /* Check that off_t can represent 2**63 - 1 correctly.
    We can't simply define LARGE_OFF_T to be 9223372036854775807,
    since some C++ compilers masquerading as C compilers
    incorrectly reject 9223372036854775807.  */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
		       && LARGE_OFF_T % 2147483647 == 1)
		      ? 1 : -1];
int
main ()
{

10362
10363
10364
10365
10366
10367
10368
10369
10370
10371


10372
10373
10374
10375
10376
10377
10378
10379
10371
10372
10373
10374
10375
10376
10377



10378
10379

10380
10381
10382
10383
10384
10385
10386







-
-
-
+
+
-







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
    TCLLIBDIR=$i
    break
    fi
  done
  TCLLIBDIR="${TCLLIBDIR}/sqlite3"
fi


#########
# Set up an appropriate program prefix
10387
10388
10389
10390
10391
10392
10393






10394
10395
10396
10397
10398
10399
10400
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413







+
+
+
+
+
+







{ $as_echo "$as_me:${as_lineno-$LINENO}: Version set to $VERSION" >&5
$as_echo "$as_me: Version set to $VERSION" >&6;}

RELEASE=`cat $srcdir/VERSION`
{ $as_echo "$as_me:${as_lineno-$LINENO}: Release set to $RELEASE" >&5
$as_echo "$as_me: Release set to $RELEASE" >&6;}

VERSION_NUMBER=`cat $srcdir/VERSION \
                           | sed 's/[^0-9]/ /g' \
                | awk '{printf "%d%03d%03d",$1,$2,$3}'`
{ $as_echo "$as_me:${as_lineno-$LINENO}: Version number set to $VERSION_NUMBER" >&5
$as_echo "$as_me: Version number set to $VERSION_NUMBER" >&6;}


#########
# Locate a compiler for the build machine.  This compiler should
# generate command-line programs that run on the build machine.
#
if test x"$cross_compiling" = xno; then
	BUILD_CC=$CC
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
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







-
-


-
-


-
-










-
+







#########
# 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 :
  enableval=$enable_amalgamation;
fi

if test "${enable_amalgamation}" = "no" ; then
if test "${enable_amalgamation}" == "no" ; then
  USE_AMALGAMATION=0
fi


#########
# Look for zlib.  Only needed by extensions and by the sqlite3.exe shell
for ac_header in zlib.h
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
11423
11424
11425
11426
11427
11428
11429





















































































11430
11431
11432
11433
11434
11435
11436







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







  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;
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
11465
11466
11467
11468
11469
11470
11471


11472
11473





11474
11475
11476
11477
11478
11479



11480


11481
11482
11483
11484
11485
11486
11487







-
-


-
-
-
-
-






-
-
-
+
-
-







#########
# 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
if test "${enable_fts4}" = "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
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
11531
11532
11533
11534
11535
11536
11537



11538
11539
11540
11541
11542
11543



11544


11545
11546
11547
11548
11549
11550
11551







-
-
-






-
-
-
+
-
-







$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
if test "${enable_fts5}" = "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
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
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







-
-
-









-
-
-
+

-
-
-
-
-










-
-
-
+

-
-
-
-
-











-
-
-
+


-
-
-
-
-









-
-


-
-
-
-
-









-
-
-
+


-
-
-
-
-







$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
if test "${enable_json1}" = "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
if test "${enable_udlimit}" = "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
if test "${enable_geopoly}" = "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
if test "${enable_session}" = "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
12374
12375
12376
12377
12378
12379
12380
12381

12382
12383
12384
12385
12386
12387
12388
12240
12241
12242
12243
12244
12245
12246

12247
12248
12249
12250
12251
12252
12253
12254







-
+







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.5, which was
This file was extended by sqlite $as_me 3.28.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 $@
12440
12441
12442
12443
12444
12445
12446
12447

12448
12449
12450
12451
12452
12453
12454
12306
12307
12308
12309
12310
12311
12312

12313
12314
12315
12316
12317
12318
12319
12320







-
+








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.5
sqlite config.status 3.28.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159





160
161
162
163
164
165
166
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







-
-
-
+
+
-



















+
+
+
+
+







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
    TCLLIBDIR=$i
    break
    fi
  done
  TCLLIBDIR="${TCLLIBDIR}/sqlite3"
fi


#########
# Set up an appropriate program prefix
#
if test "$program_prefix" = "NONE"; then
  program_prefix=""
fi
AC_SUBST(program_prefix)

VERSION=[`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'`]
AC_MSG_NOTICE(Version set to $VERSION)
AC_SUBST(VERSION)
RELEASE=`cat $srcdir/VERSION`
AC_MSG_NOTICE(Release set to $RELEASE)
AC_SUBST(RELEASE)
VERSION_NUMBER=[`cat $srcdir/VERSION \
                           | sed 's/[^0-9]/ /g' \
                | awk '{printf "%d%03d%03d",$1,$2,$3}'`]
AC_MSG_NOTICE(Version number set to $VERSION_NUMBER)
AC_SUBST(VERSION_NUMBER)

#########
# Locate a compiler for the build machine.  This compiler should
# generate command-line programs that run on the build machine.
#
if test x"$cross_compiling" = xno; then
	BUILD_CC=$CC
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
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







-


-


-







-
+







# 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]))
if test "${enable_amalgamation}" = "no" ; then
if test "${enable_amalgamation}" == "no" ; then
  USE_AMALGAMATION=0
fi
AC_SUBST(USE_AMALGAMATION)

#########
# Look for zlib.  Only needed by extensions and by the sqlite3.exe shell
AC_CHECK_HEADERS(zlib.h)
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
587
588
589
590
591
592
593





















594
595
596
597
598
599
600







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







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







-


-
-
-



-
-
+
-


-
-



-
-
+
-


-
-





-
-
+

-
-
-







-
-
+

-
-
-







-
-
+


-
-
-






-


-
-
-






-
-
+


-
-
-







  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
if test "${enable_fts4}" = "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
if test "${enable_fts5}" = "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
if test "${enable_json1}" = "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
if test "${enable_udlimit}" = "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
if test "${enable_geopoly}" = "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
if test "${enable_session}" = "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.

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




-
+
-




















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



-
+















-
-
+

-
+


-
+




-
-
+
+
-
-
-
+
+


-
+

-
-
+
+
-



-
+






-
+



-
+






-
-
+



-
+



-
+











-
-
+
+
-

-
-
-
















-
+






-
-
+









-
+



-
+









-
+



-
+






-
+



-
+







<html>
<head>
<title>The Lemon Parser Generator</title>
</head>
<body>
<body bgcolor='white'>
<a id="main"></a>
<h1 align='center'>The Lemon Parser Generator</h1>

<p>Lemon is an LALR(1) parser generator for C.
It does the same job as "bison" and "yacc".
But Lemon is not a bison or yacc clone.  Lemon
uses a different grammar syntax which is designed to
reduce the number of coding errors.  Lemon also uses a
parsing engine that is faster than yacc and
bison and which is both reentrant and threadsafe.
(Update: Since the previous sentence was written, bison
has also been updated so that it too can generate a
reentrant and threadsafe parser.)
Lemon also implements features that can be used
to eliminate resource leaks, making it suitable for use
in long-running programs such as graphical user interfaces
or embedded controllers.</p>

<p>This document is an introduction to the Lemon
parser generator.</p>

<a id="toc"></a>
<h2>1.0 Table of Contents</h2>
<ul>
<li><a href="#main">Introduction</a>
<li><a href="#toc">1.0 Table of Contents</a>
<li><a href="#secnot">2.0 Security Notes</a><br>
<li><a href="#optheory">3.0 Theory of Operation</a>
    <ul>
    <li><a href="#options">3.1 Command Line Options</a>
    <li><a href="#interface">3.2 The Parser Interface</a>
        <ul>
        <li><a href="#onstack">3.2.1 Allocating The Parse Object On Stack</a>
        <li><a href="#ifsum">3.2.2 Interface Summary</a>
        </ul>
    <li><a href="#yaccdiff">3.3 Differences With YACC and BISON</a>
    <li><a href="#build">3.4 Building The "lemon" Or "lemon.exe" Executable</a>
    </ul>
<li><a href="#syntax">4.0 Input File Syntax</a>
    <ul>
    <li><a href="#tnt">4.1 Terminals and Nonterminals</a>
    <li><a href="#rules">4.2 Grammar Rules</a>
    <li><a href="#precrules">4.3 Precedence Rules</a>
    <li><a href="#special">4.4 Special Directives</a>
    </ul>
<li><a href="#errors">5.0 Error Processing</a>
<li><a href="#history">6.0 History of Lemon</a>
<li><a href="#copyright">7.0 Copyright</a>
</ul>

<a id="secnot"></a>
<h2>2.0 Security Note</h2>
<h2>Security Note</h2>

<p>The language parser code created by Lemon is very robust and
is well-suited for use in internet-facing applications that need to
safely process maliciously crafted inputs.</p>
safely process maliciously crafted inputs.

<p>The "lemon.exe" command-line tool itself works great when given a valid
input grammar file and almost always gives helpful
error messages for malformed inputs.  However,  it is possible for
a malicious user to craft a grammar file that will cause 
lemon.exe to crash.
We do not see this as a problem, as lemon.exe is not intended to be used
with hostile inputs.
To summarize:</p>

<ul>
<li>Parser code generated by lemon &rarr; Robust and secure
<li>The "lemon.exe" command line tool itself &rarr; Not so much
</ul>

<a id="optheory"></a>
<h2>3.0 Theory of Operation</h2>
<h2>Theory of Operation</h2>

<p>Lemon is computer program that translates a context free grammar (CFG)
<p>The main goal of Lemon is to translate a context free grammar (CFG)
for a particular language into C code that implements a parser for
that language.
The Lemon program has two inputs:</p>
The program has two inputs:
<ul>
<li>The grammar specification.
<li>A parser template file.
</ul>
<p>Typically, only the grammar specification is supplied by the programmer.
Lemon comes with a default parser template
Typically, only the grammar specification is supplied by the programmer.
Lemon comes with a default parser template which works fine for most
("<a href="https://sqlite.org/src/file/tool/lempar.c">lempar.c</a>")
that works fine for most applications.  But the user is free to substitute
a different parser template if desired.</p>
applications.  But the user is free to substitute a different parser
template if desired.</p>

<p>Depending on command-line options, Lemon will generate up to
three output files.</p>
three output files.
<ul>
<li>C code to implement a parser for the input grammar.
<li>A header file defining an integer ID for each terminal symbol
<li>C code to implement the parser.
<li>A header file defining an integer ID for each terminal symbol.
    (or "token").
<li>An information file that describes the states of the generated parser
    automaton.
</ul>
<p>By default, all three of these output files are generated.
By default, all three of these output files are generated.
The header file is suppressed if the "-m" command-line option is
used and the report file is omitted when "-q" is selected.</p>

<p>The grammar specification file uses a ".y" suffix, by convention.
In the examples used in this document, we'll assume the name of the
grammar file is "gram.y".  A typical use of Lemon would be the
following command:</p>
following command:
<pre>
   lemon gram.y
</pre>
<p>This command will generate three output files named "gram.c",
This command will generate three output files named "gram.c",
"gram.h" and "gram.out".
The first is C code to implement the parser.  The second
is the header file that defines numerical values for all
terminal symbols, and the last is the report that explains
the states used by the parser automaton.</p>

<a id="options"></a>
<h3>3.1 Command Line Options</h3>
<h3>Command Line Options</h3>

<p>The behavior of Lemon can be modified using command-line options.
You can obtain a list of the available command-line options together
with a brief explanation of what each does by typing</p>
with a brief explanation of what each does by typing
<pre>
   lemon "-?"
</pre>
<p>As of this writing, the following command-line options are supported:</p>
As of this writing, the following command-line options are supported:
<ul>
<li><b>-b</b>
Show only the basis for each parser state in the report file.
<li><b>-c</b>
Do not compress the generated action tables.  The parser will be a
little larger and slower, but it will detect syntax errors sooner.
<li><b>-d</b><i>directory</i>
Write all output files into <i>directory</i>.  Normally, output files
are written into the directory that contains the input grammar file.
<li><b>-D<i>name</i></b>
Define C preprocessor macro <i>name</i>.  This macro is usable by
"<tt><a href='#pifdef'>%ifdef</a></tt>",
"<tt><a href='#pifdef'>%ifndef</a></tt>", and
"<tt><a href='#pifdef'>%ifdef</a></tt>" and
"<tt><a href='#pifdef'>%ifndef</a></tt>" lines
"<tt><a href="#pifdef">%if</a></tt> lines
in the grammar file.
<li><b>-E</b>
Run the "%if" preprocessor step only and print the revised grammar
file.
<li><b>-g</b>
Do not generate a parser.  Instead write the input grammar to standard
output with all comments, actions, and other extraneous text removed.
<li><b>-l</b>
Omit "#line" directives in the generated parser C code.
<li><b>-m</b>
Cause the output C source code to be compatible with the "makeheaders"
program.
<li><b>-p</b>
Display all conflicts that are resolved by
<a href='#precrules'>precedence rules</a>.
<li><b>-q</b>
Suppress generation of the report file.
<li><b>-r</b>
Do not sort or renumber the parser states as part of optimization.
<li><b>-s</b>
Show parser statistics before exiting.
Show parser statistics before existing.
<li><b>-T<i>file</i></b>
Use <i>file</i> as the template for the generated C-code parser implementation.
<li><b>-x</b>
Print the Lemon version number.
</ul>

<a id="interface"></a>
<h3>3.2 The Parser Interface</h3>
<h3>The Parser Interface</h3>

<p>Lemon doesn't generate a complete, working program.  It only generates
a few subroutines that implement a parser.  This section describes
the interface to those subroutines.  It is up to the programmer to
call these subroutines in an appropriate way in order to produce a
complete system.</p>

<p>Before a program begins using a Lemon-generated parser, the program
must first create the parser.
A new parser is created as follows:</p>
A new parser is created as follows:
<pre>
   void *pParser = ParseAlloc( malloc );
</pre>
<p>The ParseAlloc() routine allocates and initializes a new parser and
The ParseAlloc() routine allocates and initializes a new parser and
returns a pointer to it.
The actual data structure used to represent a parser is opaque &mdash;
its internal structure is not visible or usable by the calling routine.
For this reason, the ParseAlloc() routine returns a pointer to void
rather than a pointer to some particular structure.
The sole argument to the ParseAlloc() routine is a pointer to the
subroutine used to allocate memory.  Typically this means malloc().</p>

<p>After a program is finished using a parser, it can reclaim all
memory allocated by that parser by calling</p>
memory allocated by that parser by calling
<pre>
   ParseFree(pParser, free);
</pre>
<p>The first argument is the same pointer returned by ParseAlloc().  The
The first argument is the same pointer returned by ParseAlloc().  The
second argument is a pointer to the function used to release bulk
memory back to the system.</p>

<p>After a parser has been allocated using ParseAlloc(), the programmer
must supply the parser with a sequence of tokens (terminal symbols) to
be parsed.  This is accomplished by calling the following function
once for each token:<p>
once for each token:
<pre>
   Parse(pParser, hTokenID, sTokenData, pArg);
</pre>
<p>The first argument to the Parse() routine is the pointer returned by
The first argument to the Parse() routine is the pointer returned by
ParseAlloc().
The second argument is a small positive integer that tells the parser the
type of the next token in the data stream.
There is one token type for each terminal symbol in the grammar.
The gram.h file generated by Lemon contains #define statements that
map symbolic terminal symbol names into appropriate integer values.
A value of 0 for the second argument is a special flag to the
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
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







-
+




















-
+











-
+










-
+










-
+










-
+



-
+





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



-
+








-
+







-
+


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







-
+

-
-
-
+
+
+

-
-
+







the Parse() function will have a fourth parameter that can be
of any type chosen by the programmer.  The parser doesn't do anything
with this argument except to pass it through to action routines.
This is a convenient mechanism for passing state information down
to the action routines without having to use global variables.</p>

<p>A typical use of a Lemon parser might look something like the
following:</p>
following:
<pre>
    1 ParseTree *ParseFile(const char *zFilename){
    2    Tokenizer *pTokenizer;
    3    void *pParser;
    4    Token sToken;
    5    int hTokenId;
    6    ParserState sState;
    7
    8    pTokenizer = TokenizerCreate(zFilename);
    9    pParser = ParseAlloc( malloc );
   10    InitParserState(&amp;sState);
   11    while( GetNextToken(pTokenizer, &amp;hTokenId, &amp;sToken) ){
   12       Parse(pParser, hTokenId, sToken, &amp;sState);
   13    }
   14    Parse(pParser, 0, sToken, &amp;sState);
   15    ParseFree(pParser, free );
   16    TokenizerFree(pTokenizer);
   17    return sState.treeRoot;
   18 }
</pre>
<p>This example shows a user-written routine that parses a file of
This example shows a user-written routine that parses a file of
text and returns a pointer to the parse tree.
(All error-handling code is omitted from this example to keep it
simple.)
We assume the existence of some kind of tokenizer which is created
using TokenizerCreate() on line 8 and deleted by TokenizerFree()
on line 16.  The GetNextToken() function on line 11 retrieves the
next token from the input file and puts its type in the
integer variable hTokenId.  The sToken variable is assumed to be
some kind of structure that contains details about each token,
such as its complete text, what line it occurs on, etc.</p>

<p>This example also assumes the existence of a structure of type
<p>This example also assumes the existence of structure of type
ParserState that holds state information about a particular parse.
An instance of such a structure is created on line 6 and initialized
on line 10.  A pointer to this structure is passed into the Parse()
routine as the optional 4th argument.
The action routine specified by the grammar for the parser can use
the ParserState structure to hold whatever information is useful and
appropriate.  In the example, we note that the treeRoot field of
the ParserState structure is left pointing to the root of the parse
tree.</p>

<p>The core of this example as it relates to Lemon is as follows:</p>
<p>The core of this example as it relates to Lemon is as follows:
<pre>
   ParseFile(){
      pParser = ParseAlloc( malloc );
      while( GetNextToken(pTokenizer,&amp;hTokenId, &amp;sToken) ){
         Parse(pParser, hTokenId, sToken);
      }
      Parse(pParser, 0, sToken);
      ParseFree(pParser, free );
   }
</pre>
<p>Basically, what a program has to do to use a Lemon-generated parser
Basically, what a program has to do to use a Lemon-generated parser
is first create the parser, then send it lots of tokens obtained by
tokenizing an input source.  When the end of input is reached, the
Parse() routine should be called one last time with a token type
of 0.  This step is necessary to inform the parser that the end of
input has been reached.  Finally, we reclaim memory used by the
parser by calling ParseFree().</p>

<p>There is one other interface routine that should be mentioned
before we move on.
The ParseTrace() function can be used to generate debugging output
from the parser.  A prototype for this routine is as follows:</p>
from the parser.  A prototype for this routine is as follows:
<pre>
   ParseTrace(FILE *stream, char *zPrefix);
</pre>
<p>After this routine is called, a short (one-line) message is written
After this routine is called, a short (one-line) message is written
to the designated output stream every time the parser changes states
or calls an action routine.  Each such message is prefaced using
the text given by zPrefix.  This debugging output can be turned off
by calling ParseTrace() again with a first argument of NULL (0).</p>

<a id="onstack"></a>
<h4>3.2.1 Allocating The Parse Object On Stack</h4>

<p>If all calls to the Parse() interface are made from within
<a href="#pcode"><tt>%code</tt> directives</a>, then the parse
object can be allocated from the stack rather than from the heap.
These are the steps:

<ul>
<li> Declare a local variable of type "yyParser"
<li> Initialize the variable using ParseInit()
<li> Pass a pointer to the variable in calls ot Parse()
<li> Deallocate substructure in the parse variable using ParseFinalize().
</ul>

<p>The following code illustrates how this is done:

<pre>
   ParseFile(){
      yyParser x;
      ParseInit( &x );
      while( GetNextToken(pTokenizer,&amp;hTokenId, &amp;sToken) ){
         Parse(&x, hTokenId, sToken);
      }
      Parse(&x, 0, sToken);
      ParseFinalize( &x );
   }
</pre>

<a id="ifsum"></a>
<h4>3.2.2 Interface Summary</h4>

<p>Here is a quick overview of the C-language interface to a
Lemon-generated parser:</p>

<blockquote><pre>
void *ParseAlloc( (void*(*malloc)(size_t) );
void ParseFree(void *pParser, (void(*free)(void*) );
void Parse(void *pParser, int tokenCode, ParseTOKENTYPE token, ...);
void ParseTrace(FILE *stream, char *zPrefix);
</pre></blockquote>

<p>Notes:</p>
<ul>
<li> Use the <a href="#pname"><tt>%name</tt> directive</a> to change
the "Parse" prefix names of the procedures in the interface.
<li> Use the <a href="#token_type"><tt>%token_type</tt> directive</a>
to define the "ParseTOKENTYPE" type.
<li> Use the <a href="#extraarg"><tt>%extra_argument</tt> directive</a>
to specify the type and name of the 4th parameter to the
Parse() function.
</ul>

<a id="yaccdiff"></a>
<h3>3.3 Differences With YACC and BISON</h3>
<h3>Differences With YACC and BISON</h3>

<p>Programmers who have previously used the yacc or bison parser
generator will notice several important differences between yacc and/or
bison and Lemon.</p>
bison and Lemon.
<ul>
<li>In yacc and bison, the parser calls the tokenizer.  In Lemon,
    the tokenizer calls the parser.
<li>Lemon uses no global variables.  Yacc and bison use global variables
    to pass information between the tokenizer and parser.
<li>Lemon allows multiple parsers to be running simultaneously.  Yacc
    and bison do not.
</ul>
<p>These differences may cause some initial confusion for programmers
These differences may cause some initial confusion for programmers
with prior yacc and bison experience.
But after years of experience using Lemon, I firmly
believe that the Lemon way of doing things is better.</p>

<p><i>Updated as of 2016-02-16:</i>
The text above was written in the 1990s.
We are told that Bison has lately been enhanced to support the
tokenizer-calls-parser paradigm used by Lemon, eliminating the
tokenizer-calls-parser paradigm used by Lemon, and to obviate the
need for global variables.</p>

<a id="build"><a>
<h3>3.4 Building The "lemon" or "lemon.exe" Executable</h3>

<p>The "lemon" or "lemon.exe" program is built from a single file
of C-code named 
"<a href="https://sqlite.org/src/tool/lemon.c">lemon.c</a>". 
The Lemon source code is generic C89 code that uses
no unusual or non-standard libraries.  Any
reasonable C compiler should suffice to compile the lemon program.  
A command-line like the following will usually work:</p>

<blockquote><pre>
cc -o lemon lemon.c
</pre></blockquote

<p>On Windows machines with Visual C++ installed, bring up a
"VS20<i>NN</i> x64 Native Tools Command Prompt" window and enter:

<blockquote><pre>
cl lemon.c
</pre></blockquote>

<p>Compiling Lemon really is that simple. 
Additional compiler options such as
"-O2" or "-g" or "-Wall" can be added if desired, but they are not
necessary.</p>


<a id="syntax"></a>
<h2>4.0 Input File Syntax</h2>
<h2>Input File Syntax</h2>

<p>The main purpose of the grammar specification file for Lemon is
to define the grammar for the parser.  But the input file also
specifies additional information Lemon requires to do its job.
Most of the work in using Lemon is in writing an appropriate
grammar file.</p>

<p>The grammar file for Lemon is, for the most part, a free format.
<p>The grammar file for Lemon is, for the most part, free format.
It does not have sections or divisions like yacc or bison.  Any
declaration can occur at any point in the file.  Lemon ignores
whitespace (except where it is needed to separate tokens), and it
honors the same commenting conventions as C and C++.</p>
declaration can occur at any point in the file.
Lemon ignores whitespace (except where it is needed to separate
tokens), and it honors the same commenting conventions as C and C++.</p>

<a id="tnt"></a>
<h3>4.1 Terminals and Nonterminals</h3>
<h3>Terminals and Nonterminals</h3>

<p>A terminal symbol (token) is any string of alphanumeric
and/or underscore characters
that begins with an uppercase letter.
A terminal can contain lowercase letters after the first character,
but the usual convention is to make terminals all uppercase.
A nonterminal, on the other hand, is any string of alphanumeric
454
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
470
471
472
473
474
475

476
477
478
479
480
481

482
483
484
485
486
487
488
489
490
491
492
493

494
495
496

497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

514
515
516
517

518
519
520
521

522
523
524

525
526
527
528
529
530
531
532
533
534

535
536
537
538

539
540
541
542
543
544
545
546
547


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

566
567
568
569
570
571
572

573
574
575
576
577

578
579
580
581

582
583
584
585

586
587

588
589
590
591

592
593
594
595

596
597
598
599

600
601
602
603
604


605
606
607
608

609
610
611
612
613
614

615
616
617
618
619

620
621

622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650

651
652
653
654
655
656
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
672
673
674
675
676

677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708
709
710
711


712
713
714
715
716
717
718
719
720
721
722
723
724
725
726


727
728
729
730
731

732
733
734
735
736
737
738
739
740


741
742
743
744
745
746
747


748
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763

764
765
766
767

768
769
770
771
772
773

774
775
776
777
778
779
780
330
331
332
333
334
335
336


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

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389

390
391
392
393

394
395
396
397

398
399
400

401
402
403
404
405
406
407
408
409
410

411
412
413
414

415
416
417
418
419
420
421
422


423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448

449
450
451
452
453

454
455
456
457

458
459
460
461

462
463

464
465
466
467

468
469
470
471

472
473
474
475

476
477
478
479


480
481
482
483
484

485
486
487
488
489
490

491
492
493
494
495

496
497

498
499
500
501
502
503
504
505
506

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
539


540
541
542
543
544
545
546
547
548
549
550
551

552
553
554
555
556
557

558
559
560

561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

581
582
583


584
585
586
587
588
589
590
591
592
593
594
595





596
597
598
599
600
601

602
603
604
605
606
607
608
609


610
611
612
613
614
615
616


617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633

634
635
636
637

638
639
640
641
642
643

644
645
646
647
648
649
650
651







-
-
+












-
+






+











-
+



+
















-
+



-
+



-
+


-
+









-
+



-
+







-
-
+
+

















-
+






-
+




-
+



-
+



-
+

-
+



-
+



-
+



-
+



-
-
+
+



-
+





-
+




-
+

-
+








-
+



















-
+












-
-
+











-
+





-



-




















-
+


-
-
+
+










-
-
-
-
-
+
+




-
+







-
-
+
+





-
-
+
+








-
+






-
+



-
+





-
+








<p>Yacc and bison allow terminal symbols to have either alphanumeric
names or to be individual characters included in single quotes, like
this: ')' or '$'.  Lemon does not allow this alternative form for
terminal symbols.  With Lemon, all symbols, terminals and nonterminals,
must have alphanumeric names.</p>

<a id="rules"></a>
<h3>4.2 Grammar Rules</h3>
<h3>Grammar Rules</h3>

<p>The main component of a Lemon grammar file is a sequence of grammar
rules.
Each grammar rule consists of a nonterminal symbol followed by
the special symbol "::=" and then a list of terminals and/or nonterminals.
The rule is terminated by a period.
The list of terminals and nonterminals on the right-hand side of the
rule can be empty.
Rules can occur in any order, except that the left-hand side of the
first rule is assumed to be the start symbol for the grammar (unless
specified otherwise using the <tt><a href='#start_symbol'>%start_symbol</a></tt>
directive described below.)
A typical sequence of grammar rules might look something like this:</p>
A typical sequence of grammar rules might look something like this:
<pre>
  expr ::= expr PLUS expr.
  expr ::= expr TIMES expr.
  expr ::= LPAREN expr RPAREN.
  expr ::= VALUE.
</pre>
</p>

<p>There is one non-terminal in this example, "expr", and five
terminal symbols or tokens: "PLUS", "TIMES", "LPAREN",
"RPAREN" and "VALUE".</p>

<p>Like yacc and bison, Lemon allows the grammar to specify a block
of C code that will be executed whenever a grammar rule is reduced
by the parser.
In Lemon, this action is specified by putting the C code (contained
within curly braces <tt>{...}</tt>) immediately after the
period that closes the rule.
For example:</p>
For example:
<pre>
  expr ::= expr PLUS expr.   { printf("Doing an addition...\n"); }
</pre>
</p>

<p>In order to be useful, grammar actions must normally be linked to
their associated grammar rules.
In yacc and bison, this is accomplished by embedding a "$$" in the
action to stand for the value of the left-hand side of the rule and
symbols "$1", "$2", and so forth to stand for the value of
the terminal or nonterminal at position 1, 2 and so forth on the
right-hand side of the rule.
This idea is very powerful, but it is also very error-prone.  The
single most common source of errors in a yacc or bison grammar is
to miscount the number of symbols on the right-hand side of a grammar
rule and say "$7" when you really mean "$8".</p>

<p>Lemon avoids the need to count grammar symbols by assigning symbolic
names to each symbol in a grammar rule and then using those symbolic
names in the action.
In yacc or bison, one would write this:</p>
In yacc or bison, one would write this:
<pre>
  expr -&gt; expr PLUS expr  { $$ = $1 + $3; };
</pre>
<p>But in Lemon, the same rule becomes the following:</p>
But in Lemon, the same rule becomes the following:
<pre>
  expr(A) ::= expr(B) PLUS expr(C).  { A = B+C; }
</pre>
<p>In the Lemon rule, any symbol in parentheses after a grammar rule
In the Lemon rule, any symbol in parentheses after a grammar rule
symbol becomes a place holder for that symbol in the grammar rule.
This place holder can then be used in the associated C action to
stand for the value of that symbol.</p>
stand for the value of that symbol.<p>

<p>The Lemon notation for linking a grammar rule with its reduce
action is superior to yacc/bison on several counts.
First, as mentioned above, the Lemon method avoids the need to
count grammar symbols.
Secondly, if a terminal or nonterminal in a Lemon grammar rule
includes a linking symbol in parentheses but that linking symbol
is not actually used in the reduce action, then an error message
is generated.
For example, the rule</p>
For example, the rule
<pre>
  expr(A) ::= expr(B) PLUS expr(C).  { A = B; }
</pre>
<p>will generate an error because the linking symbol "C" is used
will generate an error because the linking symbol "C" is used
in the grammar rule but not in the reduce action.</p>

<p>The Lemon notation for linking grammar rules to reduce actions
also facilitates the use of destructors for reclaiming memory
allocated by the values of terminals and nonterminals on the
right-hand side of a rule.</p>

<a id='precrules'></a>
<h3>4.3 Precedence Rules</h3>
<a name='precrules'></a>
<h3>Precedence Rules</h3>

<p>Lemon resolves parsing ambiguities in exactly the same way as
yacc and bison.  A shift-reduce conflict is resolved in favor
of the shift, and a reduce-reduce conflict is resolved by reducing
whichever rule comes first in the grammar file.</p>

<p>Just like in
yacc and bison, Lemon allows a measure of control
over the resolution of parsing conflicts using precedence rules.
A precedence value can be assigned to any terminal symbol
using the
<tt><a href='#pleft'>%left</a></tt>,
<tt><a href='#pright'>%right</a></tt> or
<tt><a href='#pnonassoc'>%nonassoc</a></tt> directives.  Terminal symbols
mentioned in earlier directives have a lower precedence than
terminal symbols mentioned in later directives.  For example:</p>

<pre>
<p><pre>
   %left AND.
   %left OR.
   %nonassoc EQ NE GT GE LT LE.
   %left PLUS MINUS.
   %left TIMES DIVIDE MOD.
   %right EXP NOT.
</pre>
</pre></p>

<p>In the preceding sequence of directives, the AND operator is
defined to have the lowest precedence.  The OR operator is one
precedence level higher.  And so forth.  Hence, the grammar would
attempt to group the ambiguous expression</p>
attempt to group the ambiguous expression
<pre>
     a AND b OR c
</pre>
<p>like this</p>
like this
<pre>
     a AND (b OR c).
</pre>
<p>The associativity (left, right or nonassoc) is used to determine
The associativity (left, right or nonassoc) is used to determine
the grouping when the precedence is the same.  AND is left-associative
in our example, so</p>
in our example, so
<pre>
     a AND b AND c
</pre>
<p>is parsed like this</p>
is parsed like this
<pre>
     (a AND b) AND c.
</pre>
<p>The EXP operator is right-associative, though, so</p>
The EXP operator is right-associative, though, so
<pre>
     a EXP b EXP c
</pre>
<p>is parsed like this</p>
is parsed like this
<pre>
     a EXP (b EXP c).
</pre>
<p>The nonassoc precedence is used for non-associative operators.
So</p>
The nonassoc precedence is used for non-associative operators.
So
<pre>
     a EQ b EQ c
</pre>
<p>is an error.</p>
is an error.</p>

<p>The precedence of non-terminals is transferred to rules as follows:
The precedence of a grammar rule is equal to the precedence of the
left-most terminal symbol in the rule for which a precedence is
defined.  This is normally what you want, but in those cases where
you want the precedence of a grammar rule to be something different,
you want to precedence of a grammar rule to be something different,
you can specify an alternative precedence symbol by putting the
symbol in square braces after the period at the end of the rule and
before any C-code.  For example:</p>

<pre>
<p><pre>
   expr = MINUS expr.  [NOT]
</pre>
</pre></p>

<p>This rule has a precedence equal to that of the NOT symbol, not the
MINUS symbol as would have been the case by default.</p>

<p>With the knowledge of how precedence is assigned to terminal
symbols and individual
grammar rules, we can now explain precisely how parsing conflicts
are resolved in Lemon.  Shift-reduce conflicts are resolved
as follows:</p>
as follows:
<ul>
<li> If either the token to be shifted or the rule to be reduced
     lacks precedence information, then resolve in favor of the
     shift, but report a parsing conflict.
<li> If the precedence of the token to be shifted is greater than
     the precedence of the rule to reduce, then resolve in favor
     of the shift.  No parsing conflict is reported.
<li> If the precedence of the token to be shifted is less than the
     precedence of the rule to reduce, then resolve in favor of the
     reduce action.  No parsing conflict is reported.
<li> If the precedences are the same and the shift token is
     right-associative, then resolve in favor of the shift.
     No parsing conflict is reported.
<li> If the precedences are the same and the shift token is
     left-associative, then resolve in favor of the reduce.
     No parsing conflict is reported.
<li> Otherwise, resolve the conflict by doing the shift, and
     report a parsing conflict.
</ul>
<p>Reduce-reduce conflicts are resolved this way:</p>
Reduce-reduce conflicts are resolved this way:
<ul>
<li> If either reduce rule
     lacks precedence information, then resolve in favor of the
     rule that appears first in the grammar, and report a parsing
     conflict.
<li> If both rules have precedence and the precedence is different,
     then resolve the dispute in favor of the rule with the highest
     precedence, and do not report a conflict.
<li> Otherwise, resolve the conflict by reducing by the rule that
     appears first in the grammar, and report a parsing conflict.
</ul>

<a id="special"></a>
<h3>4.4 Special Directives</h3>
<h3>Special Directives</h3>

<p>The input grammar to Lemon consists of grammar rules and special
directives.  We've described all the grammar rules, so now we'll
talk about the special directives.</p>

<p>Directives in Lemon can occur in any order.  You can put them before
the grammar rules, or after the grammar rules, or in the midst of the
grammar rules.  It doesn't matter.  The relative order of
directives used to assign precedence to terminals is important, but
other than that, the order of directives in Lemon is arbitrary.</p>

<p>Lemon supports the following special directives:</p>
<p>Lemon supports the following special directives:
<ul>
<li><tt><a href='#pcode'>%code</a></tt>
<li><tt><a href='#default_destructor'>%default_destructor</a></tt>
<li><tt><a href='#default_type'>%default_type</a></tt>
<li><tt><a href='#destructor'>%destructor</a></tt>
<li><tt><a href='#pifdef'>%else</a></tt>
<li><tt><a href='#pifdef'>%endif</a></tt>
<li><tt><a href='#extraarg'>%extra_argument</a></tt>
<li><tt><a href='#pfallback'>%fallback</a></tt>
<li><tt><a href='#pifdef'>%if</a></tt>
<li><tt><a href='#pifdef'>%ifdef</a></tt>
<li><tt><a href='#pifdef'>%ifndef</a></tt>
<li><tt><a href='#pinclude'>%include</a></tt>
<li><tt><a href='#pleft'>%left</a></tt>
<li><tt><a href='#pname'>%name</a></tt>
<li><tt><a href='#pnonassoc'>%nonassoc</a></tt>
<li><tt><a href='#parse_accept'>%parse_accept</a></tt>
<li><tt><a href='#parse_failure'>%parse_failure</a></tt>
<li><tt><a href='#pright'>%right</a></tt>
<li><tt><a href='#stack_overflow'>%stack_overflow</a></tt>
<li><tt><a href='#stack_size'>%stack_size</a></tt>
<li><tt><a href='#start_symbol'>%start_symbol</a></tt>
<li><tt><a href='#syntax_error'>%syntax_error</a></tt>
<li><tt><a href='#token_class'>%token_class</a></tt>
<li><tt><a href='#token_destructor'>%token_destructor</a></tt>
<li><tt><a href='#token_prefix'>%token_prefix</a></tt>
<li><tt><a href='#token_type'>%token_type</a></tt>
<li><tt><a href='#ptype'>%type</a></tt>
<li><tt><a href='#pwildcard'>%wildcard</a></tt>
</ul>
<p>Each of these directives will be described separately in the
Each of these directives will be described separately in the
following sections:</p>

<a id='pcode'></a>
<h4>4.4.1 The <tt>%code</tt> directive</h4>
<a name='pcode'></a>
<h4>The <tt>%code</tt> directive</h4>

<p>The <tt>%code</tt> directive is used to specify additional C code that
is added to the end of the main output file.  This is similar to
the <tt><a href='#pinclude'>%include</a></tt> directive except that
<tt>%include</tt> is inserted at the beginning of the main output file.</p>

<p><tt>%code</tt> is typically used to include some action routines or perhaps
a tokenizer or even the "main()" function
as part of the output file.</p>

<p>There can be multiple <tt>%code</tt> directives.  The arguments of
all <tt>%code</tt> directives are concatenated.</p>

<a id='default_destructor'></a>
<h4>4.4.2 The <tt>%default_destructor</tt> directive</h4>
<a name='default_destructor'></a>
<h4>The <tt>%default_destructor</tt> directive</h4>

<p>The <tt>%default_destructor</tt> directive specifies a destructor to
use for non-terminals that do not have their own destructor
specified by a separate <tt>%destructor</tt> directive.  See the documentation
on the <tt><a href='#destructor'>%destructor</a></tt> directive below for
on the <tt><a name='#destructor'>%destructor</a></tt> directive below for
additional information.</p>

<p>In some grammars, many different non-terminal symbols have the
same data type and hence the same destructor.  This directive is
a convenient way to specify the same destructor for all those
non-terminals using a single statement.</p>

<a id='default_type'></a>
<h4>4.4.3 The <tt>%default_type</tt> directive</h4>
<a name='default_type'></a>
<h4>The <tt>%default_type</tt> directive</h4>

<p>The <tt>%default_type</tt> directive specifies the data type of non-terminal
symbols that do not have their own data type defined using a separate
<tt><a href='#ptype'>%type</a></tt> directive.</p>

<a id='destructor'></a>
<h4>4.4.4 The <tt>%destructor</tt> directive</h4>
<a name='destructor'></a>
<h4>The <tt>%destructor</tt> directive</h4>

<p>The <tt>%destructor</tt> directive is used to specify a destructor for
a non-terminal symbol.
(See also the <tt><a href='#token_destructor'>%token_destructor</a></tt>
directive which is used to specify a destructor for terminal symbols.)</p>

<p>A non-terminal's destructor is called to dispose of the
non-terminal's value whenever the non-terminal is popped from
the stack.  This includes all of the following circumstances:</p>
the stack.  This includes all of the following circumstances:
<ul>
<li> When a rule reduces and the value of a non-terminal on
     the right-hand side is not linked to C code.
<li> When the stack is popped during error processing.
<li> When the ParseFree() function runs.
</ul>
<p>The destructor can do whatever it wants with the value of
The destructor can do whatever it wants with the value of
the non-terminal, but its design is to deallocate memory
or other resources held by that non-terminal.</p>

<p>Consider an example:</p>
<p>Consider an example:
<pre>
   %type nt {void*}
   %destructor nt { free($$); }
   nt(A) ::= ID NUM.   { A = malloc( 100 ); }
</pre>
<p>This example is a bit contrived, but it serves to illustrate how
This example is a bit contrived, but it serves to illustrate how
destructors work.  The example shows a non-terminal named
"nt" that holds values of type "void*".  When the rule for
an "nt" reduces, it sets the value of the non-terminal to
space obtained from malloc().  Later, when the nt non-terminal
is popped from the stack, the destructor will fire and call
free() on this malloced space, thus avoiding a memory leak.
(Note that the symbol "$$" in the destructor code is replaced
789
790
791
792
793
794
795
796
797


798
799

800
801
802
803
804
805

806
807

808
809
810
811
812
813
814
815
816

817
818
819


820
821
822


823
824
825
826
827

828
829

830
831

832
833

834
835
836

837
838
839


840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855

856
857
858
859
860
861
862
863
864
865
866
867
868
869


870
871
872
873


874
875
876
877
878
879
880
881
882

883
884
885
886
887
888
889
890
891
892
893
894
895
896
897




898
899
900


901
902
903
904
905
906
907
908
909
910
911
912
913

914
915

916
917
918
919
920
921
922
923
924


925
926
927
928
929
930
931
932
933
934
935

936
937
938
939
940
941
942

943
944
945
946
947
948
949
950
951
952
953
954


955
956
957
958
959
960

961
962

963
964
965

966
967
968
969
970
971
972

973
974
975
976


977
978
979
980
981
982
983
984
985


986
987
988
989
990
991
992
993
994

995
996
997
998

999
1000
1001


1002
1003
1004
1005
1006
1007
1008
1009

1010
1011
1012
1013

1014
1015
1016


1017
1018
1019
1020
1021
1022
1023
1024


1025
1026
1027
1028
1029
1030
1031

1032
1033
1034
1035

1036
1037
1038
1039
1040
1041

1042
1043
1044
1045
1046

1047
1048
1049
1050

1051
1052
1053


1054
1055
1056
1057
1058
1059
1060
1061

1062
1063

1064
1065
1066


1067
1068
1069
1070
1071
1072
1073

1074
1075

1076
1077
1078


1079
1080

1081
1082
1083


1084
1085
1086
1087
1088
1089


1090
1091
1092
1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1105


1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123

1124
1125
1126
1127
1128
1129

1130
1131
1132


1133
1134
1135
1136
1137
1138
1139

1140
1141
1142

1143
1144

1145
1146
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156

1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169


1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180


1181
1182
1183
1184
1185
1186
1187
660
661
662
663
664
665
666


667
668
669

670
671
672
673
674
675

676
677

678
679
680
681
682
683
684
685
686

687
688


689
690
691


692
693
694
695
696
697

698
699

700
701

702
703

704
705
706

707
708


709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

726
727
728
729
730
731
732
733
734
735
736
737
738


739
740
741



742
743
744
745
746
747
748
749
750
751

752
753














754
755
756
757
758


759
760
761
762
763
764
765
766
767
768
769
770
771
772

773
774

775
776
777
778
779
780
781
782


783
784
785
786
787
788
789
790
791
792
793
794

795
796
797
798
799
800
801

802
803
804
805
806
807
808
809
810
811
812


813
814
815
816
817
818
819

820
821

822
823
824

825
826
827
828
829
830
831

832
833
834


835
836
837
838
839
840
841
842
843


844
845
846
847
848
849
850
851
852
853

854
855
856
857

858
859


860
861
862
863
864
865
866
867
868

869
870
871
872

873
874


875
876
877
878
879
880
881
882


883
884
885
886
887
888
889
890

891
892
893
894

895
896
897
898
899
900

901
902
903
904
905

906
907
908
909

910
911


912
913
914
915
916
917
918
919
920

921
922

923
924


925
926
927
928
929
930
931
932

933
934

935
936


937
938
939

940
941


942
943
944
945
946
947


948
949
950
951
952
953
954
955
956

957
958
959
960
961
962
963


964
965
966
967
968
969
970
971

972
973
974
975
976
977
978

979
980
981
982

983
984
985
986
987
988

989
990


991
992
993
994
995
996
997
998

999
1000
1001

1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012
1013

1014
1015

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


1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038


1039
1040
1041
1042
1043
1044
1045
1046
1047







-
-
+
+

-
+





-
+

-
+








-
+

-
-
+
+

-
-
+
+




-
+

-
+

-
+

-
+


-
+

-
-
+
+















-
+












-
-
+
+

-
-
-
+
+








-
+

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

-
-
+
+












-
+

-
+







-
-
+
+










-
+






-
+










-
-
+
+





-
+

-
+


-
+






-
+


-
-
+
+







-
-
+
+








-
+



-
+

-
-
+
+







-
+



-
+

-
-
+
+






-
-
+
+






-
+



-
+





-
+




-
+



-
+

-
-
+
+







-
+

-
+

-
-
+
+






-
+

-
+

-
-
+
+

-
+

-
-
+
+




-
-
+
+







-
+






-
-
+
+






-
+






-
+



-
+





-
+

-
-
+
+






-
+


-
+

-
+









-
+

-
+











-
-
+
+









-
-
+
+







larger structure, and we don't want to destroy it, which is why
the destructor is not called in this circumstance.</p>

<p>Destructors help avoid memory leaks by automatically freeing
allocated objects when they go out of scope.
To do the same using yacc or bison is much more difficult.</p>

<a id='extraarg'></a>
<h4>4.4.5 The <tt>%extra_argument</tt> directive</h4>
<a name='extraarg'></a>
<h4>The <tt>%extra_argument</tt> directive</h4>

<p>The <tt>%extra_argument</tt> directive instructs Lemon to add a 4th parameter
The <tt>%extra_argument</tt> directive instructs Lemon to add a 4th parameter
to the parameter list of the Parse() function it generates.  Lemon
doesn't do anything itself with this extra argument, but it does
make the argument available to C-code action routines, destructors,
and so forth.  For example, if the grammar file contains:</p>

<pre>
<p><pre>
    %extra_argument { MyStruct *pAbc }
</pre>
</pre></p>

<p>Then the Parse() function generated will have an 4th parameter
of type "MyStruct*" and all action routines will have access to
a variable named "pAbc" that is the value of the 4th parameter
in the most recent call to Parse().</p>

<p>The <tt>%extra_context</tt> directive works the same except that it
is passed in on the ParseAlloc() or ParseInit() routines instead of
on Parse().</p>
on Parse().

<a id='extractx'></a>
<h4>4.4.6 The <tt>%extra_context</tt> directive</h4>
<a name='extractx'></a>
<h4>The <tt>%extra_context</tt> directive</h4>

<p>The <tt>%extra_context</tt> directive instructs Lemon to add a 2nd parameter
to the parameter list of the ParseAlloc() and ParseInit() functions.  Lemon
The <tt>%extra_context</tt> directive instructs Lemon to add a 2th parameter
to the parameter list of the ParseAlloc() and ParseInif() functions.  Lemon
doesn't do anything itself with these extra argument, but it does
store the value make it available to C-code action routines, destructors,
and so forth.  For example, if the grammar file contains:</p>

<pre>
<p><pre>
    %extra_context { MyStruct *pAbc }
</pre>
</pre></p>

<p>Then the ParseAlloc() and ParseInit() functions will have an 2nd parameter
<p>Then the ParseAlloc() and ParseInit() functions will have an 2th parameter
of type "MyStruct*" and all action routines will have access to
a variable named "pAbc" that is the value of that 2nd parameter.</p>
a variable named "pAbc" that is the value of that 2th parameter.</p>

<p>The <tt>%extra_argument</tt> directive works the same except that it
is passed in on the Parse() routine instead of on ParseAlloc()/ParseInit().</p>
is passed in on the Parse() routine instead of on ParseAlloc()/ParseInit().

<a id='pfallback'></a>
<h4>4.4.7 The <tt>%fallback</tt> directive</h4>
<a name='pfallback'></a>
<h4>The <tt>%fallback</tt> directive</h4>

<p>The <tt>%fallback</tt> directive specifies an alternative meaning for one
or more tokens.  The alternative meaning is tried if the original token
would have generated a syntax error.</p>

<p>The <tt>%fallback</tt> directive was added to support robust parsing of SQL
syntax in <a href='https://www.sqlite.org/'>SQLite</a>.
The SQL language contains a large assortment of keywords, each of which
appears as a different token to the language parser.  SQL contains so
many keywords that it can be difficult for programmers to keep up with
them all.  Programmers will, therefore, sometimes mistakenly use an
obscure language keyword for an identifier.  The <tt>%fallback</tt> directive
provides a mechanism to tell the parser:  "If you are unable to parse
this keyword, try treating it as an identifier instead."</p>

<p>The syntax of <tt>%fallback</tt> is as follows:</p>
<p>The syntax of <tt>%fallback</tt> is as follows:

<blockquote>
<tt>%fallback</tt> <i>ID</i> <i>TOKEN...</i> <b>.</b>
</blockquote></p>

<p>In words, the <tt>%fallback</tt> directive is followed by a list of token
names terminated by a period.
The first token name is the fallback token &mdash; the
token to which all the other tokens fall back to.  The second and subsequent
arguments are tokens which fall back to the token identified by the first
argument.</p>

<a id='pifdef'></a>
<h4>4.4.8 The <tt>%if</tt> directive and its friends</h4>
<a name='pifdef'></a>
<h4>The <tt>%ifdef</tt>, <tt>%ifndef</tt>, and <tt>%endif</tt> directives</h4>

<p>The <tt>%if</tt>, <tt>%ifdef</tt>, <tt>%ifndef</tt>, <tt>%else</tt>,
and <tt>%endif</tt> directives
are similar to #if, #ifdef, #ifndef, #else, and #endif in the C-preprocessor,
<p>The <tt>%ifdef</tt>, <tt>%ifndef</tt>, and <tt>%endif</tt> directives
are similar to #ifdef, #ifndef, and #endif in the C-preprocessor,
just not as general.
Each of these directives must begin at the left margin.  No whitespace
is allowed between the "%" and the directive name.</p>

<p>Grammar text in between "<tt>%ifdef MACRO</tt>" and the next nested
"<tt>%endif</tt>" is
ignored unless the "-DMACRO" command-line option is used.  Grammar text
betwen "<tt>%ifndef MACRO</tt>" and the next nested "<tt>%endif</tt>" is
included except when the "-DMACRO" command-line option is used.<p>
included except when the "-DMACRO" command-line option is used.</p>

<p>The text in between "<tt>%if</tt> <i>CONDITIONAL</i>" and its
corresponding <tt>%endif</tt> is included only if <i>CONDITIONAL</i>
is true.  The CONDITION is one or more macro names, optionally connected
using the "||" and "&amp;&amp;" binary operators, the "!" unary operator,
and grouped using balanced parentheses.  Each term is true if the
corresponding macro exists, and false if it does not exist.</p>

<p>An optional "<tt>%else</tt>" directive can occur anywhere in between a 
<tt>%ifdef</tt>, <tt>%ifndef</tt>, or <tt>%if</tt> directive and
its corresponding <tt>%endif</tt>.</p>

<p>Note that the argument to <tt>%ifdef</tt> and <tt>%ifndef</tt> is
intended to be a single preprocessor symbol name, not a general expression.
Use the "<tt>%if</tt>" directive for general expressions.</p>
<p>Note that the argument to <tt>%ifdef</tt> and <tt>%ifndef</tt> must
be a single preprocessor symbol name, not a general expression.
There is no "<tt>%else</tt>" directive.</p>


<a id='pinclude'></a>
<h4>4.4.9 The <tt>%include</tt> directive</h4>
<a name='pinclude'></a>
<h4>The <tt>%include</tt> directive</h4>

<p>The <tt>%include</tt> directive specifies C code that is included at the
top of the generated parser.  You can include any text you want &mdash;
the Lemon parser generator copies it blindly.  If you have multiple
<tt>%include</tt> directives in your grammar file, their values are concatenated
so that all <tt>%include</tt> code ultimately appears near the top of the
generated parser, in the same order as it appeared in the grammar.</p>

<p>The <tt>%include</tt> directive is very handy for getting some extra #include
preprocessor statements at the beginning of the generated parser.
For example:</p>

<pre>
<p><pre>
   %include {#include &lt;unistd.h&gt;}
</pre>
</pre></p>

<p>This might be needed, for example, if some of the C actions in the
grammar call functions that are prototyped in unistd.h.</p>

<p>Use the <tt><a href="#pcode">%code</a></tt> directive to add code to
the end of the generated parser.</p>

<a id='pleft'></a>
<h4>4.4.10 The <tt>%left</tt> directive</h4>
<a name='pleft'></a>
<h4>The <tt>%left</tt> directive</h4>

The <tt>%left</tt> directive is used (along with the
<tt><a href='#pright'>%right</a></tt> and
<tt><a href='#pnonassoc'>%nonassoc</a></tt> directives) to declare
precedences of terminal symbols.
Every terminal symbol whose name appears after
a <tt>%left</tt> directive but before the next period (".") is
given the same left-associative precedence value.  Subsequent
<tt>%left</tt> directives have higher precedence.  For example:</p>

<pre>
<p><pre>
   %left AND.
   %left OR.
   %nonassoc EQ NE GT GE LT LE.
   %left PLUS MINUS.
   %left TIMES DIVIDE MOD.
   %right EXP NOT.
</pre>
</pre></p>

<p>Note the period that terminates each <tt>%left</tt>,
<tt>%right</tt> or <tt>%nonassoc</tt>
directive.</p>

<p>LALR(1) grammars can get into a situation where they require
a large amount of stack space if you make heavy use or right-associative
operators.  For this reason, it is recommended that you use <tt>%left</tt>
rather than <tt>%right</tt> whenever possible.</p>

<a id='pname'></a>
<h4>4.4.11 The <tt>%name</tt> directive</h4>
<a name='pname'></a>
<h4>The <tt>%name</tt> directive</h4>

<p>By default, the functions generated by Lemon all begin with the
five-character string "Parse".  You can change this string to something
different using the <tt>%name</tt> directive.  For instance:</p>

<pre>
<p><pre>
   %name Abcde
</pre>
</pre></p>

<p>Putting this directive in the grammar file will cause Lemon to generate
functions named</p>
functions named
<ul>
<li> AbcdeAlloc(),
<li> AbcdeFree(),
<li> AbcdeTrace(), and
<li> Abcde().
</ul>
</p>The <tt>%name</tt> directive allows you to generate two or more different
The <tt>%name</tt> directive allows you to generate two or more different
parsers and link them all into the same executable.</p>

<a id='pnonassoc'></a>
<h4>4.4.12 The <tt>%nonassoc</tt> directive</h4>
<a name='pnonassoc'></a>
<h4>The <tt>%nonassoc</tt> directive</h4>

<p>This directive is used to assign non-associative precedence to
one or more terminal symbols.  See the section on
<a href='#precrules'>precedence rules</a>
or on the <tt><a href='#pleft'>%left</a></tt> directive
for additional information.</p>

<a id='parse_accept'></a>
<h4>4.4.13 The <tt>%parse_accept</tt> directive</h4>
<a name='parse_accept'></a>
<h4>The <tt>%parse_accept</tt> directive</h4>

<p>The <tt>%parse_accept</tt> directive specifies a block of C code that is
executed whenever the parser accepts its input string.  To "accept"
an input string means that the parser was able to process all tokens
without error.</p>

<p>For example:</p>

<pre>
<p><pre>
   %parse_accept {
      printf("parsing complete!\n");
   }
</pre>
</pre></p>

<a id='parse_failure'></a>
<h4>4.4.14 The <tt>%parse_failure</tt> directive</h4>
<a name='parse_failure'></a>
<h4>The <tt>%parse_failure</tt> directive</h4>

<p>The <tt>%parse_failure</tt> directive specifies a block of C code that
is executed whenever the parser fails complete.  This code is not
executed until the parser has tried and failed to resolve an input
error using is usual error recovery strategy.  The routine is
only invoked when parsing is unable to continue.</p>

<pre>
<p><pre>
   %parse_failure {
     fprintf(stderr,"Giving up.  Parser is hopelessly lost...\n");
   }
</pre>
</pre></p>

<a id='pright'></a>
<h4>4.4.15 The <tt>%right</tt> directive</h4>
<a name='pright'></a>
<h4>The <tt>%right</tt> directive</h4>

<p>This directive is used to assign right-associative precedence to
one or more terminal symbols.  See the section on
<a href='#precrules'>precedence rules</a>
or on the <a href='#pleft'>%left</a> directive for additional information.</p>

<a id='stack_overflow'></a>
<h4>4.4.16 The <tt>%stack_overflow</tt> directive</h4>
<a name='stack_overflow'></a>
<h4>The <tt>%stack_overflow</tt> directive</h4>

<p>The <tt>%stack_overflow</tt> directive specifies a block of C code that
is executed if the parser's internal stack ever overflows.  Typically
this just prints an error message.  After a stack overflow, the parser
will be unable to continue and must be reset.</p>

<pre>
<p><pre>
   %stack_overflow {
     fprintf(stderr,"Giving up.  Parser stack overflow\n");
   }
</pre>
</pre></p>

<p>You can help prevent parser stack overflows by avoiding the use
of right recursion and right-precedence operators in your grammar.
Use left recursion and and left-precedence operators instead to
encourage rules to reduce sooner and keep the stack size down.
For example, do rules like this:</p>
For example, do rules like this:
<pre>
   list ::= list element.      // left-recursion.  Good!
   list ::= .
</pre>
<p>Not like this:</p>
Not like this:
<pre>
   list ::= element list.      // right-recursion.  Bad!
   list ::= .
</pre>
</pre></p>

<a id='stack_size'></a>
<h4>4.4.17 The <tt>%stack_size</tt> directive</h4>
<a name='stack_size'></a>
<h4>The <tt>%stack_size</tt> directive</h4>

<p>If stack overflow is a problem and you can't resolve the trouble
by using left-recursion, then you might want to increase the size
of the parser's stack using this directive.  Put an positive integer
after the <tt>%stack_size</tt> directive and Lemon will generate a parse
with a stack of the requested size.  The default value is 100.</p>

<pre>
<p><pre>
   %stack_size 2000
</pre>
</pre></p>

<a id='start_symbol'></a>
<h4>4.4.18 The <tt>%start_symbol</tt> directive</h4>
<a name='start_symbol'></a>
<h4>The <tt>%start_symbol</tt> directive</h4>

<p>By default, the start symbol for the grammar that Lemon generates
is the first non-terminal that appears in the grammar file.  But you
can choose a different start symbol using the
<tt>%start_symbol</tt> directive.</p>

<pre>
<p><pre>
   %start_symbol  prog
</pre>
</pre></p>

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

<p>See <a href='#errors'>Error Processing</a>.</p>
<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>
<a name='token_class'></a>
<h4>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>

<a id='token_destructor'></a>
<h4>4.4.21 The <tt>%token_destructor</tt> directive</h4>
<a name='token_destructor'></a>
<h4>The <tt>%token_destructor</tt> directive</h4>

<p>The <tt>%destructor</tt> directive assigns a destructor to a non-terminal
symbol.  (See the description of the
<tt><a href='%destructor'>%destructor</a></tt> directive above.)
The <tt>%token_destructor</tt> directive does the same thing
for all terminal symbols.</p>

<p>Unlike non-terminal symbols, which may each have a different data type
<p>Unlike non-terminal symbols which may each have a different data type
for their values, terminals all use the same data type (defined by
the <tt><a href='#token_type'>%token_type</a></tt> directive)
and so they use a common destructor.
Other than that, the token destructor works just like the non-terminal
destructors.</p>

<a id='token_prefix'></a>
<h4>4.4.22 The <tt>%token_prefix</tt> directive</h4>
<a name='token_prefix'></a>
<h4>The <tt>%token_prefix</tt> directive</h4>

<p>Lemon generates #defines that assign small integer constants
to each terminal symbol in the grammar.  If desired, Lemon will
add a prefix specified by this directive
to each of the #defines it generates.</p>

<p>So if the default output of Lemon looked like this:</p>
<p>So if the default output of Lemon looked like this:
<pre>
    #define AND              1
    #define MINUS            2
    #define OR               3
    #define PLUS             4
</pre>
<p>You can insert a statement into the grammar like this:</p>
You can insert a statement into the grammar like this:
<pre>
    %token_prefix    TOKEN_
</pre>
<p>to cause Lemon to produce these symbols instead:</p>
to cause Lemon to produce these symbols instead:
<pre>
    #define TOKEN_AND        1
    #define TOKEN_MINUS      2
    #define TOKEN_OR         3
    #define TOKEN_PLUS       4
</pre>
</pre></p>

<a id='token_type'></a><a id='ptype'></a>
<h4>4.4.23 The <tt>%token_type</tt> and <tt>%type</tt> directives</h4>
<a name='token_type'></a><a name='ptype'></a>
<h4>The <tt>%token_type</tt> and <tt>%type</tt> directives</h4>

<p>These directives are used to specify the data types for values
on the parser's stack associated with terminal and non-terminal
symbols.  The values of all terminal symbols must be of the same
type.  This turns out to be the same data type as the 3rd parameter
to the Parse() function generated by Lemon.  Typically, you will
make the value of a terminal symbol be a pointer to some kind of
make the value of a terminal symbol by a pointer to some kind of
token structure.  Like this:</p>

<pre>
<p><pre>
   %token_type    {Token*}
</pre>
</pre></p>

<p>If the data type of terminals is not specified, the default value
is "void*".</p>

<p>Non-terminal symbols can each have their own data types.  Typically
the data type of a non-terminal is a pointer to the root of a parse tree
structure that contains all information about that non-terminal.
For example:</p>

<pre>
<p><pre>
   %type   expr  {Expr*}
</pre>
</pre></p>

<p>Each entry on the parser's stack is actually a union containing
instances of all data types for every non-terminal and terminal symbol.
Lemon will automatically use the correct element of this union depending
on what the corresponding non-terminal or terminal symbol is.  But
the grammar designer should keep in mind that the size of the union
will be the size of its largest element.  So if you have a single
non-terminal whose data type requires 1K of storage, then your 100
entry parser stack will require 100K of heap space.  If you are willing
and able to pay that price, fine.  You just need to know.</p>

<a id='pwildcard'></a>
<h4>4.4.24 The <tt>%wildcard</tt> directive</h4>
<a name='pwildcard'></a>
<h4>The <tt>%wildcard</tt> directive</h4>

<p>The <tt>%wildcard</tt> directive is followed by a single token name and a
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>
<a name='error_processing'></a>
<h3>Error Processing</h3>

<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
first invokes the code specified by the <tt>%syntax_error</tt> directive, if
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
1056
1057
1058
1059
1060
1061
1062




































1063
1064







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


is unable to shift the error symbol, then the
<tt><a href='#parse_failure'>%parse_failure</a></tt> routine
is invoked and the parser resets itself to its start state, ready
to begin parsing a new file.  This is what will happen at the very
first syntax error, of course, if there are no instances of the
"error" non-terminal in your grammar.</p>

<a id='history'></a>
<h2>6.0 History of Lemon</h2>

<p>Lemon was originally written by Richard Hipp sometime in the late
1980s on a Sun4 Workstation using K&amp;R C.  
There was a companion LL(1) parser generator program named "Lime", the
source code to which as been lost.</p>

<p>The lemon.c source file was originally many separate files that were
compiled together to generate the "lemon" executable.  Sometime in the
1990s, the individual source code files were combined together into
the current single large "lemon.c" source file.  You can still see traces
of original filenames in the code.</p>

<p>Since 2001, Lemon has been part of the 
<a href="https://sqlite.org/">SQLite project</a> and the source code
to Lemon has been managed as a part of the 
<a href="https://sqlite.org/src">SQLite source tree</a> in the following
files:</p>

<ul>
<li> <a href="https://sqlite.org/src/file/tool/lemon.c">tool/lemon.c</a>
<li> <a href="https://sqlite.org/src/file/tool/lempar.c">tool/lempar.c</a>
<li> <a href="https://sqlite.org/src/file/doc/lemon.html">doc/lemon.html</a>
</ul>

<a id="copyright"></a>
<h2>7.0 Copyright</h2>

<p>All of the source code to Lemon, including the template parser file
"lempar.c" and this documentation file ("lemon.html") are in the public
domain.  You can use the code for any purpose and without attribution.</p>

<p>The code comes with no warranty.  If it breaks, you get to keep both
pieces.</p>

</body>
</html>

Deleted doc/trusted-schema.md.

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














































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# The new-security-options branch

## The problem that the [new-security-options](/timeline?r=new-security-options) branch tries to solve

An attacker might modify the schema of an SQLite database by adding
structures that cause code to run when some other application opens and
reads the database.  For example, the attacker might replace a table
definition with a view.  Or the attacker might add triggers to tables
or views, or add new CHECK constraints or generated columns or indexes
with expressions in the index list or in the WHERE clause.  If the
added features invoke SQL functions or virtual tables with side effects,
that might cause harm to the system if run by a high-privilege victim.
Or, the added features might exfiltrate information if the database is
read by a high-privilege victim.

The changes in this branch strive to make it easier for high-privilege
applications to safely read SQLite database files that might have been
maliciously corrupted by an attacker.

## Overview of changes in [new-security-options](/timeline?r=new-security-options)

The basic idea is to tag every SQL function and virtual table with one
of three risk levels:

  1.  Innocuous
  2.  Normal
  3.  Direct-Only

Innocuous functions/vtabs are safe and can be used at any time.
Direct-only elements, in contrast, might have cause side-effects and
should only be used from top-level SQL, not from within triggers or views nor
in elements of the schema such as CHECK constraint, DEFAULT values, 
generated columns, index expressions, or in the WHERE clause of a 
partial index that are potentially under the control of an attacker.
Normal elements behave like Innocuous if TRUSTED\_SCHEMA=on
and behave like direct-only if TRUSTED\_SCHEMA=off.

Application-defined functions and virtual tables go in as Normal unless
the application takes deliberate steps to change the risk level.

For backwards compatibility, the default is TRUSTED\_SCHEMA=on.  Documentation
will be updated to recommend applications turn TRUSTED\_SCHEMA to off.

An innocuous function or virtual table is one that can only read content
from the database file in which it resides, and can only alter the database
in which it resides.  Most SQL functions are innocuous.  For example, there
is no harm in an attacker running the abs() function.

Direct-only elements that have side-effects that go outside the database file
in which it lives, or return information from outside of the database file.
Examples of direct-only elements include:

  1.  The fts3\_tokenizer() function
  2.  The writefile() function
  3.  The readfile() function
  4.  The zipvfs virtual table
  5.  The csv virtual table

We do not want an attacker to be able to add these kinds of things to
the database schema and possibly trick a high-privilege application 
from performing any of these actions.  Therefore, functions and vtabs
with side-effects are marked as Direct-Only.

Legacy applications might add other risky functions or vtabs.  Those will
go in as "Normal" by default.  For optimal security, we want those risky
app-defined functions and vtabs to be direct-only, but making that the
default might break some legacy applications.  Hence, all app-defined
functions and vtabs go in as Normal, but the application can switch them
over to "Direct-Only" behavior using a single pragma.

The restrictions on the use of functions and virtual tables do not apply
to TEMP.  A TEMP VIEW or a TEMP TRIGGER can use any valid SQL function
or virtual table.  The idea is that TEMP views and triggers must be
directly created by the application and are thus under the control of the
application.  TEMP views and triggers cannot be created by an attacker who
corrupts the schema of a persistent database file.  Hence TEMP views and
triggers are safe.

## Specific changes

  1.  New sqlite3\_db\_config() option SQLITE\_DBCONFIG\_TRUSTED\_SCHEMA for
      turning TRUSTED\_SCHEMA on and off.  It defaults to ON.

  2.  Compile-time option -DSQLITE\_TRUSTED\_SCHEMA=0 causes the default
      TRUSTED\_SCHEMA setting to be off.

  3.  New pragma "PRAGMA trusted\_schema=(ON\|OFF);".  This provides access
      to the TRUSTED_SCHEMA setting for application coded using scripting
      languages or other secondary languages where they are unable to make
      calls to sqlite3\_db\_config().

  4.  New options for the "enc" parameter to sqlite3\_create\_function() and
      its kin:
      <ol type="a">
      <li>  _SQLITE\_INNOCUOUS_  &rarr; tags the new functions as Innocuous
      <li>  _SQLITE\_DIRECTONLY_ &rarr; tags the new functions as Direct-Only
      </ol>

  5.  New options to sqlite3\_vtab\_config():
      <ol type="a">
      <li>  _SQLITE\_VTAB\_INNOCUOUS_   &rarr; tags the vtab as Innocuous
      <li>  _SQLITE\_VTAB\_DIRECTONLY_  &rarr; tags the vtab as Direct-Only
      </ol>

  6.  Change many of the functions and virtual tables in the SQLite source
      tree to use one of the tags above.

  7.  Enhanced PRAGMA function\_list and virtual-table "pragma\_function\_list"
      with additional columns.  The columns now are:
      <ul>
      <li> _name_      &rarr;  Name of the function
      <li> _builtin_   &rarr;  1 for built-in functions.  0 otherwise.
      <li> _type_      &rarr;  's'=Scalar, 'a'=Aggregate, 'w'=Window
      <li> _enc_       &rarr;  'utf8', 'utf16le', or 'utf16be'
      <li> _narg_      &rarr;  number of argument
      <li> _flags_     &rarr;  Bitmask of SQLITE\_INNOCUOUS, SQLITE\_DIRECTONLY,
                               SQLITE\_DETERMINISTIC, SQLITE\_SUBTYPE, and
                               SQLITE\_FUNC\_INTERNAL flags.
      </ul>
      <p>The last four columns are new.

  8.  The function\_list PRAGMA now also shows all entries for each function.
      So, for example, if a function can take either 2 or 3 arguments,
      there are separate rows for the 2-argument and 3-argument versions of
      the function.

## Additional Notes

The function_list enhancements allow the application to query the set
of SQL functions that meet various criteria.  For example, to see all
SQL functions that are never allowed to be used in the schema or in
trigger or views:

~~~
    SELECT DISTINCT name FROM pragma_function_list
     WHERE (flags & 0x80000)!=0
     ORDER BY name;
~~~

Doing the same is not possible for virtual tables, as a virtual table
might be Innocuous, Normal, or Direct-Only depending on the arguments
passed into the xConnect method.

Deleted doc/vdbesort-memory.md.

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

















































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

20-11-2020

# Memory Allocation In vdbesort.c

Memory allocation is slightly different depending on:

  * whether or not SQLITE_CONFIG_SMALL_MALLOC is set, and
  * whether or not worker threads are enabled.

## SQLITE_CONFIG_SMALL_MALLOC=0

Assuming SQLITE_CONFIG_SMALL_MALLOC is not set, keys passed to the sorter are
added to an in-memory buffer. This buffer is grown using sqlite3Realloc() as
required it reaches the size configured for the main pager cache using "PRAGMA
cache_size". i.e. if the user has executed "PRAGMA main.cache_size = -2048",
then this buffer is allowed to grow up to 2MB in size.

Once the buffer has grown to its threshold, keys are sorted and written to
a temp file. If worker threads are not enabled, this is the only significant
allocation the sorter module makes. After keys are sorted and flushed out to
the temp file, the buffer is reused to accumulate the next batch of keys.

If worker threads are available, then the buffer is passed to a worker thread
to sort and flush once it is full, and a new buffer allocated to allow the
main thread to continue to accumulate keys. Buffers are reused once they
have been flushed, so in this case at most (nWorker+1) buffers are allocated
and used, where nWorker is the number of configured worker threads.

There are no other significant users of heap memory in the sorter module. 
Once sorted buffers of keys have been flushed to disk, they are read back
either by mapping the file (via sqlite3_file.xFetch()) or else read back
in one page at a time.

All buffers are allocated by the main thread. A sorter object is associated
with a single database connection, to which it holds a pointer.

## SQLITE_CONFIG_SMALL_MALLOC=1

This case is similar to the above, except that instead of accumulating
multiple keys in a single large buffer, sqlite3VdbeSorterWrite() stores
keys in a regular heap-memory linked list (one allocation per element).
List elements are freed as they are flushed to disk, either by the main
thread or by a worker thread.

Each time a key is added the sorter (and an allocation made),
sqlite3HeapNearlyFull() is called. If it returns true, the current
list of keys is flushed to a temporary file, even if it has not yet
reached the size threshold.

Deleted doc/wal-lock.md.

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
























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# Wal-Mode Blocking Locks

On some Unix-like systems, SQLite may be configured to use POSIX blocking locks
by:

  * building the library with SQLITE\_ENABLE\_SETLK\_TIMEOUT defined, and 
  * configuring a timeout in ms using the sqlite3\_busy\_timeout() API.

Blocking locks may be advantageous as (a) waiting database clients do not
need to continuously poll the database lock, and (b) using blocking locks
facilitates transfer of OS priority between processes when a high priority
process is blocked by a lower priority one.

Only read/write clients use blocking locks. Clients that have read-only access
to the \*-shm file nevery use blocking locks.

Threads or processes that access a single database at a time never deadlock as
a result of blocking database locks. But it is of course possible for threads
that lock multiple databases simultaneously to do so. In most cases the OS will
detect the deadlock and return an error.

## Wal Recovery

Wal database "recovery" is a process required when the number of connected
database clients changes from zero to one. In this case, a client is 
considered to connect to the database when it first reads data from it.
Before recovery commences, an exclusive WRITER lock is taken. 

Without blocking locks, if two clients attempt recovery simultaneously, one
fails to obtain the WRITER lock and either invokes the busy-handler callback or
returns SQLITE\_BUSY to the user. With blocking locks configured, the second
client blocks on the WRITER lock.

## Database Readers

Usually, read-only are not blocked by any other database clients, so they 
have no need of blocking locks.

If a read-only transaction is being opened on a snapshot, the CHECKPOINTER
lock is required briefly as part of opening the transaction (to check that a
checkpointer is not currently overwriting the snapshot being opened). A
blocking lock is used to obtain the CHECKPOINTER lock in this case. A snapshot
opener may therefore block on and transfer priority to a checkpointer in some
cases.

## Database Writers

A database writer must obtain the exclusive WRITER lock. It uses a blocking
lock to do so if any of the following are true:

  * the transaction is an implicit one consisting of a single DML or DDL
    statement, or
  * the transaction is opened using BEGIN IMMEDIATE or BEGIN EXCLUSIVE, or
  * the first SQL statement executed following the BEGIN command is a DML or
    DDL statement (not a read-only statement like a SELECT).

In other words, in all cases except when an open read-transaction is upgraded
to a write-transaction. In that case a non-blocking lock is used.

## Database Checkpointers

Database checkpointers takes the following locks, in order:

  * The exclusive CHECKPOINTER lock.
  * The exclusive WRITER lock (FULL, RESTART and TRUNCATE only).
  * Exclusive lock on read-mark slots 1-N. These are immediately released after being taken.
  * Exclusive lock on read-mark 0.
  * Exclusive lock on read-mark slots 1-N again. These are immediately released
    after being taken (RESTART and TRUNCATE only).

All of the above use blocking locks.

## Summary

With blocking locks configured, the only cases in which clients should see an
SQLITE\_BUSY error are:

  * if the OS does not grant a blocking lock before the configured timeout
    expires, and
  * when an open read-transaction is upgraded to a write-transaction.

In all other cases the blocking locks implementation should prevent clients
from having to handle SQLITE\_BUSY errors and facilitate appropriate transfer
of priorities between competing clients.

Clients that lock multiple databases simultaneously must be wary of deadlock.


Changes to ext/async/sqlite3async.c.

1700
1701
1702
1703
1704
1705
1706

1700
1701
1702
1703
1704
1705
1706
1707







+
      break;
  }
  va_end(ap);
  return rc;
}

#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO) */

Changes to ext/async/sqlite3async.h.

216
217
218
219
220
221
222

216
217
218
219
220
221
222
223







+
#define SQLITEASYNC_HALT_NOW   1       /* Halt as soon as possible */
#define SQLITEASYNC_HALT_IDLE  2       /* Halt when write-queue is empty */

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif        /* ifndef __SQLITEASYNC_H_ */

Changes to ext/expert/expert1.test.

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
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39



40
41
42
43
44
45
46







-









-
-
-







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

proc do_setup_rec_test {tn setup sql res} {
  reset_db
  if {[info exists ::set_main_db_name]} {
    dbconfig_maindbname_icecube db
  }
  db eval $setup
  uplevel [list do_rec_test $tn $sql $res]
}

foreach {tn setup} {
  1 {
    if {![file executable $CMD]} { continue }
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
72
73
74
75
76
77
78




79
80
81
82
83
84
85







-
-
-
-







      $expert destroy

      set tst [subst -nocommands {set {} [squish [join {$result}]]}]
      uplevel [list do_test $tn $tst [string trim [squish $res]]]
    }
  }
  3 {
    if {[info commands sqlite3_expert_new]==""} { continue }
    set ::set_main_db_name 1
  }
  4 {
    if {![file executable $CLI]} { continue }

    proc do_rec_test {tn sql res} {
      set res [squish [string trim $res]]
      set tst [subst -nocommands { 
        squish [string trim [exec $::CLI test.db ".expert" {$sql;}]]
      }]
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
130
131
132
133
134
135
136

137
138
139
140
141
142
143

144
145
146
147
148
149
150







-







-







} {
  SELECT a FROM t1 WHERE a=? ORDER BY b;
} {
  CREATE INDEX t1_idx_000123a7 ON t1(a, b);
  SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
}

if 0 {
do_setup_rec_test $tn.6 {
  CREATE TABLE t1(a, b, c);
} {
  SELECT min(a) FROM t1
} {
  CREATE INDEX t1_idx_00000061 ON t1(a);
  SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
}
}

do_setup_rec_test $tn.7 {
  CREATE TABLE t1(a, b, c);
} {
  SELECT * FROM t1 ORDER BY a, b, c;
} {
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

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







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

















-
+









-
+








-
+






-
+



















-

+
} {
  SELECT * FROM t1 WHERE b IS NOT NULL;
} {
  (no new indexes)
  SCAN TABLE t1
}

do_setup_rec_test $tn.17.1 {
  CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
  SELECT * FROM example WHERE a=?
} {
  (no new indexes)
  SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=?)
}
do_setup_rec_test $tn.17.2 {
  CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
  SELECT * FROM example WHERE b=?
} {
  CREATE INDEX example_idx_00000042 ON example(B);
  SEARCH TABLE example USING INDEX example_idx_00000042 (B=?)
}
do_setup_rec_test $tn.17.3 {
  CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
  SELECT * FROM example WHERE a=? AND b=?
} {
  (no new indexes)
  SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=? AND B=?)
}
do_setup_rec_test $tn.17.4 {
  CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
  SELECT * FROM example WHERE a=? AND b>?
} {
  (no new indexes)
  SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=? AND B>?)
}
do_setup_rec_test $tn.17.5 {
  CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
  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
  $expert analyze

  set candidates [squish [string trim [$expert report 0 candidates]]]
  $expert destroy

  uplevel [list do_test $tn [list set {} $candidates] $res]
}


reset_db
do_execsql_test 5.0 {
do_execsql_test 4.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d);

  WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
  INSERT INTO t1 SELECT (i-1)/50, (i-1)/20 FROM s;

  WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
  INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s;
}
do_candidates_test 5.1 {
do_candidates_test 4.1 {
  SELECT * FROM t1,t2 WHERE (b=? OR a=?) AND (c=? OR d=?)
} {
  CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20 
  CREATE INDEX t1_idx_00000061 ON t1(a); -- stat1: 100 50 
  CREATE INDEX t2_idx_00000063 ON t2(c); -- stat1: 100 20 
  CREATE INDEX t2_idx_00000064 ON t2(d); -- stat1: 100 5
}

do_candidates_test 5.2 {
do_candidates_test 4.2 {
  SELECT * FROM t1,t2 WHERE a=? AND b=? AND c=? AND d=?
} {
  CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 17
  CREATE INDEX t2_idx_0001295b ON t2(c, d); -- stat1: 100 20 5
}

do_execsql_test 5.3 {
do_execsql_test 4.3 {
  CREATE INDEX t1_idx_00000061 ON t1(a); -- stat1: 100 50 
  CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20 
  CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 16

  CREATE INDEX t2_idx_00000063 ON t2(c); -- stat1: 100 20 
  CREATE INDEX t2_idx_00000064 ON t2(d); -- stat1: 100 5
  CREATE INDEX t2_idx_0001295b ON t2(c, d); -- stat1: 100 20 5

  ANALYZE;
  SELECT * FROM sqlite_stat1 ORDER BY 1, 2;
} {
  t1 t1_idx_00000061 {100 50} 
  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

finish_test

Changes to ext/expert/sqlite3expert.c.

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







-

-
+








-



















-
+







  sqlite3_stmt *p1 = 0;
  int nCol = 0;
  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);
  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);
    nCol++;
    nPk += (sqlite3_column_int(p1, 5)>0);
  }
  rc2 = sqlite3_reset(p1);
  if( rc==SQLITE_OK ) rc = rc2;

  nByte += sizeof(IdxColumn) * nCol;
  if( rc==SQLITE_OK ){
    pNew = idxMalloc(&rc, nByte);
  }
  if( rc==SQLITE_OK ){
    pNew->aCol = (IdxColumn*)&pNew[1];
    pNew->nCol = nCol;
    pCsr = (char*)&pNew->aCol[nCol];
  }

  nCol = 0;
  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
    int nCopy = STRLEN(zCol) + 1;
    pNew->aCol[nCol].zName = pCsr;
    pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1);
    pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
    memcpy(pCsr, zCol, nCopy);
    pCsr += nCopy;

    rc = sqlite3_table_column_metadata(
        db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
    );
    if( rc==SQLITE_OK ){
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
1124
1125
1126
1127
1128
1129
1130

1131
1132
1133



1134
1135

1136
1137


1138

1139
1140
1141
1142
1143
1144
1145







-
+


-
-
-


-
+

-
-
+
-







        "EXPLAIN QUERY PLAN %s", pStmt->zSql
    );
    while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
      /* int iId = sqlite3_column_int(pExplain, 0); */
      /* int iParent = sqlite3_column_int(pExplain, 1); */
      /* int iNotUsed = sqlite3_column_int(pExplain, 2); */
      const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
      int nDetail;
      int nDetail = STRLEN(zDetail);
      int i;

      if( !zDetail ) continue;
      nDetail = STRLEN(zDetail);

      for(i=0; i<nDetail; i++){
        const char *zIdx = 0;
        if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
        if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
          zIdx = &zDetail[i+13];
        }else if( i+22<nDetail 
            && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 
        }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
        ){
          zIdx = &zDetail[i+22];
        }
        if( zIdx ){
          const char *zSql;
          int nIdx = 0;
          while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){
            nIdx++;
1221
1222
1223
1224
1225
1226
1227
1228

1229
1230
1231
1232
1233
1234
1235
1214
1215
1216
1217
1218
1219
1220

1221
1222
1223
1224
1225
1226
1227
1228







-
+







  char **pzErr
){
  static const char *zInt = UNIQUE_TABLE_NAME;
  static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME;
  IdxTable *pTab = pWrite->pTab;
  const char *zTab = pTab->zName;
  const char *zSql = 
    "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_schema "
    "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master "
    "WHERE tbl_name = %Q AND type IN ('table', 'trigger') "
    "ORDER BY type;";
  sqlite3_stmt *pSelect = 0;
  int rc = SQLITE_OK;
  char *zWrite = 0;

  /* Create the table and its triggers in the temp schema */
1321
1322
1323
1324
1325
1326
1327
1328

1329
1330
1331

1332
1333

1334
1335
1336
1337
1338
1339
1340
1314
1315
1316
1317
1318
1319
1320

1321
1322
1323

1324
1325

1326
1327
1328
1329
1330
1331
1332
1333







-
+


-
+

-
+








  /* For each table in the main db schema:
  **
  **   1) Add an entry to the p->pTable list, and
  **   2) Create the equivalent virtual table in dbv.
  */
  rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
      "SELECT type, name, sql, 1 FROM sqlite_schema "
      "SELECT type, name, sql, 1 FROM sqlite_master "
      "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
      " UNION ALL "
      "SELECT type, name, sql, 2 FROM sqlite_schema "
      "SELECT type, name, sql, 2 FROM sqlite_master "
      "WHERE type = 'trigger'"
      "  AND tbl_name IN(SELECT name FROM sqlite_schema WHERE type = 'view') "
      "  AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') "
      "ORDER BY 4, 1"
  );
  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
    const char *zType = (const char*)sqlite3_column_text(pSchema, 0);
    const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
    const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);

1496
1497
1498
1499
1500
1501
1502
1503

1504
1505
1506
1507
1508
1509
1510
1489
1490
1491
1492
1493
1494
1495

1496
1497
1498
1499
1500
1501
1502
1503







-
+







  }
}

static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){
  int rc = SQLITE_OK;
  const char *zMax = 
    "SELECT max(i.seqno) FROM "
    "  sqlite_schema AS s, "
    "  sqlite_master AS s, "
    "  pragma_index_list(s.name) AS l, "
    "  pragma_index_info(l.name) AS i "
    "WHERE s.type = 'table'";
  sqlite3_stmt *pMax = 0;

  *pnMax = 0;
  rc = idxPrepareStmt(db, &pMax, pzErr, zMax);
1649
1650
1651
1652
1653
1654
1655
1656

1657
1658
1659
1660
1661
1662
1663
1642
1643
1644
1645
1646
1647
1648

1649
1650
1651
1652
1653
1654
1655
1656







-
+







  i64 iPrev = -100000;
  sqlite3_stmt *pAllIndex = 0;
  sqlite3_stmt *pIndexXInfo = 0;
  sqlite3_stmt *pWrite = 0;

  const char *zAllIndex =
    "SELECT s.rowid, s.name, l.name FROM "
    "  sqlite_schema AS s, "
    "  sqlite_master AS s, "
    "  pragma_index_list(s.name) AS l "
    "WHERE s.type = 'table'";
  const char *zIndexXInfo = 
    "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key";
  const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)";

  /* If iSample==0, no sqlite_stat1 data is required. */
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729





1730
1731
1732

1733
1734
1735
1736
1737
1738
1739
1710
1711
1712
1713
1714
1715
1716






1717
1718
1719
1720
1721

1722

1723
1724
1725
1726
1727
1728
1729
1730







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

-
+







    );
  }

  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);
  }
  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);
    rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0);
  }

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

/*
1764
1765
1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777
1778
1755
1756
1757
1758
1759
1760
1761

1762
1763
1764
1765
1766
1767
1768
1769







-
+







  }
  

  /* Copy the entire schema of database [db] into [dbm]. */
  if( rc==SQLITE_OK ){
    sqlite3_stmt *pSql;
    rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, 
        "SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'"
        "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'"
        " AND sql NOT LIKE 'CREATE VIRTUAL %%'"
    );
    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
      const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
      rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
    }
    idxFinalize(&rc, pSql);
1955
1956
1957
1958
1959
1960
1961
1962

1946
1947
1948
1949
1950
1951
1952

1953







-
+
    idxWriteFree(p->pWrite);
    idxHashClear(&p->hIdx);
    sqlite3_free(p->zCandidates);
    sqlite3_free(p);
  }
}

#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */

Changes to ext/expert/sqlite3expert.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14


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


13
14
15
16
17
18
19
20
21












-
-
+
+







/*
** 2017 April 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.
**
*************************************************************************
*/
#if !defined(SQLITEEXPERT_H)
#define SQLITEEXPERT_H 1


#include "sqlite3.h"

typedef struct sqlite3expert sqlite3expert;

/*
** Create a new sqlite3expert object.
**
161
162
163
164
165
166
167
168

161
162
163
164
165
166
167

168







-
+
/*
** Free an (sqlite3expert*) handle and all associated resources. There 
** should be one call to this function for each successful call to 
** sqlite3-expert_new().
*/
void sqlite3_expert_destroy(sqlite3expert*);

#endif  /* !defined(SQLITEEXPERT_H) */

Changes to ext/fts3/README.content.

170
171
172
173
174
175
176


170
171
172
173
174
175
176
177
178







+
+

    INSERT INTO t3(t3) VALUES('rebuild');

  This command may also be used with ordinary FTS4 tables, although it may
  only be useful if the full-text index has somehow become corrupt. It is an
  error to attempt to rebuild the full-text index maintained by a contentless
  FTS4 table.


Changes to ext/fts3/fts3.c.

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







+
+
+
+
+
-
+














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







#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
  v = (v & mask1) | ( (*(const unsigned char*)(ptr++)) << shift );  \
  if( (v & mask2)==0 ){ var = v; return ret; }
#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
  v = (*ptr++);                                               \
  if( (v & mask2)==0 ){ var = v; return ret; }

/* 
** Read a 64-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read, or 0 on error.
** The value is stored in *v.
*/
int sqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){
int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
  const unsigned char *p = (const unsigned char*)pBuf;
  const unsigned char *pStart = p;
  u32 a;
  u64 b;
  int shift;

  GETVARINT_INIT(a, p, 0,  0x00,     0x80, *v, 1);
  GETVARINT_STEP(a, p, 7,  0x7F,     0x4000, *v, 2);
  GETVARINT_STEP(a, p, 14, 0x3FFF,   0x200000, *v, 3);
  GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4);
  b = (a & 0x0FFFFFFF );

  for(shift=28; shift<=63; shift+=7){
    u64 c = *p++;
    b += (c&0x7F) << shift;
    if( (c & 0x80)==0 ) break;
  }
  *v = b;
  return (int)(p - pStart);
}

/* 
** Read a 64-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read, or 0 on error.
** The value is stored in *v.
*/
int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
  return sqlite3Fts3GetVarintU(pBuf, (sqlite3_uint64*)v);
}

/* 
** Read a 64-bit variable-length integer from memory starting at p[0] and
** not extending past pEnd[-1].
** Return the number of bytes read, or 0 on error.
** The value is stored in *v.
*/
int sqlite3Fts3GetVarintBounded(
  const char *pBuf,
  const char *pEnd,
  sqlite_int64 *v
){
  const unsigned char *p = (const unsigned char*)pBuf;
  const unsigned char *pStart = p;
  const unsigned char *pX = (const unsigned char*)pEnd;
  u64 b = 0;
  int shift;
  for(shift=0; shift<=63; shift+=7){
    u64 c = p<pX ? *p : 0;
    p++;
    b += (c&0x7F) << shift;
    if( (c & 0x80)==0 ) break;
  }
  *v = b;
  return (int)(p - pStart);
}

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







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















+

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

+

-
+







  if( p->zLanguageid ){
    fts3Appendf(pRc, &zRet, ", ?");
  }
  sqlite3_free(zFree);
  return zRet;
}

/*
** Buffer z contains a positive integer value encoded as utf-8 text.
** Decode this value and store it in *pnOut, returning the number of bytes
** consumed. If an overflow error occurs return a negative value.
*/
int sqlite3Fts3ReadInt(const char *z, int *pnOut){
  u64 iVal = 0;
  int i;
  for(i=0; z[i]>='0' && z[i]<='9'; i++){
    iVal = iVal*10 + (z[i] - '0');
    if( iVal>0x7FFFFFFF ) return -1;
  }
  *pnOut = (int)iVal;
  return i;
}

/*
** This function interprets the string at (*pp) as a non-negative integer
** value. It reads the integer and sets *pnOut to the value read, then 
** sets *pp to point to the byte immediately following the last byte of
** the integer value.
**
** Only decimal digits ('0'..'9') may be part of an integer value. 
**
** If *pp does not being with a decimal digit SQLITE_ERROR is returned and
** the output value undefined. Otherwise SQLITE_OK is returned.
**
** This function is used when parsing the "prefix=" FTS4 parameter.
*/
static int fts3GobbleInt(const char **pp, int *pnOut){
  const int MAX_NPREFIX = 10000000;
  const char *p;                  /* Iterator pointer */
  int nInt = 0;                   /* Output value */
  int nByte;
  nByte = sqlite3Fts3ReadInt(*pp, &nInt);
  if( nInt>MAX_NPREFIX ){
    nInt = 0;
  }

  for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
    nInt = nInt * 10 + (p[0] - '0');
    if( nInt>MAX_NPREFIX ){
      nInt = 0;
      break;
    }
  if( nByte==0 ){
    return SQLITE_ERROR;
  }
  if( p==*pp ) return SQLITE_ERROR;
  *pnOut = nInt;
  *pp += nByte;
  *pp = p;
  return SQLITE_OK;
}

/*
** This function is called to allocate an array of Fts3Index structures
** representing the indexes maintained by the current FTS table. FTS tables
** always maintain the main "terms" index, but may also maintain one or
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1470
1471
1472
1473
1474
1475
1476




1477
1478
1479
1480
1481
1482
1483







-
-
-
-







  }

  /* Figure out the page-size for the database. This is required in order to
  ** estimate the cost of loading large doclists from the database.  */
  fts3DatabasePageSize(&rc, p);
  p->nNodeSize = p->nPgsz-35;

#if defined(SQLITE_DEBUG)||defined(SQLITE_TEST)
  p->nMergeCount = FTS3_MERGE_COUNT;
#endif

  /* Declare the table schema to SQLite. */
  fts3DeclareVtab(&rc, p);

fts3_init_out:
  sqlite3_free(zPrefix);
  sqlite3_free(aIndex);
  sqlite3_free(zCompress);
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1565
1566
1567
1568
1569
1570
1571




1572
1573
1574
1575
1576
1577
1578







-
-
-
-







  int iCons = -1;                 /* Index of constraint to use */

  int iLangidCons = -1;           /* Index of langid=x constraint, if present */
  int iDocidGe = -1;              /* Index of docid>=x constraint, if present */
  int iDocidLe = -1;              /* Index of docid<=x constraint, if present */
  int iIdx;

  if( p->bLock ){
    return SQLITE_ERROR;
  }

  /* By default use a full table scan. This is an expensive option,
  ** so search through the constraints to see if a more efficient 
  ** strategy is possible.
  */
  pInfo->idxNum = FTS3_FULLSCAN_SEARCH;
  pInfo->estimatedCost = 5000000;
  for(i=0; i<pInfo->nConstraint; i++){
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
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







-
-
-
+
-
-

















-
-



-


-







    char *zSql;
    if( p->pSeekStmt ){
      pCsr->pStmt = p->pSeekStmt;
      p->pSeekStmt = 0;
    }else{
      zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
      if( !zSql ) return SQLITE_NOMEM;
      p->bLock++;
      rc = sqlite3_prepare_v3(
          p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0
      rc = sqlite3_prepare_v3(p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0);
      );
      p->bLock--;
      sqlite3_free(zSql);
    }
    if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
  }
  return rc;
}

/*
** Position the pCsr->pStmt statement so that it is on the row
** of the %_content table that contains the last match.  Return
** SQLITE_OK on success.  
*/
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
  int rc = SQLITE_OK;
  if( pCsr->isRequireSeek ){
    rc = fts3CursorSeekStmt(pCsr);
    if( rc==SQLITE_OK ){
      Fts3Table *pTab = (Fts3Table*)pCsr->base.pVtab;
      pTab->bLock++;
      sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
      pCsr->isRequireSeek = 0;
      if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
        pTab->bLock--;
        return SQLITE_OK;
      }else{
        pTab->bLock--;
        rc = sqlite3_reset(pCsr->pStmt);
        if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){
          /* If no row was found and no error has occurred, then the %_content
          ** table is missing a row that is present in the full-text index.
          ** The data structures are corrupt.  */
          rc = FTS_CORRUPT_VTAB;
          pCsr->isEof = 1;
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1834
1835
1836
1837
1838
1839
1840

1841
1842
1843
1844
1845
1846
1847







-







  int rc = SQLITE_OK;             /* Return code */
  const char *zCsr = zNode;       /* Cursor to iterate through node */
  const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
  char *zBuffer = 0;              /* Buffer to load terms into */
  i64 nAlloc = 0;                 /* Size of allocated buffer */
  int isFirstTerm = 1;            /* True when processing first term on page */
  sqlite3_int64 iChild;           /* Block id of child node to descend to */
  int nBuffer = 0;                /* Total term size */

  /* Skip over the 'height' varint that occurs at the start of every 
  ** interior node. Then load the blockid of the left-child of the b-tree
  ** node into variable iChild.  
  **
  ** Even if the data structure on disk is corrupted, this (reading two
  ** varints from the buffer) does not risk an overread. If zNode is a
1919
1920
1921
1922
1923
1924
1925

1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870




1871
1872
1873
1874
1875
1876
1877







+





-
-
-
-







    return FTS_CORRUPT_VTAB;
  }
  
  while( zCsr<zEnd && (piFirst || piLast) ){
    int cmp;                      /* memcmp() result */
    int nSuffix;                  /* Size of term suffix */
    int nPrefix = 0;              /* Size of term prefix */
    int nBuffer;                  /* Total term size */
  
    /* Load the next term on the node into zBuffer. Use realloc() to expand
    ** the size of zBuffer if required.  */
    if( !isFirstTerm ){
      zCsr += fts3GetVarint32(zCsr, &nPrefix);
      if( nPrefix>nBuffer ){
        rc = FTS_CORRUPT_VTAB;
        goto finish_scan;
      }
    }
    isFirstTerm = 0;
    zCsr += fts3GetVarint32(zCsr, &nSuffix);
    
    assert( nPrefix>=0 && nSuffix>=0 );
    if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr || nSuffix==0 ){
      rc = FTS_CORRUPT_VTAB;
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
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







-
+



















-
-
-
-
-
-
+
-
















-
+







  int rc = SQLITE_OK;             /* Return code */
  int iHeight;                    /* Height of this node in tree */

  assert( piLeaf || piLeaf2 );

  fts3GetVarint32(zNode, &iHeight);
  rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2);
  assert_fts3_nc( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) );
  assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) );

  if( rc==SQLITE_OK && iHeight>1 ){
    char *zBlob = 0;              /* Blob read from %_segments table */
    int nBlob = 0;                /* Size of zBlob in bytes */

    if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){
      rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0);
      if( rc==SQLITE_OK ){
        rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0);
      }
      sqlite3_free(zBlob);
      piLeaf = 0;
      zBlob = 0;
    }

    if( rc==SQLITE_OK ){
      rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0);
    }
    if( rc==SQLITE_OK ){
      int iNewHeight = 0;
      fts3GetVarint32(zBlob, &iNewHeight);
      if( iNewHeight>=iHeight ){
        rc = FTS_CORRUPT_VTAB;
      }else{
        rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2);
      rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2);
      }
    }
    sqlite3_free(zBlob);
  }

  return rc;
}

/*
** This function is used to create delta-encoded serialized lists of FTS3 
** varints. Each call to this function appends a single varint to a list.
*/
static void fts3PutDeltaVarint(
  char **pp,                      /* IN/OUT: Output pointer */
  sqlite3_int64 *piPrev,          /* IN/OUT: Previous value written to list */
  sqlite3_int64 iVal              /* Write this value to the list */
){
  assert_fts3_nc( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) );
  assert( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) );
  *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev);
  *piPrev = iVal;
}

/*
** When this function is called, *ppPoslist is assumed to point to the 
** start of a position-list. After it returns, *ppPoslist points to the
2152
2153
2154
2155
2156
2157
2158
2159
2160


2161
2162
2163

2164
2165
2166
2167
2168
2169
2170
2082
2083
2084
2085
2086
2087
2088


2089
2090

2091

2092
2093
2094
2095
2096
2097
2098
2099







-
-
+
+
-

-
+







    p += n;
    *pp = p;
  }
  *ppPoslist = pEnd;
}

/*
** Value used to signify the end of an position-list. This must be
** as large or larger than any value that might appear on the
** Value used to signify the end of an position-list. This is safe because
** it is not possible to have a document with 2^31 terms.
** position-list, even a position list that has been corrupted.
*/
#define POSITION_LIST_END LARGEST_INT64
#define POSITION_LIST_END 0x7fffffff

/*
** This function is used to help parse position-lists. When this function is
** called, *pp may point to the start of the next varint in the position-list
** being parsed, or it may point to 1 byte past the end of the position-list
** (in which case **pp will be a terminator bytes POS_END (0) or
** (1)).
2181
2182
2183
2184
2185
2186
2187
2188
2189

2190
2191
2192
2193
2194
2195
2196
2197
2110
2111
2112
2113
2114
2115
2116


2117

2118
2119
2120
2121
2122
2123
2124







-
-
+
-







** the next position.
*/
static void fts3ReadNextPos(
  char **pp,                    /* IN/OUT: Pointer into position-list buffer */
  sqlite3_int64 *pi             /* IN/OUT: Value read from position-list */
){
  if( (**pp)&0xFE ){
    int iVal;
    *pp += fts3GetVarint32((*pp), &iVal);
    fts3GetDeltaVarint(pp, pi);
    *pi += iVal;
    *pi -= 2;
  }else{
    *pi = POSITION_LIST_END;
  }
}

/*
2234
2235
2236
2237
2238
2239
2240
2241

2242
2243
2244
2245
2246
2247
2248

2249
2250
2251
2252
2253
2254
2255
2161
2162
2163
2164
2165
2166
2167

2168
2169
2170
2171
2172
2173
2174

2175
2176
2177
2178
2179
2180
2181
2182







-
+






-
+







    int iCol1;         /* The current column index in pp1 */
    int iCol2;         /* The current column index in pp2 */

    if( *p1==POS_COLUMN ){ 
      fts3GetVarint32(&p1[1], &iCol1);
      if( iCol1==0 ) return FTS_CORRUPT_VTAB;
    }
    else if( *p1==POS_END ) iCol1 = 0x7fffffff;
    else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
    else iCol1 = 0;

    if( *p2==POS_COLUMN ){
      fts3GetVarint32(&p2[1], &iCol2);
      if( iCol2==0 ) return FTS_CORRUPT_VTAB;
    }
    else if( *p2==POS_END ) iCol2 = 0x7fffffff;
    else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
    else iCol2 = 0;

    if( iCol1==iCol2 ){
      sqlite3_int64 i1 = 0;       /* Last position from pp1 */
      sqlite3_int64 i2 = 0;       /* Last position from pp2 */
      sqlite3_int64 iPrev = 0;
      int n = fts3PutColNumber(&p, iCol1);
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2190
2191
2192
2193
2194
2195
2196



2197
2198
2199
2200
2201
2202
2203







-
-
-







      ** POS_END (0) or POS_COLUMN (1). The following block merges the two lists
      ** and writes the results to buffer p. p is left pointing to the byte
      ** after the list written. No terminator (POS_END or POS_COLUMN) is
      ** written to the output.
      */
      fts3GetDeltaVarint(&p1, &i1);
      fts3GetDeltaVarint(&p2, &i2);
      if( i1<2 || i2<2 ){
        break;
      }
      do {
        fts3PutDeltaVarint(&p, &iPrev, (i1<i2) ? i1 : i2); 
        iPrev -= 2;
        if( i1==i2 ){
          fts3ReadNextPos(&p1, &i1);
          fts3ReadNextPos(&p2, &i2);
        }else if( i1<i2 ){
2334
2335
2336
2337
2338
2339
2340
2341

2342
2343
2344
2345
2346
2347
2348
2258
2259
2260
2261
2262
2263
2264

2265
2266
2267
2268
2269
2270
2271
2272







-
+







  char *p2 = *pp2;
  int iCol1 = 0;
  int iCol2 = 0;

  /* Never set both isSaveLeft and isExact for the same invocation. */
  assert( isSaveLeft==0 || isExact==0 );

  assert_fts3_nc( p!=0 && *p1!=0 && *p2!=0 );
  assert( p!=0 && *p1!=0 && *p2!=0 );
  if( *p1==POS_COLUMN ){ 
    p1++;
    p1 += fts3GetVarint32(p1, &iCol1);
  }
  if( *p2==POS_COLUMN ){ 
    p2++;
    p2 += fts3GetVarint32(p2, &iCol2);
2507
2508
2509
2510
2511
2512
2513
2514
2515


2516
2517

2518
2519

2520
2521
2522
2523
2524
2525
2526
2431
2432
2433
2434
2435
2436
2437


2438
2439
2440

2441
2442

2443
2444
2445
2446
2447
2448
2449
2450







-
-
+
+

-
+

-
+







  char *pEnd,                     /* End of buffer */
  int bDescIdx,                   /* True if docids are descending */
  sqlite3_int64 *pVal             /* IN/OUT: Integer value */
){
  if( *pp>=pEnd ){
    *pp = 0;
  }else{
    u64 iVal;
    *pp += sqlite3Fts3GetVarintU(*pp, &iVal);
    sqlite3_int64 iVal;
    *pp += sqlite3Fts3GetVarint(*pp, &iVal);
    if( bDescIdx ){
      *pVal = (i64)((u64)*pVal - iVal);
      *pVal -= iVal;
    }else{
      *pVal = (i64)((u64)*pVal + iVal);
      *pVal += iVal;
    }
  }
}

/*
** This function is used to write a single varint to a buffer. The varint
** is written to *pp. Before returning, *pp is set to point 1 byte past the
2539
2540
2541
2542
2543
2544
2545
2546

2547
2548
2549

2550
2551
2552

2553
2554
2555

2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572

2573
2574
2575
2576
2577
2578
2579
2463
2464
2465
2466
2467
2468
2469

2470
2471


2472
2473


2474
2475
2476

2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492


2493
2494
2495
2496
2497
2498
2499
2500







-
+

-
-
+

-
-
+


-
+















-
-
+







static void fts3PutDeltaVarint3(
  char **pp,                      /* IN/OUT: Output pointer */
  int bDescIdx,                   /* True for descending docids */
  sqlite3_int64 *piPrev,          /* IN/OUT: Previous value written to list */
  int *pbFirst,                   /* IN/OUT: True after first int written */
  sqlite3_int64 iVal              /* Write this value to the list */
){
  sqlite3_uint64 iWrite;
  sqlite3_int64 iWrite;
  if( bDescIdx==0 || *pbFirst==0 ){
    assert_fts3_nc( *pbFirst==0 || iVal>=*piPrev );
    iWrite = (u64)iVal - (u64)*piPrev;
    iWrite = iVal - *piPrev;
  }else{
    assert_fts3_nc( *piPrev>=iVal );
    iWrite = (u64)*piPrev - (u64)iVal;
    iWrite = *piPrev - iVal;
  }
  assert( *pbFirst || *piPrev==0 );
  assert_fts3_nc( *pbFirst==0 || iWrite>0 );
  assert( *pbFirst==0 || iWrite>0 );
  *pp += sqlite3Fts3PutVarint(*pp, iWrite);
  *piPrev = iVal;
  *pbFirst = 1;
}


/*
** This macro is used by various functions that merge doclists. The two
** arguments are 64-bit docid values. If the value of the stack variable
** bDescDoclist is 0 when this macro is invoked, then it returns (i1-i2). 
** Otherwise, (i2-i1).
**
** Using this makes it easier to write code that can merge doclists that are
** sorted in either ascending or descending order.
*/
/* #define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i64)((u64)i1-i2)) */
#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1>i2?1:((i1==i2)?0:-1)))
#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1-i2))

/*
** This function does an "OR" merge of two doclists (output contains all
** positions contained in either argument doclist). If the docids in the 
** input doclists are sorted in ascending order, parameter bDescDoclist
** should be false. If they are sorted in ascending order, it should be
** passed a non-zero value.
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2576
2577
2578
2579
2580
2581
2582


2583
2584
2585
2586
2587
2588
2589







-
-







      fts3PoslistCopy(&p, &p1);
      fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
    }else{
      fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2);
      fts3PoslistCopy(&p, &p2);
      fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
    }
    
    assert( (p-aOut)<=((p1?(p1-a1):n1)+(p2?(p2-a2):n2)+FTS3_VARINT_MAX-1) );
  }

  if( rc!=SQLITE_OK ){
    sqlite3_free(aOut);
    p = aOut = 0;
  }else{
    assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 );
2979
2980
2981
2982
2983
2984
2985
2986

2987
2988
2989
2990
2991
2992
2993
2898
2899
2900
2901
2902
2903
2904

2905
2906
2907
2908
2909
2910
2911
2912







-
+








  /* If iLevel is less than 0 and this is not a scan, include a seg-reader 
  ** for the pending-terms. If this is a scan, then this call must be being
  ** made by an fts4aux module, not an FTS table. In this case calling
  ** Fts3SegReaderPending might segfault, as the data structures used by 
  ** fts4aux are not completely populated. So it's easiest to filter these
  ** calls out here.  */
  if( iLevel<0 && p->aIndex && p->iPrevLangid==iLangid ){
  if( iLevel<0 && p->aIndex ){
    Fts3SegReader *pSeg = 0;
    rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
    if( rc==SQLITE_OK && pSeg ){
      rc = fts3SegReaderCursorAppend(pCsr, pSeg);
    }
  }

3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265












3266
3267
3268
3269
3270
3271
3272
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







-
-







-







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







** even if we reach end-of-file.  The fts3EofMethod() will be called
** subsequently to determine whether or not an EOF was hit.
*/
static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){
  int rc;
  Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
  if( pCsr->eSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){
    Fts3Table *pTab = (Fts3Table*)pCursor->pVtab;
    pTab->bLock++;
    if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){
      pCsr->isEof = 1;
      rc = sqlite3_reset(pCsr->pStmt);
    }else{
      pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0);
      rc = SQLITE_OK;
    }
    pTab->bLock--;
  }else{
    rc = fts3EvalNext((Fts3Cursor *)pCursor);
  }
  assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
  return rc;
}

/*
** The following are copied from sqliteInt.h.
**
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#ifndef SQLITE_AMALGAMATION
# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
#endif

/*
** If the numeric type of argument pVal is "integer", then return it
** converted to a 64-bit signed integer. Otherwise, return a copy of
** the second parameter, iDefault.
*/
static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){
  if( pVal ){
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3240
3241
3242
3243
3244
3245
3246




3247
3248
3249
3250
3251
3252
3253







-
-
-
-







  sqlite3_value *pDocidGe = 0;    /* The "docid >= ?" constraint, if any */
  sqlite3_value *pDocidLe = 0;    /* The "docid <= ?" constraint, if any */
  int iIdx;

  UNUSED_PARAMETER(idxStr);
  UNUSED_PARAMETER(nVal);

  if( p->bLock ){
    return SQLITE_ERROR;
  }

  eSearch = (idxNum & 0x0000FFFF);
  assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) );
  assert( p->pSegments==0 );

  /* Collect arguments into local variables */
  iIdx = 0;
  if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++];
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396

3397
3398
3399
3400
3401
3402
3403
3404
3405
3311
3312
3313
3314
3315
3316
3317



3318


3319
3320
3321
3322
3323
3324
3325







-
-
-
+
-
-







      );
    }else{
      zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", 
          p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
      );
    }
    if( zSql ){
      p->bLock++;
      rc = sqlite3_prepare_v3(
          p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0
      rc = sqlite3_prepare_v3(p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0);
      );
      p->bLock--;
      sqlite3_free(zSql);
    }else{
      rc = SQLITE_NOMEM;
    }
  }else if( eSearch==FTS3_DOCID_SEARCH ){
    rc = fts3CursorSeekStmt(pCsr);
    if( rc==SQLITE_OK ){
3475
3476
3477
3478
3479
3480
3481
3482

3483
3484
3485
3486
3487
3488
3489
3395
3396
3397
3398
3399
3400
3401

3402
3403
3404
3405
3406
3407
3408
3409







-
+







        sqlite3_result_int64(pCtx, pCsr->iLangid);
        break;
      }else if( p->zLanguageid==0 ){
        sqlite3_result_int(pCtx, 0);
        break;
      }else{
        iCol = p->nColumn;
        /* no break */ deliberate_fall_through
        /* fall-through */
      }

    default:
      /* A user column. Or, if this is a full-table scan, possibly the
      ** language-id column. Seek the cursor. */
      rc = fts3CursorSeek(0, pCsr);
      if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3638
3639
3640
3641
3642
3643
3644

3645

3646

3647

3648
3649
3650
3651
3652
3653
3654







-

-

-

-







        "wrong number of arguments to function snippet()", -1);
    return;
  }
  if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return;

  switch( nVal ){
    case 6: nToken = sqlite3_value_int(apVal[5]);
            /* no break */ deliberate_fall_through
    case 5: iCol = sqlite3_value_int(apVal[4]);
            /* no break */ deliberate_fall_through
    case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]);
            /* no break */ deliberate_fall_through
    case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]);
            /* no break */ deliberate_fall_through
    case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
  }
  if( !zEllipsis || !zEnd || !zStart ){
    sqlite3_result_error_nomem(pContext);
  }else if( nToken==0 ){
    sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
  }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
4412
4413
4414
4415
4416
4417
4418
4419

4420
4421
4422
4423
4424
4425
4426
4328
4329
4330
4331
4332
4333
4334

4335
4336
4337
4338
4339
4340
4341
4342







-
+







  ** scanned in forward order, and the phrase consists of 
  ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first"
  ** tokens or prefix tokens that cannot use a prefix-index.  */
  int bHaveIncr = 0;
  int bIncrOk = (bOptOk 
   && pCsr->bDesc==pTab->bDescIdx 
   && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
#ifdef SQLITE_TEST
   && pTab->bNoIncrDoclist==0
#endif
  );
  for(i=0; bIncrOk==1 && i<p->nToken; i++){
    Fts3PhraseToken *pToken = &p->aToken[i];
    if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){
      bIncrOk = 0;
4523
4524
4525
4526
4527
4528
4529
4530

4531
4532
4533
4534
4535
4536
4537
4439
4440
4441
4442
4443
4444
4445

4446
4447
4448
4449
4450
4451
4452
4453







-
+







  sqlite3_int64 *piDocid,         /* IN/OUT: Docid pointer */
  u8 *pbEof                       /* OUT: End-of-file flag */
){
  char *p = *ppIter;

  assert( nDoclist>0 );
  assert( *pbEof==0 );
  assert_fts3_nc( p || *piDocid==0 );
  assert( p || *piDocid==0 );
  assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) );

  if( p==0 ){
    p = aDoclist;
    p += sqlite3Fts3GetVarint(p, piDocid);
  }else{
    fts3PoslistCopy(0, &p);
4554
4555
4556
4557
4558
4559
4560
4561

4562
4563
4564
4565
4566
4567
4568
4569
4570

4571
4572
4573
4574
4575
4576
4577
4470
4471
4472
4473
4474
4475
4476

4477
4478
4479
4480

4481
4482
4483
4484

4485
4486
4487
4488
4489
4490
4491
4492







-
+



-




-
+







*/
static void fts3EvalDlPhraseNext(
  Fts3Table *pTab,
  Fts3Doclist *pDL,
  u8 *pbEof
){
  char *pIter;                            /* Used to iterate through aAll */
  char *pEnd;                             /* 1 byte past end of aAll */
  char *pEnd = &pDL->aAll[pDL->nAll];     /* 1 byte past end of aAll */
 
  if( pDL->pNextDocid ){
    pIter = pDL->pNextDocid;
    assert( pDL->aAll!=0 || pIter==0 );
  }else{
    pIter = pDL->aAll;
  }

  if( pIter==0 || pIter>=(pEnd = pDL->aAll + pDL->nAll) ){
  if( pIter>=pEnd ){
    /* We have already reached the end of this doclist. EOF. */
    *pbEof = 1;
  }else{
    sqlite3_int64 iDelta;
    pIter += sqlite3Fts3GetVarint(pIter, &iDelta);
    if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){
      pDL->iDocid += iDelta;
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947






4948
4949
4950
4951
4952
4953
4954
4955
4850
4851
4852
4853
4854
4855
4856






4857
4858
4859
4860
4861
4862

4863
4864
4865
4866
4867
4868
4869







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







    sqlite3_int64 nByte = 0;
    const char *pEnd;
    const char *a;

    rc = sqlite3Fts3SelectDoctotal(p, &pStmt);
    if( rc!=SQLITE_OK ) return rc;
    a = sqlite3_column_blob(pStmt, 0);
    testcase( a==0 );  /* If %_stat.value set to X'' */
    if( a ){
      pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
      a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc);
      while( a<pEnd ){
        a += sqlite3Fts3GetVarintBounded(a, pEnd, &nByte);
    assert( a );

    pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
    a += sqlite3Fts3GetVarint(a, &nDoc);
    while( a<pEnd ){
      a += sqlite3Fts3GetVarint(a, &nByte);
      }
    }
    if( nDoc==0 || nByte==0 ){
      sqlite3_reset(pStmt);
      return FTS_CORRUPT_VTAB;
    }

    pCsr->nDoc = nDoc;
5173
5174
5175
5176
5177
5178
5179
5180

5181
5182
5183
5184
5185
5186
5187
5087
5088
5089
5090
5091
5092
5093

5094
5095
5096
5097
5098
5099
5100
5101







-
+







** the phrase object passed as the fifth argument according to a NEAR
** condition. For example:
**
**     abc NEAR/5 "def ghi"
**
** Parameter nNear is passed the NEAR distance of the expression (5 in
** the example above). When this function is called, *paPoslist points to
** the position list, and *pnToken is the number of phrase tokens in the
** the position list, and *pnToken is the number of phrase tokens in, the
** phrase on the other side of the NEAR operator to pPhrase. For example,
** if pPhrase refers to the "def ghi" phrase, then *paPoslist points to
** the position list associated with phrase "abc".
**
** All positions in the pPhrase position list that are not sufficiently
** close to a position in the *paPoslist position list are removed. If this
** leaves 0 positions, zero is returned. Otherwise, non-zero.
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219




5220
5221
5222
5223
5224
5225
5226
5227
5122
5123
5124
5125
5126
5127
5128





5129
5130
5131
5132

5133
5134
5135
5136
5137
5138
5139







-
-
-
-
-
+
+
+
+
-








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

  return res;
}

5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5234
5235
5236
5237
5238
5239
5240

5241
5242
5243
5244
5245
5246
5247







-







            if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){
              Fts3Doclist *pDl = &pLeft->pPhrase->doclist;
              while( *pRc==SQLITE_OK && pLeft->bEof==0 ){
                memset(pDl->pList, 0, pDl->nList);
                fts3EvalNextRow(pCsr, pLeft, pRc);
              }
            }
            pRight->bEof = pLeft->bEof = 1;
          }
        }
        break;
      }
  
      case FTSQUERY_OR: {
        Fts3Expr *pLeft = pExpr->pLeft;
5565
5566
5567
5568
5569
5570
5571
5572
5573

5574
5575
5576
5577
5578
5579
5580
5581
5582
5476
5477
5478
5479
5480
5481
5482


5483


5484
5485
5486
5487
5488
5489
5490







-
-
+
-
-







          }
          *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase);
          bHit = (pPhrase->doclist.pList!=0);
          pExpr->iDocid = pCsr->iPrevId;
        }else
#endif
        {
          bHit = ( 
              pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId
          bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId);
           && pExpr->pPhrase->doclist.nList>0
          );
        }
        break;
      }
    }
  }
  return bHit;
}
5831
5832
5833
5834
5835
5836
5837
5838

5839
5840
5841
5842
5843
5844
5845
5846
5739
5740
5741
5742
5743
5744
5745

5746

5747
5748
5749
5750
5751
5752
5753







-
+
-







      ** do loop can not be written:
      **
      **   do {...} while( pRoot->iDocid<iDocid && rc==SQLITE_OK );
      */
      fts3EvalRestart(pCsr, pRoot, &rc);
      do {
        fts3EvalNextRow(pCsr, pRoot, &rc);
        assert_fts3_nc( pRoot->bEof==0 );
        assert( pRoot->bEof==0 );
        if( pRoot->bEof ) rc = FTS_CORRUPT_VTAB;
      }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );
    }
  }
  return rc;
}

/*

Changes to ext/fts3/fts3Int.h.

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
192
193
194
195
196
197
198





199
200
201
202
203
204
205







-
-
-
-
-







*/
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
# define TESTONLY(X)  X
#else
# define TESTONLY(X)
#endif

#define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)

#define deliberate_fall_through

#endif /* SQLITE_AMALGAMATION */

#ifdef SQLITE_DEBUG
int sqlite3Fts3Corrupt(void);
# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt()
#else
# define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
235
236
237
238
239
240
241

242
243
244
245
246
247
248







-







  char **azColumn;                /* column names.  malloced */
  u8 *abNotindexed;               /* True for 'notindexed' columns */
  sqlite3_tokenizer *pTokenizer;  /* tokenizer for inserts and queries */
  char *zContentTbl;              /* content=xxx option, or NULL */
  char *zLanguageid;              /* languageid=xxx option, or NULL */
  int nAutoincrmerge;             /* Value configured by 'automerge' */
  u32 nLeafAdd;                   /* Number of leaf blocks added this trans */
  int bLock;                      /* Used to prevent recursive content= tbls */

  /* Precompiled statements used by the implementation. Each of these 
  ** statements is run and reset within a single virtual table API call. 
  */
  sqlite3_stmt *aStmt[40];
  sqlite3_stmt *pSeekStmt;        /* Cache for fts3CursorSeekStmt() */

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
293
294
295
296
297
298
299

300
301
302
303



304
305
306







307
308
309
310
311
312
313







-
+



-
-
-



-
-
-
-
-
-
-







  ** values do not contribute to FTS functionality; they are used for
  ** verifying the operation of the SQLite core.
  */
  int inTransaction;     /* True after xBegin but before xCommit/xRollback */
  int mxSavepoint;       /* Largest valid xSavepoint integer */
#endif

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
#ifdef SQLITE_TEST
  /* True to disable the incremental doclist optimization. This is controled
  ** by special insert command 'test-no-incr-doclist'.  */
  int bNoIncrDoclist;

  /* Number of segments in a level */
  int nMergeCount;
#endif
};

/* Macro to find the number of segments to merge */
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# define MergeCount(P) ((P)->nMergeCount)
#else
# define MergeCount(P) FTS3_MERGE_COUNT
#endif

/*
** When the core wants to read from the virtual table, it creates a
** virtual table cursor (an instance of the following structure) using
** the xOpen method. Cursors are destroyed using the xClose method.
*/
struct Fts3Cursor {
  sqlite3_vtab_cursor base;       /* Base class used by SQLite core */
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
563
564
565
566
567
568
569


570
571
572
573
574
575
576
577

578
579
580
581
582
583
584







-
-








-







  (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \
)

/* fts3.c */
void sqlite3Fts3ErrMsg(char**,const char*,...);
int sqlite3Fts3PutVarint(char *, sqlite3_int64);
int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
int sqlite3Fts3GetVarintU(const char *, sqlite_uint64 *);
int sqlite3Fts3GetVarintBounded(const char*,const char*,sqlite3_int64*);
int sqlite3Fts3GetVarint32(const char *, int *);
int sqlite3Fts3VarintLen(sqlite3_uint64);
void sqlite3Fts3Dequote(char *);
void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
int sqlite3Fts3ReadInt(const char *z, int *pnOut);

/* fts3_tokenizer.c */
const char *sqlite3Fts3NextToken(const char *, int *);
int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, 
    sqlite3_tokenizer **, char **
);

Changes to ext/fts3/fts3_expr.c.

442
443
444
445
446
447
448


449


450
451
452
453
454
455
456
442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
459







+
+
-
+
+







      int nKey = pKey->n;
      char cNext;

      /* If this is a "NEAR" keyword, check for an explicit nearness. */
      if( pKey->eType==FTSQUERY_NEAR ){
        assert( nKey==4 );
        if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
          nNear = 0;
          for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){
          nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear);
            nNear = nNear * 10 + (zInput[nKey] - '0');
          }
        }
      }

      /* At this point this is probably a keyword. But for that to be true,
      ** the next byte must contain either whitespace, an open or close
      ** parenthesis, a quote character, or EOF. 
      */
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
492
493
494
495
496
497
498





499
500
501
502
503
504
505







-
-
-
-
-







    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_snippet.c.

429
430
431
432
433
434
435
436

437
438
439

440
441
442
443
444
445
446
429
430
431
432
433
434
435

436
437
438

439
440
441
442
443
444
445
446







-
+


-
+







    SnippetPhrase *pPhrase = &pIter->aPhrase[i];
    if( pPhrase->pTail ){
      char *pCsr = pPhrase->pTail;
      int iCsr = pPhrase->iTail;

      while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){
        int j;
        u64 mPhrase = (u64)1 << (i%64);
        u64 mPhrase = (u64)1 << i;
        u64 mPos = (u64)1 << (iCsr - iStart);
        assert( iCsr>=iStart && (iCsr - iStart)<=64 );
        assert( i>=0 );
        assert( i>=0 && i<=64 );
        if( (mCover|mCovered)&mPhrase ){
          iScore++;
        }else{
          iScore += 1000;
        }
        mCover |= mPhrase;

556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570







-
+







  sIter.iCurrent = -1;
  rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter);
  if( rc==SQLITE_OK ){

    /* Set the *pmSeen output variable. */
    for(i=0; i<nList; i++){
      if( sIter.aPhrase[i].pHead ){
        *pmSeen |= (u64)1 << (i%64);
        *pmSeen |= (u64)1 << i;
      }
    }

    /* Loop through all candidate snippets. Store the best snippet in 
     ** *pFragment. Store its associated 'score' in iBestScore.
     */
    pFragment->iCol = iCol;
872
873
874
875
876
877
878
879

880
881
882
883
884
885
886
872
873
874
875
876
877
878

879
880
881
882
883
884
885
886







-
+







  assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS );
  if( p->flag==FTS3_MATCHINFO_LHITS ){
    iStart = pExpr->iPhrase * p->nCol;
  }else{
    iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
  }

  if( pIter ) while( 1 ){
  while( 1 ){
    int nHit = fts3ColumnlistCount(&pIter);
    if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
      if( p->flag==FTS3_MATCHINFO_LHITS ){
        p->aMatchinfo[iStart + iCol] = (u32)nHit;
      }else if( nHit ){
        p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F));
      }
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
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







-
+
-



-

-
-








-

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


-







  return nVal;
}

static int fts3MatchinfoSelectDoctotal(
  Fts3Table *pTab,
  sqlite3_stmt **ppStmt,
  sqlite3_int64 *pnDoc,
  const char **paLen,
  const char **paLen
  const char **ppEnd
){
  sqlite3_stmt *pStmt;
  const char *a;
  const char *pEnd;
  sqlite3_int64 nDoc;
  int n;


  if( !*ppStmt ){
    int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt);
    if( rc!=SQLITE_OK ) return rc;
  }
  pStmt = *ppStmt;
  assert( sqlite3_data_count(pStmt)==1 );

  n = sqlite3_column_bytes(pStmt, 0);
  a = sqlite3_column_blob(pStmt, 0);
  if( a==0 ){
    return FTS_CORRUPT_VTAB;
  }
  pEnd = a + n;
  a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc);
  a += sqlite3Fts3GetVarint(a, &nDoc);
  if( nDoc<=0 || a>pEnd ){
    return FTS_CORRUPT_VTAB;
  if( nDoc==0 ) return FTS_CORRUPT_VTAB;
  }
  *pnDoc = nDoc;
  *pnDoc = (u32)nDoc;

  if( paLen ) *paLen = a;
  if( ppEnd ) *ppEnd = pEnd;
  return SQLITE_OK;
}

/*
** An instance of the following structure is used to store state while 
** iterating through a multi-column position-list corresponding to the
** hits for a single phrase on a single row in order to calculate the
1245
1246
1247
1248
1249
1250
1251
1252

1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263

1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
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







-
+








-

-
+






-
-
-
-













-


-
+
-
-
-
-







      case FTS3_MATCHINFO_NCOL:
        if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol;
        break;
        
      case FTS3_MATCHINFO_NDOC:
        if( bGlobal ){
          sqlite3_int64 nDoc = 0;
          rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0, 0);
          rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0);
          pInfo->aMatchinfo[0] = (u32)nDoc;
        }
        break;

      case FTS3_MATCHINFO_AVGLENGTH: 
        if( bGlobal ){
          sqlite3_int64 nDoc;     /* Number of rows in table */
          const char *a;          /* Aggregate column length array */
          const char *pEnd;       /* First byte past end of length array */

          rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a, &pEnd);
          rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a);
          if( rc==SQLITE_OK ){
            int iCol;
            for(iCol=0; iCol<pInfo->nCol; iCol++){
              u32 iVal;
              sqlite3_int64 nToken;
              a += sqlite3Fts3GetVarint(a, &nToken);
              if( a>pEnd ){
                rc = SQLITE_CORRUPT_VTAB;
                break;
              }
              iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc);
              pInfo->aMatchinfo[iCol] = iVal;
            }
          }
        }
        break;

      case FTS3_MATCHINFO_LENGTH: {
        sqlite3_stmt *pSelectDocsize = 0;
        rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize);
        if( rc==SQLITE_OK ){
          int iCol;
          const char *a = sqlite3_column_blob(pSelectDocsize, 0);
          const char *pEnd = a + sqlite3_column_bytes(pSelectDocsize, 0);
          for(iCol=0; iCol<pInfo->nCol; iCol++){
            sqlite3_int64 nToken;
            a += sqlite3Fts3GetVarintBounded(a, pEnd, &nToken);
            a += sqlite3Fts3GetVarint(a, &nToken);
            if( a>pEnd ){
              rc = SQLITE_CORRUPT_VTAB;
              break;
            }
            pInfo->aMatchinfo[iCol] = (u32)nToken;
          }
        }
        sqlite3_reset(pSelectDocsize);
        break;
      }

1318
1319
1320
1321
1322
1323
1324
1325

1326
1327
1328
1329
1330
1331
1332
1296
1297
1298
1299
1300
1301
1302

1303
1304
1305
1306
1307
1308
1309
1310







-
+







        Fts3Expr *pExpr;
        assert( zArg[i]==FTS3_MATCHINFO_HITS );
        pExpr = pCsr->pExpr;
        rc = fts3ExprLoadDoclists(pCsr, 0, 0);
        if( rc!=SQLITE_OK ) break;
        if( bGlobal ){
          if( pCsr->pDeferred ){
            rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0);
            rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0);
            if( rc!=SQLITE_OK ) break;
          }
          rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
          sqlite3Fts3EvalTestDeferred(pCsr, &rc);
          if( rc!=SQLITE_OK ) break;
        }
        (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);

Changes to ext/fts3/fts3_tokenize_vtab.c.

184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
184
185
186
187
188
189
190

191

192
193
194
195
196
197
198







-
+
-







      zModule = azDequote[0];
    }
    rc = fts3tokQueryTokenizer((Fts3Hash*)pHash, zModule, &pMod, pzErr);
  }

  assert( (rc==SQLITE_OK)==(pMod!=0) );
  if( rc==SQLITE_OK ){
    const char * const *azArg = 0;
    const char * const *azArg = (const char * const *)&azDequote[1];
    if( nDequote>1 ) azArg = (const char * const *)&azDequote[1];
    rc = pMod->xCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok);
  }

  if( rc==SQLITE_OK ){
    pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable));
    if( pTab==0 ){
      rc = SQLITE_NOMEM;
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360







-
+







  if( idxNum==1 ){
    const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
    int nByte = sqlite3_value_bytes(apVal[0]);
    pCsr->zInput = sqlite3_malloc64(nByte+1);
    if( pCsr->zInput==0 ){
      rc = SQLITE_NOMEM;
    }else{
      if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte);
      memcpy(pCsr->zInput, zByte, nByte);
      pCsr->zInput[nByte] = 0;
      rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr);
      if( rc==SQLITE_OK ){
        pCsr->pCsr->pTokenizer = pTab->pTok;
      }
    }
  }

Changes to ext/fts3/fts3_tokenizer.c.

386
387
388
389
390
391
392
393

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

393


394
395
396
397
398
399
400







-
+
-
-







  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
  if( SQLITE_ROW==sqlite3_step(pStmt) ){
    if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB
    if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
     && sqlite3_column_bytes(pStmt, 0)==sizeof(*pp)
    ){
      memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
    }
  }

  return sqlite3_finalize(pStmt);
}

477
478
479
480
481
482
483
484

485
486
487
488
489
490
491
475
476
477
478
479
480
481

482
483
484
485
486
487
488
489







-
+







int sqlite3Fts3InitHashTable(
  sqlite3 *db, 
  Fts3Hash *pHash, 
  const char *zName
){
  int rc = SQLITE_OK;
  void *p = (void *)pHash;
  const int any = SQLITE_UTF8|SQLITE_DIRECTONLY;
  const int any = SQLITE_ANY;

#ifdef SQLITE_TEST
  char *zTest = 0;
  char *zTest2 = 0;
  void *pdb = (void *)db;
  zTest = sqlite3_mprintf("%s_test", zName);
  zTest2 = sqlite3_mprintf("%s_internal_test", zName);

Changes to ext/fts3/fts3_unicode.c.

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
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;
    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.

19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33







-
+








#include "fts3Int.h"
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)

#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>


#define FTS_MAX_APPENDABLE_HEIGHT 16

/*
** When full-text index nodes are loaded from disk, the buffer that they
** are loaded into has the following number of bytes of padding at the end 
** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77







-
+







# define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold
#else
# define FTS3_NODE_CHUNKSIZE (4*1024) 
# define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4)
#endif

/*
** The values that may be meaningfully bound to the :1 parameter in
** The two values that may be meaningfully bound to the :1 parameter in
** statements SQL_REPLACE_STAT and SQL_SELECT_STAT.
*/
#define FTS_STAT_DOCTOTAL      0
#define FTS_STAT_INCRMERGEHINT 1
#define FTS_STAT_AUTOINCRMERGE 2

/*
331
332
333
334
335
336
337
338

339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
331
332
333
334
335
336
337

338
339
340
341
342
343

344


345
346
347
348
349
350
351







-
+





-
+
-
-







/* This statement is used to determine which level to read the input from
** when performing an incremental merge. It returns the absolute level number
** of the oldest level in the db that contains at least ? segments. Or,
** if no level in the FTS index contains more than ? segments, the statement
** returns zero rows.  */
/* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' "
         "  GROUP BY level HAVING cnt>=?"
         "  ORDER BY (level %% 1024) ASC, 2 DESC LIMIT 1",
         "  ORDER BY (level %% 1024) ASC LIMIT 1",

/* Estimate the upper limit on the number of leaf nodes in a new segment
** created by merging the oldest :2 segments from absolute level :1. See 
** function sqlite3Fts3Incrmerge() for details.  */
/* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) "
         "  FROM (SELECT * FROM %Q.'%q_segdir' "
         "  FROM %Q.'%q_segdir' WHERE level = ? AND idx < ?",
         "        WHERE level = ? ORDER BY idx ASC LIMIT ?"
         "  )",

/* SQL_DELETE_SEGDIR_ENTRY
**   Delete the %_segdir entry on absolute level :1 with index :2.  */
/* 30 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?",

/* SQL_SHIFT_SEGDIR_ENTRY
**   Modify the idx value for the segment with idx=:3 on absolute level :2
694
695
696
697
698
699
700
701

702
703
704
705
706
707
708
692
693
694
695
696
697
698

699
700
701
702
703
704
705
706







-
+







){
  PendingList *p = *pp;
  int rc = SQLITE_OK;

  assert( !p || p->iLastDocid<=iDocid );

  if( !p || p->iLastDocid!=iDocid ){
    u64 iDelta = (u64)iDocid - (u64)(p ? p->iLastDocid : 0);
    sqlite3_int64 iDelta = iDocid - (p ? p->iLastDocid : 0);
    if( p ){
      assert( p->nData<p->nSpace );
      assert( p->aData[p->nData]==0 );
      p->nData++;
    }
    if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iDelta)) ){
      goto pendinglistappend_out;
1151
1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163







-
+








  if( rc==SQLITE_OK ){
    /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already
    ** full, merge all segments in level iLevel into a single iLevel+1
    ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise,
    ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext.
    */
    if( iNext>=MergeCount(p) ){
    if( iNext>=FTS3_MERGE_COUNT ){
      fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel));
      rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel);
      *piIdx = 0;
    }else{
      *piIdx = iNext;
    }
  }
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1233
1234
1235
1236
1237
1238
1239


1240
1241
1242
1243
1244
1245
1246







-
-







        if( rc!=SQLITE_OK ){
          sqlite3_free(aByte);
          aByte = 0;
        }
      }
      *paBlob = aByte;
    }
  }else if( rc==SQLITE_ERROR ){
    rc = FTS_CORRUPT_VTAB;
  }

  return rc;
}

/*
** Close the blob handle at p->pSegments, if it is open. See comments above
1379
1380
1381
1382
1383
1384
1385
1386

1387
1388
1389
1390
1391
1392
1393
1375
1376
1377
1378
1379
1380
1381

1382
1383
1384
1385
1386
1387
1388
1389







-
+







  
  /* Because of the FTS3_NODE_PADDING bytes of padding, the following is 
  ** safe (no risk of overread) even if the node data is corrupted. */
  pNext += fts3GetVarint32(pNext, &nPrefix);
  pNext += fts3GetVarint32(pNext, &nSuffix);
  if( nSuffix<=0 
   || (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
   || nPrefix>pReader->nTerm
   || nPrefix>pReader->nTermAlloc
  ){
    return FTS_CORRUPT_VTAB;
  }

  /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
  ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
  ** overflow - hence the (i64) casts.  */
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1409
1410
1411
1412
1413
1414
1415

1416
1417
1418
1419
1420
1421
1422







-








  /* Check that the doclist does not appear to extend past the end of the
  ** b-tree node. And that the final byte of the doclist is 0x00. If either 
  ** of these statements is untrue, then the data structure is corrupt.
  */
  if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
   || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
   || pReader->nDoclist==0
  ){
    return FTS_CORRUPT_VTAB;
  }
  return SQLITE_OK;
}

/*
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
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







-
-
+
+

-
+

-
+





-
+







    ** returning.
    */
    if( p>=pEnd ){
      pReader->pOffsetList = 0;
    }else{
      rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX);
      if( rc==SQLITE_OK ){
        u64 iDelta;
        pReader->pOffsetList = p + sqlite3Fts3GetVarintU(p, &iDelta);
        sqlite3_int64 iDelta;
        pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta);
        if( pTab->bDescIdx ){
          pReader->iDocid = (i64)((u64)pReader->iDocid - iDelta);
          pReader->iDocid -= iDelta;
        }else{
          pReader->iDocid = (i64)((u64)pReader->iDocid + iDelta);
          pReader->iDocid += iDelta;
        }
      }
    }
  }

  return rc;
  return SQLITE_OK;
}


int sqlite3Fts3MsrOvfl(
  Fts3Cursor *pCsr, 
  Fts3MultiSegReader *pMsr,
  int *pnOvfl
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2026
2027
2028
2029
2030
2031
2032





2033
2034
2035
2036
2037
2038
2039







-
-
-
-
-







    int nReq = nData;             /* Required space after adding zTerm */
    int nPrefix;                  /* Number of bytes of prefix compression */
    int nSuffix;                  /* Suffix length */

    nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm);
    nSuffix = nTerm-nPrefix;

    /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of 
    ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when
    ** compared with BINARY collation. This indicates corruption.  */
    if( nSuffix<=0 ) return FTS_CORRUPT_VTAB;

    nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix;
    if( nReq<=p->nNodeSize || !pTree->zTerm ){

      if( nReq>p->nNodeSize ){
        /* An unusual case: this is the first term to be added to the node
        ** and the static node buffer (p->nNodeSize bytes) is not large
        ** enough. Use a separately malloced buffer instead This wastes
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2270
2271
2272
2273
2274
2275
2276

2277
2278
2279
2280
2281
2282
2283







-







    sqlite3Fts3VarintLen(nDoclist) +        /* Size of doclist */
    nDoclist;                               /* Doclist data */

  if( nData>0 && nData+nReq>p->nNodeSize ){
    int rc;

    /* The current leaf node is full. Write it out to the database. */
    if( pWriter->iFree==LARGEST_INT64 ) return FTS_CORRUPT_VTAB;
    rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData);
    if( rc!=SQLITE_OK ) return rc;
    p->nLeafAdd++;

    /* Add the current term to the interior node tree. The term added to
    ** the interior tree must:
    **
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2319
2320
2321
2322
2323
2324
2325

2326
2327
2328

2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347

2348
2349
2350
2351
2352
2353
2354







-



-



















-







    pWriter->nSize = nReq;
  }
  assert( nData+nReq<=pWriter->nSize );

  /* Append the prefix-compressed term and doclist to the buffer. */
  nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix);
  nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix);
  assert( nSuffix>0 );
  memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix);
  nData += nSuffix;
  nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist);
  assert( nDoclist>0 );
  memcpy(&pWriter->aData[nData], aDoclist, nDoclist);
  pWriter->nData = nData + nDoclist;

  /* Save the current term so that it can be used to prefix-compress the next.
  ** If the isCopyTerm parameter is true, then the buffer pointed to by
  ** zTerm is transient, so take a copy of the term data. Otherwise, just
  ** store a copy of the pointer.
  */
  if( isCopyTerm ){
    if( nTerm>pWriter->nMalloc ){
      char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2);
      if( !zNew ){
        return SQLITE_NOMEM;
      }
      pWriter->nMalloc = nTerm*2;
      pWriter->zMalloc = zNew;
      pWriter->zTerm = zNew;
    }
    assert( pWriter->zTerm==pWriter->zMalloc );
    assert( nTerm>0 );
    memcpy(pWriter->zTerm, zTerm, nTerm);
  }else{
    pWriter->zTerm = (char *)zTerm;
  }
  pWriter->nTerm = nTerm;

  return SQLITE_OK;
2501
2502
2503
2504
2505
2506
2507
2508

2509
2510
2511
2512
2513
2514
2515
2487
2488
2489
2490
2491
2492
2493

2494
2495
2496
2497
2498
2499
2500
2501







-
+







  ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR).
  */
  sqlite3_stmt *pStmt;
  int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0);
  if( rc!=SQLITE_OK ) return rc;
  sqlite3_bind_int64(pStmt, 1, iAbsLevel+1);
  sqlite3_bind_int64(pStmt, 2, 
      (((u64)iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL
      ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL
  );

  *pbMax = 0;
  if( SQLITE_ROW==sqlite3_step(pStmt) ){
    *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL;
  }
  return sqlite3_reset(pStmt);
2629
2630
2631
2632
2633
2634
2635
2636

2637
2638
2639
2640
2641
2642
2643

2644
2645
2646
2647
2648
2649
2650
2615
2616
2617
2618
2619
2620
2621

2622
2623
2624
2625
2626
2627
2628

2629
2630
2631
2632
2633
2634
2635
2636







-
+






-
+







    if( iCol==iCurrent ){
      nList = (int)(p - pList);
      break;
    }

    nList -= (int)(p - pList);
    pList = p;
    if( nList<=0 ){
    if( nList==0 ){
      break;
    }
    p = &pList[1];
    p += fts3GetVarint32(p, &iCurrent);
  }

  if( bZero && (pEnd - &pList[nList])>0){
  if( bZero && &pList[nList]!=pEnd ){
    memset(&pList[nList], 0, pEnd - &pList[nList]);
  }
  *ppList = pList;
  *pnList = nList;
}

/*
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2649
2650
2651
2652
2653
2654
2655

2656
2657
2658
2659
2660
2661
2662







-







    char *pNew;
    pMsr->nBuffer = nList*2;
    pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer);
    if( !pNew ) return SQLITE_NOMEM;
    pMsr->aBuffer = pNew;
  }

  assert( nList>0 );
  memcpy(pMsr->aBuffer, pList, nList);
  return SQLITE_OK;
}

int sqlite3Fts3MsrIncrNext(
  Fts3Table *p,                   /* Virtual table handle */
  Fts3MultiSegReader *pMsr,       /* Multi-segment-reader handle */
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2836
2837
2838
2839
2840
2841
2842













2843
2844
2845
2846
2847
2848
2849







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







    pCsr->apSegment[i]->nOffsetList = 0;
    pCsr->apSegment[i]->iDocid = 0;
  }

  return SQLITE_OK;
}

static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){
  if( nReq>pCsr->nBuffer ){
    char *aNew;
    pCsr->nBuffer = nReq*2;
    aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
    if( !aNew ){
      return SQLITE_NOMEM;
    }
    pCsr->aBuffer = aNew;
  }
  return SQLITE_OK;
}


int sqlite3Fts3SegReaderStep(
  Fts3Table *p,                   /* Virtual table handle */
  Fts3MultiSegReader *pCsr        /* Cursor object */
){
  int rc = SQLITE_OK;

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
2962
2963
2964
2965
2966
2967
2968


2969
2970
2971
2972
2973

2974

2975
2976
2977
2978
2979
2980
2981
2982
2983
2984


2985
2986

2987
2988
2989
2990
2991
2992
2993
2994







-
-
+

+
+
+
-
+
-

+


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








        if( !isIgnoreEmpty || nList>0 ){

          /* Calculate the 'docid' delta value to write into the merged 
          ** doclist. */
          sqlite3_int64 iDelta;
          if( p->bDescIdx && nDoclist>0 ){
            if( iPrev<=iDocid ) return FTS_CORRUPT_VTAB;
            iDelta = (i64)((u64)iPrev - (u64)iDocid);
            iDelta = iPrev - iDocid;
          }else{
            iDelta = iDocid - iPrev;
          }
          if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){
            if( nDoclist>0 && iPrev>=iDocid ) return FTS_CORRUPT_VTAB;
            return FTS_CORRUPT_VTAB;
            iDelta = (i64)((u64)iDocid - (u64)iPrev);
          }
          assert( nDoclist>0 || iDelta==iDocid );

          nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
          if( nDoclist+nByte>pCsr->nBuffer ){
            char *aNew;
            pCsr->nBuffer = (nDoclist+nByte)*2;
            aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
            if( !aNew ){
              return SQLITE_NOMEM;

          rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist);
            }
            pCsr->aBuffer = aNew;
          if( rc ) return rc;
          }

          if( isFirst ){
            char *a = &pCsr->aBuffer[nDoclist];
            int nWrite;
           
            nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a);
            if( nWrite ){
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3005
3006
3007
3008
3009
3010
3011



3012
3013
3014
3015
3016
3017
3018







-
-
-







            }
          }
        }

        fts3SegReaderSort(apSegment, nMerge, j, xCmp);
      }
      if( nDoclist>0 ){
        rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING);
        if( rc ) return rc;
        memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING);
        pCsr->aDoclist = pCsr->aBuffer;
        pCsr->nDoclist = nDoclist;
        rc = SQLITE_ROW;
      }
    }
    pCsr->nAdvance = nMerge;
  }while( rc==SQLITE_OK );
3077
3078
3079
3080
3081
3082
3083
3084

3085
3086
3087
3088

3089
3090
3091
3092
3093
3094
3095
3096
3097
3098

3099
3100
3101
3102
3103
3104
3105
3054
3055
3056
3057
3058
3059
3060

3061
3062
3063
3064

3065
3066
3067
3068
3069
3070
3071
3072
3073
3074

3075
3076
3077
3078
3079
3080
3081
3082







-
+



-
+









-
+







  i64 *piEndBlock,
  i64 *pnByte
){
  const unsigned char *zText = sqlite3_column_text(pStmt, iCol);
  if( zText ){
    int i;
    int iMul = 1;
    u64 iVal = 0;
    i64 iVal = 0;
    for(i=0; zText[i]>='0' && zText[i]<='9'; i++){
      iVal = iVal*10 + (zText[i] - '0');
    }
    *piEndBlock = (i64)iVal;
    *piEndBlock = iVal;
    while( zText[i]==' ' ) i++;
    iVal = 0;
    if( zText[i]=='-' ){
      i++;
      iMul = -1;
    }
    for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
      iVal = iVal*10 + (zText[i] - '0');
    }
    *pnByte = ((i64)iVal * (i64)iMul);
    *pnByte = (iVal * (i64)iMul);
  }
}


/*
** A segment of size nByte bytes has just been written to absolute level
** iAbsLevel. Promote any segments that should be promoted as a result.
3274
3275
3276
3277
3278
3279
3280
3281

3282
3283
3284
3285
3286
3287
3288
3251
3252
3253
3254
3255
3256
3257

3258
3259
3260
3261
3262
3263
3264
3265







-
+







  while( SQLITE_OK==rc ){
    rc = sqlite3Fts3SegReaderStep(p, &csr);
    if( rc!=SQLITE_ROW ) break;
    rc = fts3SegWriterAdd(p, &pWriter, 1, 
        csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist);
  }
  if( rc!=SQLITE_OK ) goto finished;
  assert_fts3_nc( pWriter || bIgnoreEmpty );
  assert( pWriter || bIgnoreEmpty );

  if( iLevel!=FTS3_SEGCURSOR_PENDING ){
    rc = fts3DeleteSegdir(
        p, iLangid, iIndex, iLevel, csr.apSegment, csr.nSegment
    );
    if( rc!=SQLITE_OK ) goto finished;
  }
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510

3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531

3532
3533
3534
3535
3536
3537
3538
3478
3479
3480
3481
3482
3483
3484



3485

3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513







-
-
-
+
-




















+







** iIndex/iLangid combination.
*/
static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
  int bSeenDone = 0;
  int rc;
  sqlite3_stmt *pAllLangid = 0;

  rc = sqlite3Fts3PendingTermsFlush(p);
  if( rc==SQLITE_OK ){
    rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
  rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
  }
  if( rc==SQLITE_OK ){
    int rc2;
    sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
    sqlite3_bind_int(pAllLangid, 2, p->nIndex);
    while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
      int i;
      int iLangid = sqlite3_column_int(pAllLangid, 0);
      for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
        rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL);
        if( rc==SQLITE_DONE ){
          bSeenDone = 1;
          rc = SQLITE_OK;
        }
      }
    }
    rc2 = sqlite3_reset(pAllLangid);
    if( rc==SQLITE_OK ) rc = rc2;
  }

  sqlite3Fts3SegmentsClose(p);
  sqlite3Fts3PendingTermsClear(p);

  return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc;
}

/*
** This function is called when the user executes the following statement:
**
3775
3776
3777
3778
3779
3780
3781
3782

3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801

3802
3803
3804
3805
3806
3807
3808
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







-
+


















-
+







    p->aNode = 0;
  }else{
    if( bFirst==0 ){
      p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
    }
    p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);

    if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
    if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
      return FTS_CORRUPT_VTAB;
    }
    blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
    if( rc==SQLITE_OK ){
      memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
      p->term.n = nPrefix+nSuffix;
      p->iOff += nSuffix;
      if( p->iChild==0 ){
        p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
        if( (p->nNode-p->iOff)<p->nDoclist ){
          return FTS_CORRUPT_VTAB;
        }
        p->aDoclist = &p->aNode[p->iOff];
        p->iOff += p->nDoclist;
      }
    }
  }

  assert_fts3_nc( p->iOff<=p->nNode );
  assert( p->iOff<=p->nNode );
  return rc;
}

/*
** Release all dynamic resources held by node-reader object *p.
*/
static void nodeReaderRelease(NodeReader *p){
3818
3819
3820
3821
3822
3823
3824
3825

3826
3827
3828
3829
3830
3831
3832

3833
3834
3835
3836
3837
3838
3839
3793
3794
3795
3796
3797
3798
3799

3800
3801
3802
3803
3804
3805
3806

3807
3808
3809
3810
3811
3812
3813
3814







-
+






-
+







*/
static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){
  memset(p, 0, sizeof(NodeReader));
  p->aNode = aNode;
  p->nNode = nNode;

  /* Figure out if this is a leaf or an internal node. */
  if( aNode && aNode[0] ){
  if( p->aNode[0] ){
    /* An internal node. */
    p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild);
  }else{
    p->iOff = 1;
  }

  return aNode ? nodeReaderNext(p) : SQLITE_OK;
  return nodeReaderNext(p);
}

/*
** This function is called while writing an FTS segment each time a leaf o
** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed
** to be greater than the largest key on the node just written, but smaller
** than or equal to the first key that will be written to the next leaf
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3837
3838
3839
3840
3841
3842
3843

3844
3845
3846
3847
3848
3849
3850







-








    /* Figure out how much space the key will consume if it is written to
    ** the current node of layer iLayer. Due to the prefix compression, 
    ** the space required changes depending on which node the key is to
    ** be added to.  */
    nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm);
    nSuffix = nTerm - nPrefix;
    if(nSuffix<=0 ) return FTS_CORRUPT_VTAB;
    nSpace  = sqlite3Fts3VarintLen(nPrefix);
    nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;

    if( pNode->key.n==0 || (pNode->block.n + nSpace)<=p->nNodeSize ){ 
      /* If the current node of layer iLayer contains zero keys, or if adding
      ** the key to it will not cause it to grow to larger than nNodeSize 
      ** bytes in size, write the key here.  */
3956
3957
3958
3959
3960
3961
3962
3963

3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3930
3931
3932
3933
3934
3935
3936

3937
3938
3939
3940
3941
3942
3943

3944
3945
3946
3947
3948
3949
3950







-
+






-







  int bFirst = (pPrev->n==0);     /* True if this is the first term written */
  int nPrefix;                    /* Size of term prefix in bytes */
  int nSuffix;                    /* Size of term suffix in bytes */

  /* Node must have already been started. There must be a doclist for a
  ** leaf node, and there must not be a doclist for an internal node.  */
  assert( pNode->n>0 );
  assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) );
  assert( (pNode->a[0]=='\0')==(aDoclist!=0) );

  blobGrowBuffer(pPrev, nTerm, &rc);
  if( rc!=SQLITE_OK ) return rc;

  nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm);
  nSuffix = nTerm - nPrefix;
  if( nSuffix<=0 ) return FTS_CORRUPT_VTAB;
  memcpy(pPrev->a, zTerm, nTerm);
  pPrev->n = nTerm;

  if( bFirst==0 ){
    pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix);
  }
  pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix);
4173
4174
4175
4176
4177
4178
4179
4180

4181
4182
4183
4184
4185
4186
4187
4146
4147
4148
4149
4150
4151
4152

4153
4154
4155
4156
4157
4158
4159
4160







-
+







static int fts3TermCmp(
  const char *zLhs, int nLhs,     /* LHS of comparison */
  const char *zRhs, int nRhs      /* RHS of comparison */
){
  int nCmp = MIN(nLhs, nRhs);
  int res;

  res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0);
  res = memcmp(zLhs, zRhs, nCmp);
  if( res==0 ) res = nLhs - nRhs;

  return res;
}


/*
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4230
4231
4232
4233
4234
4235
4236




4237
4238
4239
4240
4241
4242
4243







-
-
-
-







      fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData);
      if( pWriter->nLeafData<0 ){
        pWriter->nLeafData = pWriter->nLeafData * -1;
      }
      pWriter->bNoLeafData = (pWriter->nLeafData==0);
      nRoot = sqlite3_column_bytes(pSelect, 4);
      aRoot = sqlite3_column_blob(pSelect, 4);
      if( aRoot==0 ){
        sqlite3_reset(pSelect);
        return nRoot ? SQLITE_NOMEM : FTS_CORRUPT_VTAB;
      }
    }else{
      return sqlite3_reset(pSelect);
    }

    /* Check for the zero-length marker in the %_segments table */
    rc = fts3IsAppendable(p, iEnd, &bAppendable);

4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320

4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337




4338
4339
4340

4341
4342
4343
4344
4345
4346
4347
4348
4349








4350
4351
4352
4353
4354



4355
4356
4357


4358
4359
4360
4361
4362
4363
4364
4365
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
4293
4294





4295
4296
4297
4298



4299









4300
4301
4302
4303
4304
4305
4306
4307





4308
4309
4310



4311
4312

4313
4314
4315
4316
4317
4318
4319







-
-
-
-













-
+
-
-



-






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








    if( rc==SQLITE_OK && bAppendable ){
      /* It is possible to append to this segment. Set up the IncrmergeWriter
      ** object to do so.  */
      int i;
      int nHeight = (int)aRoot[0];
      NodeWriter *pNode;
      if( nHeight<1 || nHeight>=FTS_MAX_APPENDABLE_HEIGHT ){
        sqlite3_reset(pSelect);
        return FTS_CORRUPT_VTAB;
      }

      pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT;
      pWriter->iStart = iStart;
      pWriter->iEnd = iEnd;
      pWriter->iAbsLevel = iAbsLevel;
      pWriter->iIdx = iIdx;

      for(i=nHeight+1; i<FTS_MAX_APPENDABLE_HEIGHT; i++){
        pWriter->aNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst;
      }

      pNode = &pWriter->aNodeWriter[nHeight];
      pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight;
      blobGrowBuffer(&pNode->block, 
      blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc);
          MAX(nRoot, p->nNodeSize)+FTS3_NODE_PADDING, &rc
      );
      if( rc==SQLITE_OK ){
        memcpy(pNode->block.a, aRoot, nRoot);
        pNode->block.n = nRoot;
        memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
      }

      for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
        NodeReader reader;
        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 ){
        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);
          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, 
          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), &rc);
                  MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc
                  );
              if( rc==SQLITE_OK ){
                memcpy(pNode->block.a, aBlock, nBlock);
                pNode->block.n = nBlock;
            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);
            }
            sqlite3_free(aBlock);
            }
          }
        }
        nodeReaderRelease(&reader);
      }
    }

    rc2 = sqlite3_reset(pSelect);
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604

4605
4606
4607
4608
4609
4610
4611
4548
4549
4550
4551
4552
4553
4554




4555
4556
4557
4558
4559
4560
4561
4562







-
-
-
-
+







  const char *zTerm,              /* Omit all terms smaller than this */
  int nTerm,                      /* Size of zTerm in bytes */
  sqlite3_int64 *piBlock          /* OUT: Block number in next layer down */
){
  NodeReader reader;              /* Reader object */
  Blob prev = {0, 0, 0};          /* Previous term written to new node */
  int rc = SQLITE_OK;             /* Return code */
  int bLeaf;                       /* True for a leaf node */

  if( nNode<1 ) return FTS_CORRUPT_VTAB;
  bLeaf = aNode[0]=='\0';
  int bLeaf = aNode[0]=='\0';     /* True for a leaf node */

  /* Allocate required output space */
  blobGrowBuffer(pNew, nNode, &rc);
  if( rc!=SQLITE_OK ) return rc;
  pNew->n = 0;

  /* Populate new node buffer */
4863
4864
4865
4866
4867
4868
4869
4870

4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4814
4815
4816
4817
4818
4819
4820

4821

4822


4823
4824
4825
4826
4827

4828
4829
4830
4831
4832
4833
4834







-
+
-

-
-





-







** If no error occurs, return SQLITE_OK. If the hint blob in *pHint does
** not contain at least two valid varints, return SQLITE_CORRUPT_VTAB.
*/
static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
  const int nHint = pHint->n;
  int i;

  i = pHint->n-1;
  i = pHint->n-2;
  if( (pHint->a[i] & 0x80) ) return FTS_CORRUPT_VTAB;
  while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
  if( i==0 ) return FTS_CORRUPT_VTAB;
  i--;
  while( i>0 && (pHint->a[i-1] & 0x80) ) i--;

  pHint->n = i;
  i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
  i += fts3GetVarint32(&pHint->a[i], pnInput);
  assert( i<=nHint );
  if( i!=nHint ) return FTS_CORRUPT_VTAB;

  return SQLITE_OK;
}


/*
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
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







-
-
-
-
-
-

-
+












-
-
-
-
-
-
+
-







    if( rc==SQLITE_OK && hint.n ){
      int nHint = hint.n;
      sqlite3_int64 iHintAbsLevel = 0;      /* Hint level */
      int nHintSeg = 0;                     /* Hint number of segments */

      rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg);
      if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){
        /* Based on the scan in the block above, it is known that there
        ** are no levels with a relative level smaller than that of
        ** iAbsLevel with more than nSeg segments, or if nSeg is -1, 
        ** no levels with more than nMin segments. Use this to limit the
        ** value of nHintSeg to avoid a large memory allocation in case the 
        ** merge-hint is corrupt*/
        iAbsLevel = iHintAbsLevel;
        nSeg = MIN(MAX(nMin,nSeg), nHintSeg);
        nSeg = nHintSeg;
        bUseHint = 1;
        bDirtyHint = 1;
      }else{
        /* This undoes the effect of the HintPop() above - so that no entry
        ** is removed from the hint blob.  */
        hint.n = nHint;
      }
    }

    /* If nSeg is less that zero, then there is no level with at least
    ** nMin segments and no hint in the %_stat table. No work to do.
    ** Exit early in this case.  */
    if( nSeg<=0 ) break;

    assert( nMod<=0x7FFFFFFF );
    if( iAbsLevel<0 || iAbsLevel>(nMod<<32) ){
      rc = FTS_CORRUPT_VTAB;
      break;
    if( nSeg<0 ) break;
    }

    /* Open a cursor to iterate through the contents of the oldest nSeg 
    ** indexes of absolute level iAbsLevel. If this cursor is opened using 
    ** the 'hint' parameters, it is possible that there are less than nSeg
    ** segments available in level iAbsLevel. In this case, no work is
    ** done on iAbsLevel - fall through to the next iteration of the loop 
    ** to start work on some other level.  */
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
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







+

-
-
-
-
-
-
-
-










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







    }

    if( rc==SQLITE_OK ){
      rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr);
    }
    if( SQLITE_OK==rc && pCsr->nSegment==nSeg
     && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter))
     && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr))
    ){
      int bEmpty = 0;
      rc = sqlite3Fts3SegReaderStep(p, pCsr);
      if( rc==SQLITE_OK ){
        bEmpty = 1;
      }else if( rc!=SQLITE_ROW ){
        sqlite3Fts3SegReaderFinish(pCsr);
        break;
      }
      if( bUseHint && iIdx>0 ){
        const char *zKey = pCsr->zTerm;
        int nKey = pCsr->nTerm;
        rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter);
      }else{
        rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter);
      }

      if( rc==SQLITE_OK && pWriter->nLeafEst ){
        fts3LogMerge(nSeg, iAbsLevel);
        if( bEmpty==0 ){
          do {
            rc = fts3IncrmergeAppend(p, pWriter, pCsr);
            if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr);
            if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK;
          }while( rc==SQLITE_ROW );
        do {
          rc = fts3IncrmergeAppend(p, pWriter, pCsr);
          if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr);
          if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK;
        }while( rc==SQLITE_ROW );
        }

        /* Update or delete the input segments */
        if( rc==SQLITE_OK ){
          nRem -= (1 + pWriter->nWork);
          rc = fts3IncrmergeChomp(p, iAbsLevel, pCsr, &nSeg);
          if( nSeg!=0 ){
            bDirtyHint = 1;
5087
5088
5089
5090
5091
5092
5093
5094

5095
5096
5097
5098
5099
5100
5101
5013
5014
5015
5016
5017
5018
5019

5020
5021
5022
5023
5024
5025
5026
5027







-
+







** before it will be selected for a merge, respectively.
*/
static int fts3DoIncrmerge(
  Fts3Table *p,                   /* FTS3 table handle */
  const char *zParam              /* Nul-terminated string containing "A,B" */
){
  int rc;
  int nMin = (MergeCount(p) / 2);
  int nMin = (FTS3_MERGE_COUNT / 2);
  int nMerge = 0;
  const char *z = zParam;

  /* Read the first integer value */
  nMerge = fts3Getint(&z);

  /* If the first integer value is followed by a ',',  read the second
5132
5133
5134
5135
5136
5137
5138
5139

5140
5141
5142
5143
5144
5145
5146
5058
5059
5060
5061
5062
5063
5064

5065
5066
5067
5068
5069
5070
5071
5072







-
+







static int fts3DoAutoincrmerge(
  Fts3Table *p,                   /* FTS3 table handle */
  const char *zParam              /* Nul-terminated string containing boolean */
){
  int rc = SQLITE_OK;
  sqlite3_stmt *pStmt = 0;
  p->nAutoincrmerge = fts3Getint(&zParam);
  if( p->nAutoincrmerge==1 || p->nAutoincrmerge>MergeCount(p) ){
  if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){
    p->nAutoincrmerge = 8;
  }
  if( !p->bHasStat ){
    assert( p->bFts4==0 );
    sqlite3Fts3CreateStatTable(&rc, p);
    if( rc ) return rc;
  }
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
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







-
+



-
-
+
+







-
+
-
-
-
-
+
-







  if( rc==SQLITE_OK ){
    while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){
      char *pCsr = csr.aDoclist;
      char *pEnd = &pCsr[csr.nDoclist];

      i64 iDocid = 0;
      i64 iCol = 0;
      u64 iPos = 0;
      i64 iPos = 0;

      pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid);
      while( pCsr<pEnd ){
        u64 iVal = 0;
        pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal);
        i64 iVal = 0;
        pCsr += sqlite3Fts3GetVarint(pCsr, &iVal);
        if( pCsr<pEnd ){
          if( iVal==0 || iVal==1 ){
            iCol = 0;
            iPos = 0;
            if( iVal ){
              pCsr += sqlite3Fts3GetVarint(pCsr, &iCol);
            }else{
              pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal);
              pCsr += sqlite3Fts3GetVarint(pCsr, &iVal);
              if( p->bDescIdx ){
                iDocid = (i64)((u64)iDocid - iVal);
              }else{
                iDocid = (i64)((u64)iDocid + iVal);
              iDocid += iVal;
              }
            }
          }else{
            iPos += (iVal - 2);
            cksum = cksum ^ fts3ChecksumEntry(
                csr.zTerm, csr.nTerm, iLangid, iIndex, iDocid,
                (int)iCol, (int)iPos
            );
5306
5307
5308
5309
5310
5311
5312

5313
5314
5315

5316
5317
5318
5319
5320
5321
5322
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237

5238
5239
5240
5241
5242
5243
5244
5245







+


-
+







      i64 iDocid = sqlite3_column_int64(pStmt, 0);
      int iLang = langidFromSelect(p, pStmt);
      int iCol;

      for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
        if( p->abNotindexed[iCol]==0 ){
          const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
          int nText = sqlite3_column_bytes(pStmt, iCol+1);
          sqlite3_tokenizer_cursor *pT = 0;

          rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, -1, &pT);
          rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText,&pT);
          while( rc==SQLITE_OK ){
            char const *zToken;       /* Buffer containing token */
            int nToken = 0;           /* Number of bytes in token */
            int iDum1 = 0, iDum2 = 0; /* Dummy variables */
            int iPos = 0;             /* Position of token in zText */

            rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
5393
5394
5395
5396
5397
5398
5399
5400

5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416

5417
5418
5419
5420


5421
5422
5423
5424



5425
5426
5427
5428
5429
5430






5431
5432
5433
5434


5435
5436

5437
5438
5439
5440
5441
5442
5443
5316
5317
5318
5319
5320
5321
5322

5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338

5339




5340
5341




5342
5343
5344






5345
5346
5347
5348
5349
5350




5351
5352


5353
5354
5355
5356
5357
5358
5359
5360







-
+















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







**
**   "INSERT INTO tbl(tbl) VALUES(<expr>)"
**
** Argument pVal contains the result of <expr>. Currently the only 
** meaningful value to insert is the text 'optimize'.
*/
static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
  int rc = SQLITE_ERROR;           /* Return Code */
  int rc;                         /* Return Code */
  const char *zVal = (const char *)sqlite3_value_text(pVal);
  int nVal = sqlite3_value_bytes(pVal);

  if( !zVal ){
    return SQLITE_NOMEM;
  }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){
    rc = fts3DoOptimize(p, 0);
  }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){
    rc = fts3DoRebuild(p);
  }else if( nVal==15 && 0==sqlite3_strnicmp(zVal, "integrity-check", 15) ){
    rc = fts3DoIntegrityCheck(p);
  }else if( nVal>6 && 0==sqlite3_strnicmp(zVal, "merge=", 6) ){
    rc = fts3DoIncrmerge(p, &zVal[6]);
  }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){
    rc = fts3DoAutoincrmerge(p, &zVal[10]);
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
#ifdef SQLITE_TEST
  }else{
    int v;
    if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
      v = atoi(&zVal[9]);
  }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
    p->nNodeSize = atoi(&zVal[9]);
      if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v;
      rc = SQLITE_OK;
    }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
      v = atoi(&zVal[11]);
    rc = SQLITE_OK;
  }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
    p->nMaxPendingData = atoi(&zVal[11]);
      if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v;
      rc = SQLITE_OK;
    }else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){
      p->bNoIncrDoclist = atoi(&zVal[21]);
      rc = SQLITE_OK;
    }else if( nVal>11 && 0==sqlite3_strnicmp(zVal,"mergecount=",11) ){
    rc = SQLITE_OK;
  }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){
    p->bNoIncrDoclist = atoi(&zVal[21]);
    rc = SQLITE_OK;
#endif
  }else{
      v = atoi(&zVal[11]);
      if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v;
      rc = SQLITE_OK;
    }
    rc = SQLITE_ERROR;
  }
#endif
  }

  return rc;
}

#ifndef SQLITE_DISABLE_FTS4_DEFERRED
/*
** Delete all cached deferred doclists. Deferred doclists are cached
** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function.

Changes to ext/fts3/tool/fts3view.c.

89
90
91
92
93
94
95
96

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

96
97
98
99
100
101
102
103







-
+








/*
** Show the table schema
*/
static void showSchema(sqlite3 *db, const char *zTab){
  sqlite3_stmt *pStmt;
  pStmt = prepare(db,
            "SELECT sql FROM sqlite_schema"
            "SELECT sql FROM sqlite_master"
            " WHERE name LIKE '%q%%'"
            " ORDER BY 1",
            zTab);
  while( sqlite3_step(pStmt)==SQLITE_ROW ){
    printf("%s;\n", sqlite3_column_text(pStmt, 0));
  }
  sqlite3_finalize(pStmt);
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
827
828
829
830
831
832
833

834
835
836
837
838
839
840
841







-
+







    fprintf(stderr, "Cannot open %s\n", argv[1]);
    exit(1);
  }
  if( argc==2 ){
    sqlite3_stmt *pStmt;
    int cnt = 0;
    pStmt = prepare(db, "SELECT b.sql"
                        "  FROM sqlite_schema a, sqlite_schema b"
                        "  FROM sqlite_master a, sqlite_master b"
                        " WHERE a.name GLOB '*_segdir'"
                        "   AND b.name=substr(a.name,1,length(a.name)-7)"
                        " ORDER BY 1");
    while( sqlite3_step(pStmt)==SQLITE_ROW ){
      cnt++;
      printf("%s;\n", sqlite3_column_text(pStmt, 0));
    }

Changes to ext/fts3/unicode/mkunicode.tcl.

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
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++;
      }
      aAscii[0] = 0;                  /* 0x00 is never a token character */
    }
  }]
}

proc print_test_categories {lMap} {

  set lCP [list]

Changes to ext/fts5/fts5.h.

155
156
157
158
159
160
161
162

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

162
163
164
165
166
167
168
169







-
+







**   If the query runs to completion without incident, SQLITE_OK is returned.
**   Or, if some error occurs before the query completes or is aborted by
**   the callback, an SQLite error code is returned.
**
**
** xSetAuxdata(pFts5, pAux, xDelete)
**
**   Save the pointer passed as the second argument as the extension function's 
**   Save the pointer passed as the second argument as the extension functions 
**   "auxiliary data". The pointer may then be retrieved by the current or any
**   future invocation of the same fts5 extension function made as part of
**   the same MATCH query using the xGetAuxdata() API.
**
**   Each extension function is allocated a single auxiliary data slot for
**   each FTS query (MATCH expression). If the extension function is invoked 
**   more than once for a single FTS query, then all invocations share a 
397
398
399
400
401
402
403
404
405


406
407
408
409
410
411
412
397
398
399
400
401
402
403


404
405
406
407
408
409
410
411
412







-
-
+
+







**   of "first place" within the document set, but not alternative forms
**   such as "1st place". In some applications, it would be better to match
**   all instances of "first place" or "1st place" regardless of which form
**   the user specified in the MATCH query text.
**
**   There are several ways to approach this in FTS5:
**
**   <ol><li> By mapping all synonyms to a single token. In this case, using
**            the above example, this means that the tokenizer returns the
**   <ol><li> By mapping all synonyms to a single token. In this case, the 
**            In the above example, this means that the tokenizer returns the
**            same token for inputs "first" and "1st". Say that token is in
**            fact "first", so that when the user inserts the document "I won
**            1st place" entries are added to the index for tokens "i", "won",
**            "first" and "place". If the user then queries for '1st + place',
**            the tokenizer substitutes "first" for "1st" and the query works
**            as expected.
**

Changes to ext/fts5/fts5Int.h.

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
57
58
59
60
61
62
63





64
65
66
67
68
69
70







-
-
-
-
-







/*
** Maximum number of prefix indexes on single FTS5 table. This must be
** less than 32. If it is set to anything large than that, an #error
** directive in fts5_index.c will cause the build to fail.
*/
#define FTS5_MAX_PREFIX_INDEXES 31

/*
** Maximum segments permitted in a single index 
*/
#define FTS5_MAX_SEGMENT 2000

#define FTS5_DEFAULT_NEARDIST 10
#define FTS5_DEFAULT_RANK     "bm25"

/* Name of rank and rowid columns */
#define FTS5_RANK_NAME "rank"
#define FTS5_ROWID_NAME "rowid"

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







-
-




















-
+





-
-
-
+
+
+

-
+
-
-







  char *zContent;                 /* content table */ 
  char *zContentRowid;            /* "content_rowid=" option value */ 
  int bColumnsize;                /* "columnsize=" option value (dflt==1) */
  int eDetail;                    /* FTS5_DETAIL_XXX value */
  char *zContentExprlist;
  Fts5Tokenizer *pTok;
  fts5_tokenizer *pTokApi;
  int bLock;                      /* True when table is preparing statement */
  int ePattern;                   /* FTS_PATTERN_XXX constant */

  /* Values loaded from the %_config table */
  int iCookie;                    /* Incremented when %_config is modified */
  int pgsz;                       /* Approximate page size used in %_data */
  int nAutomerge;                 /* 'automerge' setting */
  int nCrisisMerge;               /* Maximum allowed segments per level */
  int nUsermerge;                 /* 'usermerge' setting */
  int nHashSize;                  /* Bytes of memory for in-memory hash */
  char *zRank;                    /* Name of rank function */
  char *zRankArgs;                /* Arguments to rank function */

  /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
  char **pzErrmsg;

#ifdef SQLITE_DEBUG
  int bPrefixIndex;               /* True to use prefix-indexes */
#endif
};

/* Current expected value of %_config table 'version' field */
#define FTS5_CURRENT_VERSION  4
#define FTS5_CURRENT_VERSION 4

#define FTS5_CONTENT_NORMAL   0
#define FTS5_CONTENT_NONE     1
#define FTS5_CONTENT_EXTERNAL 2

#define FTS5_DETAIL_FULL      0
#define FTS5_DETAIL_NONE      1
#define FTS5_DETAIL_COLUMNS   2
#define FTS5_DETAIL_FULL    0
#define FTS5_DETAIL_NONE    1
#define FTS5_DETAIL_COLUMNS 2

#define FTS5_PATTERN_NONE     0

#define FTS5_PATTERN_LIKE     65  /* matches SQLITE_INDEX_CONSTRAINT_LIKE */
#define FTS5_PATTERN_GLOB     66  /* matches SQLITE_INDEX_CONSTRAINT_GLOB */

int sqlite3Fts5ConfigParse(
    Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char**
);
void sqlite3Fts5ConfigFree(Fts5Config*);

int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig);
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
412
413
414
415
416
417
418





419
420
421
422
423
424
425







-
-
-
-
-







int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);

/*
** Close an iterator opened by sqlite3Fts5IndexQuery().
*/
void sqlite3Fts5IterClose(Fts5IndexIter*);

/*
** Close the reader blob handle, if it is open.
*/
void sqlite3Fts5IndexCloseReader(Fts5Index*);

/*
** This interface is used by the fts5vocab module.
*/
const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*);
int sqlite3Fts5IterNextScan(Fts5IndexIter*);


483
484
485
486
487
488
489
490

491
492
493
494
495
496
497
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483







-
+







*/
int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize);
int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);

/*
** Functions called by the storage module as part of integrity-check.
*/
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum, int bUseCksum);
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum);

/* 
** Called during virtual module initialization to register UDF 
** fts5_decode() with SQLite 
*/
int sqlite3Fts5IndexInit(sqlite3*);

553
554
555
556
557
558
559
560


561
562
563
564
565
566
567
539
540
541
542
543
544
545

546
547
548
549
550
551
552
553
554







-
+
+







  Fts5Index *pIndex;              /* Full-text index */
};

int sqlite3Fts5GetTokenizer(
  Fts5Global*, 
  const char **azArg,
  int nArg,
  Fts5Config*,
  Fts5Tokenizer**,
  fts5_tokenizer**,
  char **pzErr
);

Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);

int sqlite3Fts5FlushToDisk(Fts5Table*);

637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638







-
+







int sqlite3Fts5DropAll(Fts5Config*);
int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);

int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);

int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
int sqlite3Fts5StorageIntegrity(Fts5Storage *p);

int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);

int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
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
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







-





-
-
-
-
-
-
-
















-







  const char *p;                  /* Token text (not NULL terminated) */
  int n;                          /* Size of buffer p in bytes */
};

/* Parse a MATCH expression. */
int sqlite3Fts5ExprNew(
  Fts5Config *pConfig, 
  int bPhraseToAnd,
  int iCol,                       /* Column on LHS of MATCH operator */
  const char *zExpr,
  Fts5Expr **ppNew, 
  char **pzErr
);
int sqlite3Fts5ExprPattern(
  Fts5Config *pConfig, 
  int bGlob, 
  int iCol, 
  const char *zText, 
  Fts5Expr **pp
);

/*
** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc);
**     rc==SQLITE_OK && 0==sqlite3Fts5ExprEof(pExpr);
**     rc = sqlite3Fts5ExprNext(pExpr)
** ){
**   // The document with rowid iRowid matches the expression!
**   i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
** }
*/
int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc);
int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
int sqlite3Fts5ExprEof(Fts5Expr*);
i64 sqlite3Fts5ExprRowid(Fts5Expr*);

void sqlite3Fts5ExprFree(Fts5Expr*);
int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2);

/* Called during startup to register a UDF with SQLite */
int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);

int sqlite3Fts5ExprPhraseCount(Fts5Expr*);
int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase);
int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **);
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
781
782
783
784
785
786
787




788
789
790
791
792
793
794







-
-
-
-







**************************************************************************/

/**************************************************************************
** Interface to code in fts5_tokenizer.c. 
*/

int sqlite3Fts5TokenizerInit(fts5_api*);
int sqlite3Fts5TokenizerPattern(
    int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
    Fts5Tokenizer *pTok
);
/*
** End of interface to code in fts5_tokenizer.c.
**************************************************************************/

/**************************************************************************
** Interface to code in fts5_vocab.c. 
*/

Changes to ext/fts5/fts5_aux.c.

562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
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);
  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;

636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
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 */
  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 */

668
669
670
671
672
673
674
675

676
677
678
679
680
681
682
683










684
685
686
687
688
689
690
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 and return the BM25 score for the current row. Or, if an
  /* Determine the BM25 score for the current row. */
  ** 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) )
      );
    }
  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){

Changes to ext/fts5/fts5_buffer.c.

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
174
175
176
177
178
179
180

181




182
183
184





185
186
187
188
189
190
191







-
+
-
-
-
-



-
-
-
-
-







    /* EOF */
    *piOff = -1;
    return 1;  
  }else{
    i64 iOff = *piOff;
    int iVal;
    fts5FastGetVarint32(a, i, iVal);
    if( iVal<=1 ){
    if( iVal==1 ){
      if( iVal==0 ){
        *pi = i;
        return 0;
      }
      fts5FastGetVarint32(a, i, iVal);
      iOff = ((i64)iVal) << 32;
      fts5FastGetVarint32(a, i, iVal);
      if( iVal<2 ){
        /* This is a corrupt record. So stop parsing it here. */
        *piOff = -1;
        return 1;
      }
    }
    *piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
    *pi = i;
    return 0;
  }
}

Changes to ext/fts5/fts5_config.c.

19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33







-
+







#define FTS5_DEFAULT_PAGE_SIZE   4050
#define FTS5_DEFAULT_AUTOMERGE      4
#define FTS5_DEFAULT_USERMERGE      4
#define FTS5_DEFAULT_CRISISMERGE   16
#define FTS5_DEFAULT_HASHSIZE    (1024*1024)

/* Maximum allowed page size */
#define FTS5_MAX_PAGE_SIZE (64*1024)
#define FTS5_MAX_PAGE_SIZE (128*1024)

static int fts5_iswhitespace(char x){
  return (x==' ');
}

static int fts5_isopenquote(char x){
  return (x=='"' || x=='\'' || x=='[' || x=='`');
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160







-
+







  int iOut = 0;
  q = z[0];

  /* Set stack variable q to the close-quote character */
  assert( q=='[' || q=='\'' || q=='"' || q=='`' );
  if( q=='[' ) q = ']';  

  while( z[iIn] ){
  while( ALWAYS(z[iIn]) ){
    if( z[iIn]==q ){
      if( z[iIn+1]!=q ){
        /* Character iIn was the close quote. */
        iIn++;
        break;
      }else{
        /* Character iIn and iIn+1 form an escaped quote character. Skip
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335







-
+







          }
        }
        if( p==0 ){
          *pzErr = sqlite3_mprintf("parse error in tokenize directive");
          rc = SQLITE_ERROR;
        }else{
          rc = sqlite3Fts5GetTokenizer(pGlobal, 
              (const char**)azArg, (int)nArg, pConfig,
              (const char**)azArg, (int)nArg, &pConfig->pTok, &pConfig->pTokApi,
              pzErr
          );
        }
      }
    }

    sqlite3_free(azArg);
393
394
395
396
397
398
399
400



401
402
403
404
405
406
407
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409







-
+
+
+







/*
** Allocate an instance of the default tokenizer ("simple") at 
** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error
** code if an error occurs.
*/
static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
  assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
  return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0);
  return sqlite3Fts5GetTokenizer(
      pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0
  );
}

/*
** Gobble up the first bareword or quoted word from the input buffer zIn.
** Return a pointer to the character immediately following the last in
** the gobbled word if successful, or a NULL pointer otherwise (failed
** to find close-quote character).
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
679
680
681
682
683
684
685

686
687
688
689
690
691
692
693







-
+







  );

  assert( zSql || rc==SQLITE_NOMEM );
  if( zSql ){
    rc = sqlite3_declare_vtab(pConfig->db, zSql);
    sqlite3_free(zSql);
  }
 
  
  return rc;
}

/*
** Tokenize the text passed via the second and third arguments.
**
** The callback is invoked once for each token in the input text. The
822
823
824
825
826
827
828
829

830
831
832
833
834
835
836
824
825
826
827
828
829
830

831
832
833
834
835
836
837
838







-
+







  int rc = SQLITE_OK;

  if( 0==sqlite3_stricmp(zKey, "pgsz") ){
    int pgsz = 0;
    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
      pgsz = sqlite3_value_int(pVal);
    }
    if( pgsz<32 || pgsz>FTS5_MAX_PAGE_SIZE ){
    if( pgsz<=0 || pgsz>FTS5_MAX_PAGE_SIZE ){
      *pbBadkey = 1;
    }else{
      pConfig->pgsz = pgsz;
    }
  }

  else if( 0==sqlite3_stricmp(zKey, "hashsize") ){
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
877
878
879
880
881
882
883

884
885
886
887
888
889
890







-







    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
      nCrisisMerge = sqlite3_value_int(pVal);
    }
    if( nCrisisMerge<0 ){
      *pbBadkey = 1;
    }else{
      if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
      if( nCrisisMerge>=FTS5_MAX_SEGMENT ) nCrisisMerge = FTS5_MAX_SEGMENT-1;
      pConfig->nCrisisMerge = nCrisisMerge;
    }
  }

  else if( 0==sqlite3_stricmp(zKey, "rank") ){
    const char *zIn = (const char*)sqlite3_value_text(pVal);
    char *zRank;

Changes to ext/fts5/fts5_expr.c.

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
124
125
126
127
128
129
130

131
132
133
134
135
136
137







-







struct Fts5Parse {
  Fts5Config *pConfig;
  char *zErr;
  int rc;
  int nPhrase;                    /* Size of apPhrase array */
  Fts5ExprPhrase **apPhrase;      /* Array of all phrases */
  Fts5ExprNode *pExpr;            /* Result of a successful parse */
  int bPhraseToAnd;               /* Convert "a+b" to "a AND b" */
};

void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
  va_list ap;
  va_start(ap, zFmt);
  if( pParse->rc==SQLITE_OK ){
    pParse->zErr = sqlite3_vmprintf(zFmt, ap);
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
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







-















-







}

static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);}
static void fts5ParseFree(void *p){ sqlite3_free(p); }

int sqlite3Fts5ExprNew(
  Fts5Config *pConfig,            /* FTS5 Configuration */
  int bPhraseToAnd,
  int iCol,
  const char *zExpr,              /* Expression text */
  Fts5Expr **ppNew, 
  char **pzErr
){
  Fts5Parse sParse;
  Fts5Token token;
  const char *z = zExpr;
  int t;                          /* Next token type */
  void *pEngine;
  Fts5Expr *pNew;

  *ppNew = 0;
  *pzErr = 0;
  memset(&sParse, 0, sizeof(sParse));
  sParse.bPhraseToAnd = bPhraseToAnd;
  pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
  if( pEngine==0 ){ return SQLITE_NOMEM; }
  sParse.pConfig = pConfig;

  do {
    t = fts5ExprGetToken(&sParse, &z, &token);
    sqlite3Fts5Parser(pEngine, t, token, &sParse);
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
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







-











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







      }else{
        pNew->pRoot = sParse.pExpr;
      }
      pNew->pIndex = 0;
      pNew->pConfig = pConfig;
      pNew->apExprPhrase = sParse.apPhrase;
      pNew->nPhrase = sParse.nPhrase;
      pNew->bDesc = 0;
      sParse.apPhrase = 0;
    }
  }else{
    sqlite3Fts5ParseNodeFree(sParse.pExpr);
  }

  sqlite3_free(sParse.apPhrase);
  *pzErr = sParse.zErr;
  return sParse.rc;
}

/*
** This function is only called when using the special 'trigram' tokenizer.
** Argument zText contains the text of a LIKE or GLOB pattern matched
** against column iCol. This function creates and compiles an FTS5 MATCH
** expression that will match a superset of the rows matched by the LIKE or
** GLOB. If successful, SQLITE_OK is returned. Otherwise, an SQLite error
** code.
*/
int sqlite3Fts5ExprPattern(
  Fts5Config *pConfig, int bGlob, int iCol, const char *zText, Fts5Expr **pp
){
  i64 nText = strlen(zText);
  char *zExpr = (char*)sqlite3_malloc64(nText*4 + 1);
  int rc = SQLITE_OK;

  if( zExpr==0 ){
    rc = SQLITE_NOMEM;
  }else{
    char aSpec[3];
    int iOut = 0;
    int i = 0;
    int iFirst = 0;

    if( bGlob==0 ){
      aSpec[0] = '_';
      aSpec[1] = '%';
      aSpec[2] = 0;
    }else{
      aSpec[0] = '*';
      aSpec[1] = '?';
      aSpec[2] = '[';
    }

    while( i<=nText ){
      if( i==nText 
       || zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2] 
      ){
        if( i-iFirst>=3 ){
          int jj;
          zExpr[iOut++] = '"';
          for(jj=iFirst; jj<i; jj++){
            zExpr[iOut++] = zText[jj];
            if( zText[jj]=='"' ) zExpr[iOut++] = '"';
          }
          zExpr[iOut++] = '"';
          zExpr[iOut++] = ' ';
        }
        if( zText[i]==aSpec[2] ){
          i += 2;
          if( zText[i-1]=='^' ) i++;
          while( i<nText && zText[i]!=']' ) i++;
        }
        iFirst = i+1;
      }
      i++;
    }
    if( iOut>0 ){
      int bAnd = 0;
      if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
        bAnd = 1;
        if( pConfig->eDetail==FTS5_DETAIL_NONE ){
          iCol = pConfig->nCol;
        }
      }
      zExpr[iOut] = '\0';
      rc = sqlite3Fts5ExprNew(pConfig, bAnd, iCol, zExpr, pp,pConfig->pzErrmsg);
    }else{
      *pp = 0;
    }
    sqlite3_free(zExpr);
  }

  return rc;
}

/*
** Free the expression node object passed as the only argument.
*/
void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){
  if( p ){
    int i;
    for(i=0; i<p->nChild; i++){
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
305
306
307
308
309
310
311




































312
313
314
315
316
317
318







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







  if( p ){
    sqlite3Fts5ParseNodeFree(p->pRoot);
    sqlite3_free(p->apExprPhrase);
    sqlite3_free(p);
  }
}

int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
  Fts5Parse sParse;
  memset(&sParse, 0, sizeof(sParse));

  if( *pp1 ){
    Fts5Expr *p1 = *pp1;
    int nPhrase = p1->nPhrase + p2->nPhrase;

    p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0);
    p2->pRoot = 0;

    if( sParse.rc==SQLITE_OK ){
      Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc(
          p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*)
      );
      if( ap==0 ){
        sParse.rc = SQLITE_NOMEM;
      }else{
        int i;
        memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*));
        for(i=0; i<p2->nPhrase; i++){
          ap[i] = p2->apExprPhrase[i];
        }
        p1->nPhrase = nPhrase;
        p1->apExprPhrase = ap;
      }
    }
    sqlite3_free(p2->apExprPhrase);
    sqlite3_free(p2);
  }else{
    *pp1 = p2;
  }

  return sParse.rc;
}

/*
** Argument pTerm must be a synonym iterator. Return the current rowid
** that it points to.
*/
static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
  i64 iRet = 0;
  int bRetValid = 0;
1496
1497
1498
1499
1500
1501
1502
1503
1504


1505
1506
1507
1508
1509
1510
1511
1381
1382
1383
1384
1385
1386
1387


1388
1389
1390
1391
1392
1393
1394
1395
1396







-
-
+
+







   && 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 );
  while( pRoot->bNomatch ){
    assert( pRoot->bEof==0 && rc==SQLITE_OK );
    rc = fts5ExprNodeNext(p, pRoot, 0, 0);
  }
  return rc;
}

/*
** Move to the next document 
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1621
1622
1623
1624
1625
1626
1627














1628
1629
1630
1631
1632
1633
1634







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







}

void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
  assert( pParse->pExpr==0 );
  pParse->pExpr = p;
}

static int parseGrowPhraseArray(Fts5Parse *pParse){
  if( (pParse->nPhrase % 8)==0 ){
    sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
    Fts5ExprPhrase **apNew;
    apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
    if( apNew==0 ){
      pParse->rc = SQLITE_NOMEM;
      return SQLITE_NOMEM;
    }
    pParse->apPhrase = apNew;
  }
  return SQLITE_OK;
}

/*
** This function is called by the parser to process a string token. The
** string may or may not be quoted. In any case it is tokenized and a
** phrase object consisting of all tokens returned.
*/
Fts5ExprPhrase *sqlite3Fts5ParseTerm(
  Fts5Parse *pParse,              /* Parse context */
1785
1786
1787
1788
1789
1790
1791


1792
1793
1794








1795
1796
1797
1798
1799
1800
1801
1656
1657
1658
1659
1660
1661
1662
1663
1664



1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679







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







  if( rc || (rc = sCtx.rc) ){
    pParse->rc = rc;
    fts5ExprPhraseFree(sCtx.pPhrase);
    sCtx.pPhrase = 0;
  }else{

    if( pAppend==0 ){
      if( (pParse->nPhrase % 8)==0 ){
        sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
      if( parseGrowPhraseArray(pParse) ){
        fts5ExprPhraseFree(sCtx.pPhrase);
        return 0;
        Fts5ExprPhrase **apNew;
        apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
        if( apNew==0 ){
          pParse->rc = SQLITE_NOMEM;
          fts5ExprPhraseFree(sCtx.pPhrase);
          return 0;
        }
        pParse->apPhrase = apNew;
      }
      pParse->nPhrase++;
    }

    if( sCtx.pPhrase==0 ){
      /* This happens when parsing a token or quoted phrase that contains
      ** no token characters at all. (e.g ... MATCH '""'). */
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2072
2073
2074
2075
2076
2077
2078





























































2079
2080
2081
2082
2083
2084
2085







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







    p->nChild += pSub->nChild;
    sqlite3_free(pSub);
  }else{
    p->apChild[p->nChild++] = pSub;
  }
}

/*
** This function is used when parsing LIKE or GLOB patterns against
** trigram indexes that specify either detail=column or detail=none.
** It converts a phrase:
**
**     abc + def + ghi
**
** into an AND tree:
**
**     abc AND def AND ghi
*/
static Fts5ExprNode *fts5ParsePhraseToAnd(
  Fts5Parse *pParse, 
  Fts5ExprNearset *pNear
){
  int nTerm = pNear->apPhrase[0]->nTerm;
  int ii;
  int nByte;
  Fts5ExprNode *pRet;

  assert( pNear->nPhrase==1 );
  assert( pParse->bPhraseToAnd );

  nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*);
  pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
  if( pRet ){
    pRet->eType = FTS5_AND;
    pRet->nChild = nTerm;
    fts5ExprAssignXNext(pRet);
    pParse->nPhrase--;
    for(ii=0; ii<nTerm; ii++){
      Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero(
          &pParse->rc, sizeof(Fts5ExprPhrase)
      );
      if( pPhrase ){
        if( parseGrowPhraseArray(pParse) ){
          fts5ExprPhraseFree(pPhrase);
        }else{
          pParse->apPhrase[pParse->nPhrase++] = pPhrase;
          pPhrase->nTerm = 1;
          pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup(
              &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1
          );
          pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 
              0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase)
          );
        }
      }
    }
  
    if( pParse->rc ){
      sqlite3Fts5ParseNodeFree(pRet);
      pRet = 0;
    }else{
      sqlite3Fts5ParseNearsetFree(pNear);
    }
  }

  return pRet;
}

/*
** Allocate and return a new expression object. If anything goes wrong (i.e.
** OOM error), leave an error code in pParse and return NULL.
*/
Fts5ExprNode *sqlite3Fts5ParseNode(
  Fts5Parse *pParse,              /* Parse context */
  int eType,                      /* FTS5_STRING, AND, OR or NOT */
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298







2299
2300
2301


2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315













2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336




















2337
2338
2339
2340
2341
2342
2343
2344
2096
2097
2098
2099
2100
2101
2102













2103
2104
2105
2106
2107
2108
2109
2110


2111
2112
2113













2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127




















2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147

2148
2149
2150
2151
2152
2153
2154







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

-
-
+
+

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

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







    assert( (eType!=FTS5_STRING && !pNear)
         || (eType==FTS5_STRING && !pLeft && !pRight)
    );
    if( eType==FTS5_STRING && pNear==0 ) return 0;
    if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
    if( eType!=FTS5_STRING && pRight==0 ) return pLeft;

    if( eType==FTS5_STRING 
     && pParse->bPhraseToAnd 
     && pNear->apPhrase[0]->nTerm>1
    ){
      pRet = fts5ParsePhraseToAnd(pParse, pNear);
    }else{
      if( eType==FTS5_NOT ){
        nChild = 2;
      }else if( eType==FTS5_AND || eType==FTS5_OR ){
        nChild = 2;
        if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
        if( pRight->eType==eType ) nChild += pRight->nChild-1;
      }
    if( eType==FTS5_NOT ){
      nChild = 2;
    }else if( eType==FTS5_AND || eType==FTS5_OR ){
      nChild = 2;
      if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
      if( pRight->eType==eType ) nChild += pRight->nChild-1;
    }

      nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
      pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
    nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
    pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);

      if( pRet ){
        pRet->eType = eType;
        pRet->pNear = pNear;
        fts5ExprAssignXNext(pRet);
        if( eType==FTS5_STRING ){
          int iPhrase;
          for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
            pNear->apPhrase[iPhrase]->pNode = pRet;
            if( pNear->apPhrase[iPhrase]->nTerm==0 ){
              pRet->xNext = 0;
              pRet->eType = FTS5_EOF;
            }
          }
    if( pRet ){
      pRet->eType = eType;
      pRet->pNear = pNear;
      fts5ExprAssignXNext(pRet);
      if( eType==FTS5_STRING ){
        int iPhrase;
        for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
          pNear->apPhrase[iPhrase]->pNode = pRet;
          if( pNear->apPhrase[iPhrase]->nTerm==0 ){
            pRet->xNext = 0;
            pRet->eType = FTS5_EOF;
          }
        }

          if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
            Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
            if( pNear->nPhrase!=1 
                || pPhrase->nTerm>1
                || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
              ){
              assert( pParse->rc==SQLITE_OK );
              pParse->rc = SQLITE_ERROR;
              assert( pParse->zErr==0 );
              pParse->zErr = sqlite3_mprintf(
                  "fts5: %s queries are not supported (detail!=full)", 
                  pNear->nPhrase==1 ? "phrase": "NEAR"
                  );
              sqlite3_free(pRet);
              pRet = 0;
            }
          }
        }else{
          fts5ExprAddChildren(pRet, pLeft);
          fts5ExprAddChildren(pRet, pRight);
        if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
          Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
          if( pNear->nPhrase!=1 
           || pPhrase->nTerm>1
           || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
          ){
            assert( pParse->rc==SQLITE_OK );
            pParse->rc = SQLITE_ERROR;
            assert( pParse->zErr==0 );
            pParse->zErr = sqlite3_mprintf(
                "fts5: %s queries are not supported (detail!=full)", 
                pNear->nPhrase==1 ? "phrase": "NEAR"
                );
            sqlite3_free(pRet);
            pRet = 0;
          }
        }
      }else{
        fts5ExprAddChildren(pRet, pLeft);
        fts5ExprAddChildren(pRet, pRight);
        }
      }
    }
  }

  if( pRet==0 ){
    assert( pParse->rc!=SQLITE_OK );
    sqlite3Fts5ParseNodeFree(pLeft);
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
2361
2362
2363
2364
2365
2366
2367


2368








2369

2370
2371
2372
2373
2374
2375
2376







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







  }else
  if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
    Fts5ExprNearset *pNear = pExpr->pNear;
    int i; 
    int iTerm;

    if( pNear->pColset ){
      int ii;
      Fts5Colset *pColset = pNear->pColset;
      int iCol = pNear->pColset->aiCol[0];
      if( pColset->nCol>1 ) zRet = fts5PrintfAppend(zRet, "{");
      for(ii=0; ii<pColset->nCol; ii++){
        zRet = fts5PrintfAppend(zRet, "%s%s", 
            pConfig->azCol[pColset->aiCol[ii]], ii==pColset->nCol-1 ? "" : " "
        );
      }
      if( zRet ){
        zRet = fts5PrintfAppend(zRet, "%s : ", pColset->nCol>1 ? "}" : "");
      zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]);
      }
      if( zRet==0 ) return 0;
    }

    if( pNear->nPhrase>1 ){
      zRet = fts5PrintfAppend(zRet, "NEAR(");
      if( zRet==0 ) return 0;
    }
2675
2676
2677
2678
2679
2680
2681
2682

2683
2684
2685
2686
2687
2688
2689
2690
2691

2692
2693
2694
2695
2696
2697
2698
2476
2477
2478
2479
2480
2481
2482

2483

2484
2485
2486

2487
2488
2489

2490
2491
2492
2493
2494
2495
2496
2497







-
+
-



-



-
+







    sqlite3_result_error_nomem(pCtx);
    return;
  }
  azConfig[0] = 0;
  azConfig[1] = "main";
  azConfig[2] = "tbl";
  for(i=3; iArg<nArg; iArg++){
    const char *z = (const char*)sqlite3_value_text(apVal[iArg]);
    azConfig[i++] = (const char*)sqlite3_value_text(apVal[iArg]);
    azConfig[i++] = (z ? z : "");
  }

  zExpr = (const char*)sqlite3_value_text(apVal[0]);
  if( zExpr==0 ) zExpr = "";

  rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
  if( rc==SQLITE_OK ){
    rc = sqlite3Fts5ExprNew(pConfig, 0, pConfig->nCol, zExpr, &pExpr, &zErr);
    rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
  }
  if( rc==SQLITE_OK ){
    char *zText;
    if( pExpr->pRoot->xNext==0 ){
      zText = sqlite3_mprintf("");
    }else if( bTcl ){
      zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot);

Changes to ext/fts5/fts5_hash.c.

302
303
304
305
306
307
308

309
310
311
312
313
314
315
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316







+








    p->iSzPoslist = p->nData;
    if( pHash->eDetail!=FTS5_DETAIL_NONE ){
      p->nData += 1;
      p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
    }

    nIncr += p->nData;
  }else{

    /* Appending to an existing hash-entry. Check that there is enough 
    ** space to append the largest possible new entry. Worst case scenario 
    ** is:
    **
    **     + 9 bytes for a new rowid,
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
335
336
337
338
339
340
341

342

343
344
345
346
347
348
349
350







-

-
+







  assert( (p->nAlloc - p->nData) >= (9 + 4 + 1 + 3 + 5) );

  pPtr = (u8*)p;

  /* If this is a new rowid, append the 4-byte size field for the previous
  ** entry, and the new rowid for this entry.  */
  if( iRowid!=p->iRowid ){
    u64 iDiff = (u64)iRowid - (u64)p->iRowid;
    fts5HashAddPoslistSize(pHash, p, 0);
    p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iDiff);
    p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
    p->iRowid = iRowid;
    bNew = 1;
    p->iSzPoslist = p->nData;
    if( pHash->eDetail!=FTS5_DETAIL_NONE ){
      p->nData += 1;
      p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
      p->iPos = 0;

Changes to ext/fts5/fts5_index.c.

235
236
237
238
239
240
241





242
243
244
245
246
247
248
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253







+
+
+
+
+







 ((i64)(height) << (FTS5_DATA_PAGE_B)) +                                       \
 ((i64)(pgno))                                                                 \
)

#define FTS5_SEGMENT_ROWID(segid, pgno)       fts5_dri(segid, 0, 0, pgno)
#define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)

/*
** Maximum segments permitted in a single index 
*/
#define FTS5_MAX_SEGMENT 2000

#ifdef SQLITE_DEBUG
int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
#endif


/*
** Each time a blob is read from the %_data table, it is padded with this
610
611
612
613
614
615
616
617

618
619
620
621
622
623
624
615
616
617
618
619
620
621

622
623
624
625
626
627
628
629







-
+







  fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret);
  return ret;
}

/*
** Close the read-only blob handle, if it is open.
*/
void sqlite3Fts5IndexCloseReader(Fts5Index *p){
static void fts5CloseReader(Fts5Index *p){
  if( p->pReader ){
    sqlite3_blob *pReader = p->pReader;
    p->pReader = 0;
    sqlite3_blob_close(pReader);
  }
}

639
640
641
642
643
644
645
646

647
648
649
650
651
652
653
644
645
646
647
648
649
650

651
652
653
654
655
656
657
658







-
+







      ** is required.  */
      sqlite3_blob *pBlob = p->pReader;
      p->pReader = 0;
      rc = sqlite3_blob_reopen(pBlob, iRowid);
      assert( p->pReader==0 );
      p->pReader = pBlob;
      if( rc!=SQLITE_OK ){
        sqlite3Fts5IndexCloseReader(p);
        fts5CloseReader(p);
      }
      if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
    }

    /* If the blob handle is not open at this point, open it and seek 
    ** to the requested entry.  */
    if( p->pReader==0 && rc==SQLITE_OK ){
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
686
687
688
689
690
691
692

693
694
695
696
697
698
699







-







      }
      if( rc!=SQLITE_OK ){
        sqlite3_free(pRet);
        pRet = 0;
      }else{
        /* TODO1: Fix this */
        pRet->p[nByte] = 0x00;
        pRet->p[nByte+1] = 0x00;
        pRet->szLeaf = fts5GetU16(&pRet->p[2]);
      }
    }
    p->rc = rc;
    p->nRead++;
  }

704
705
706
707
708
709
710
711

712
713
714
715
716
717
718
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722







-
+







static void fts5DataRelease(Fts5Data *pData){
  sqlite3_free(pData);
}

static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
  Fts5Data *pRet = fts5DataRead(p, iRowid);
  if( pRet ){
    if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){
    if( pRet->szLeaf>pRet->nn ){
      p->rc = FTS5_CORRUPT;
      fts5DataRelease(pRet);
      pRet = 0;
    }
  }
  return pRet;
}
984
985
986
987
988
989
990
991

992
993
994
995
996
997
998
988
989
990
991
992
993
994

995
996
997
998
999
1000
1001
1002







-
+







  Fts5Data *pData;

  pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
  if( p->rc==SQLITE_OK ){
    /* TODO: Do we need this if the leaf-index is appended? Probably... */
    memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
    p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
    if( p->rc==SQLITE_OK && (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
    if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
      p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
    }
    fts5DataRelease(pData);
    if( p->rc!=SQLITE_OK ){
      fts5StructureRelease(pRet);
      pRet = 0;
    }
1750
1751
1752
1753
1754
1755
1756
1757

1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772

1773
1774
1775
1776
1777
1778
1779
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







-
+














-
+








  if( n>pIter->iEndofDoclist ){
    n = pIter->iEndofDoclist;
  }

  ASSERT_SZLEAF_OK(pIter->pLeaf);
  while( 1 ){
    u64 iDelta = 0;
    i64 iDelta = 0;

    if( eDetail==FTS5_DETAIL_NONE ){
      /* todo */
      if( i<n && a[i]==0 ){
        i++;
        if( i<n && a[i]==0 ) i++;
      }
    }else{
      int nPos;
      int bDummy;
      i += fts5GetPoslistSize(&a[i], &nPos, &bDummy);
      i += nPos;
    }
    if( i>=n ) break;
    i += fts5GetVarint(&a[i], &iDelta);
    i += fts5GetVarint(&a[i], (u64*)&iDelta);
    pIter->iRowid += iDelta;

    /* If necessary, grow the pIter->aRowidOffset[] array. */
    if( iRowidOffset>=pIter->nRowidOffset ){
      int nNew = pIter->nRowidOffset + 8;
      int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int));
      if( aNew==0 ){
1864
1865
1866
1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
1879
1880

1881
1882
1883
1884
1885
1886
1887
1868
1869
1870
1871
1872
1873
1874

1875
1876
1877
1878
1879
1880
1881
1882
1883

1884
1885
1886
1887
1888
1889
1890
1891







-
+








-
+







  assert( pIter->flags & FTS5_SEGITER_REVERSE );
  assert( pIter->pNextLeaf==0 );
  UNUSED_PARAM(pbUnused);

  if( pIter->iRowidOffset>0 ){
    u8 *a = pIter->pLeaf->p;
    int iOff;
    u64 iDelta;
    i64 iDelta;

    pIter->iRowidOffset--;
    pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset];
    fts5SegIterLoadNPos(p, pIter);
    iOff = pIter->iLeafOffset;
    if( p->pConfig->eDetail!=FTS5_DETAIL_NONE ){
      iOff += pIter->nPos;
    }
    fts5GetVarint(&a[iOff], &iDelta);
    fts5GetVarint(&a[iOff], (u64*)&iDelta);
    pIter->iRowid -= iDelta;
  }else{
    fts5SegIterReverseNewPage(p, pIter);
  }
}

/*
2066
2067
2068
2069
2070
2071
2072
2073





2074
2075
2076

2077
2078
2079
2080
2081
2082
2083
2070
2071
2072
2073
2074
2075
2076

2077
2078
2079
2080
2081
2082
2083

2084
2085
2086
2087
2088
2089
2090
2091







-
+
+
+
+
+


-
+







        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.  */
      ** code is inlined. 
      **
      ** Later: Switched back to fts5SegIterLoadNPos() because it supports
      ** detail=none mode. Not ideal.
      */
      int nSz;
      assert( p->rc==SQLITE_OK );
      assert_nc( pIter->iLeafOffset<=pIter->pLeaf->nn );
      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 );
    }
  }
}
2313
2314
2315
2316
2317
2318
2319

2320

2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2321
2322
2323
2324
2325
2326
2327
2328

2329
2330
2331
2332

2333
2334
2335
2336
2337
2338
2339







+
-
+



-







          break;
        }
      }
    }while( 1 );
  }

 search_success:
  pIter->iLeafOffset = iOff + nNew;
  if( (i64)iOff+nNew>n || nNew<1 ){
  if( pIter->iLeafOffset>n || nNew<1 ){
    p->rc = FTS5_CORRUPT;
    return;
  }
  pIter->iLeafOffset = iOff + nNew;
  pIter->iTermLeafOffset = pIter->iLeafOffset;
  pIter->iTermLeafPgno = pIter->iLeafPgno;

  fts5BufferSet(&p->rc, &pIter->term, nKeep, pTerm);
  fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);

  if( iPgidx>=n ){
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
3069
3070
3071
3072
3073
3074
3075

3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088



3089
3090
3091
3092
3093
3094
3095







-
+












-
-
-







  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. */
  /* 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 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 ){
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
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







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




-
+


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

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







        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.
*/
** 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 */
  Fts5Iter *pIter
  Fts5Buffer *pBuf                /* Output buffer */
){
  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 i;
    int iCurrent = 0;

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

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

      const u8 *pSub = pPos;
      /* 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 ){
      int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
      if( nSub ){
          pIter->base.pData = aCopy;
          pIter->base.nData = p-aCopy;
          return;
        }
        fts5BufferSafeAppendBlob(&pIter->poslist, aCopy, p-aCopy);
        fts5BufferAppendBlob(pRc, pBuf, nSub, pSub);
      }
      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 );
3313
3314
3315
3316
3317
3318
3319




3320
3321
3322






3323
3324
3325
3326
3327
3328
3329
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322



3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335







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







  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);
      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;
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
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







-
+



















-
-
-








-
-
-
-
+
+
+
-







  }
}


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

  assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) );
  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;
    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);
  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
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
4888
4889
4890
4891
4892
4893
4894


4895
4896
4897
4898
4899
4900
4901

4902
4903


4904

4905
4906
4907
4908
4909
4910
4911







-
-
+






-
+

-
-

-







/*
** 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 */
  Fts5Buffer *p2                  /* Second list to merge */
){
  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) ){
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
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








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




-
-
+

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

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

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

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

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

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

-
-
-
+
+
-
-
+
-
-
-

+
+
+
-
+
+

+
-
-
+
+
-
-
+





-
-
+






-
+
-

-
+





-
-



















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




















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









-
-
+
-

-
+

-
-
+
-







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

** Buffers p1 and p2 contain doclists. This function merges the content
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;
  }
}


/*
** of the two doclists together and sets buffer p1 to the result before
** returning.
**
** Array aBuf[] contains nBuf doclists. These are all merged in with the
** doclist in buffer p1.
** 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 */
  int nBuf,                       /* Number of buffers in array aBuf[] */
  Fts5Buffer *aBuf                /* Other lists to merge in */ 
  Fts5Buffer *p2                  /* Second list to merge */
){
#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;
  if( p2->n ){
    i64 iLastRowid = 0;
    Fts5DoclistIter i1;
  int nOut = 0;
  Fts5Buffer out = {0, 0, 0};
  Fts5Buffer tmp = {0, 0, 0};
    Fts5DoclistIter i2;
    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.  
    /* 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 (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;
    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
    fts5DoclistIterInit(p1, &i1);
    fts5DoclistIterInit(p2, &i2);

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

    if( pHead->pNext && iLastRowid==pHead->pNext->iter.iRowid ){
      /* Merge data from two or more poslists */
    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;
      }
      else if( i2.iRowid!=i1.iRowid ){
        /* Copy entry from i2 */
      i64 iPrev = 0;
      int nTmp = FTS5_DATA_ZERO_PADDING;
      int nMerge = 0;
      PrefixMerger *pSave = pHead;
      PrefixMerger *pThis = 0;
      int nTail = 0;

      pHead = 0;
        fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
        fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
        fts5DoclistIterNext(&i2);
        if( i2.aPoslist==0 ) break;
      }
      else{
        /* Merge the two position lists. */ 
        i64 iPos1 = 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];
        i64 iPos2 = 0;
        int iOff1 = 0;
        int iOff2 = 0;
        u8 *a1 = &i1.aPoslist[i1.nSize];
        fts5PrefixMergerNextPosition(pSave);
        nTmp += pSave->iter.nPoslist + 10;
        nMerge++;
        fts5PrefixMergerInsertByPosition(&pHead, pSave);
        pSave = pNext;
      }
        u8 *a2 = &i2.aPoslist[i2.nSize];
        int nCopy;
        u8 *aCopy;

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

        fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
        fts5BufferZero(&tmp);
        sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist);
        if( p->rc ) break;

        sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
        sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
      if( pHead==0 || pHead->pNext==0 ){
        assert( iPos1>=0 && iPos2>=0 );
        p->rc = FTS5_CORRUPT;
        break;
      }


        if( iPos1<iPos2 ){
      /* 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;
      }
          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
          sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
        }else{
          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
          sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
        }
      fts5BufferZero(&tmp);

        if( iPos1>=0 && iPos2>=0 ){
      pThis = pHead;
          while( 1 ){
      pHead = pThis->pNext;
      sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos);
            if( iPos1<iPos2 ){
              if( iPos1!=iPrev ){
                sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
      fts5PrefixMergerNextPosition(pThis);
      fts5PrefixMergerInsertByPosition(&pHead, pThis);

      while( pHead->pNext ){
        pThis = pHead;
        if( pThis->iPos!=iPrev ){
          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos);
        }
              }
              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;
            }
        fts5PrefixMergerNextPosition(pThis);
        pHead = pThis->pNext;
        fts5PrefixMergerInsertByPosition(&pHead, pThis);
      }

      if( pHead->iPos!=iPrev ){
        sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos);
      }
      nTail = pHead->iter.nPoslist - pHead->iOff;

          }
        }

        if( iPos1>=0 ){
          if( iPos1!=iPrev ){
            sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
          }
          aCopy = &a1[iOff1];
          nCopy = i1.nPoslist - iOff1;
        }else{
      /* WRITEPOSLISTSIZE */
      assert( tmp.n+nTail<=nTmp );
      if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){
        if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
          assert( iPos2>=0 && iPos2!=iPrev );
          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
          aCopy = &a2[iOff2];
        break;
      }
          nCopy = i2.nPoslist - iOff2;
        }
      fts5BufferSafeAppendVarint(&out, (tmp.n+nTail) * 2);
      fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
      if( nTail>0 ){
        fts5BufferSafeAppendBlob(&out, &pHead->aPos[pHead->iOff], nTail);
      }
        if( nCopy>0 ){
          fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy);
        }

        /* WRITEPOSLISTSIZE */
        fts5BufferSafeAppendVarint(&out, tmp.n * 2);
      pHead = pSave;
        fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
      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);
        }
      }
        fts5DoclistIterNext(&i1);
        fts5DoclistIterNext(&i2);
        assert( out.n<=(p1->n+p2->n+9) );
        if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
      }
    }

    }else{
      /* Copy poslist from pHead to output */
      PrefixMerger *pThis = pHead;
    if( i1.aPoslist ){
      fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
      Fts5DoclistIter *pI = &pThis->iter;
      fts5BufferSafeAppendBlob(&out, pI->aPoslist, pI->nPoslist+pI->nSize);
      fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist);
      fts5DoclistIterNext(pI);
      pHead = pThis->pNext;
      fts5PrefixMergerInsertByRowid(&pHead, pThis);
    }
    else if( i2.aPoslist ){
      fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
      fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
  }
    }
    assert( out.n<=(p1->n+p2->n+9) );

    fts5BufferSet(&p->rc, p1, out.n, out.p);
  fts5BufferFree(p1);
  fts5BufferFree(&tmp);
    fts5BufferFree(&tmp);
    fts5BufferFree(&out);
  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 */
  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;
  int nBuf = 32;
  const int nBuf = 32;
  int nMerge = 1;

  void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
  void (*xMerge)(Fts5Index*, Fts5Buffer*, 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 );
          assert( i<nBuf );
          for(iStore=i1; iStore<i1+nMerge; iStore++){
            if( aBuf[iStore].n==0 ){
              fts5BufferSwap(&doclist, &aBuf[iStore]);
              fts5BufferZero(&doclist);
          if( aBuf[i].n==0 ){
            fts5BufferSwap(&doclist, &aBuf[i]);
            fts5BufferZero(&doclist);
              break;
            }
          }else{
          }
          if( iStore==i1+nMerge ){
            xMerge(p, &doclist, nMerge, &aBuf[i1]);
            xMerge(p, &doclist, &aBuf[i]);
            for(iStore=i1; iStore<i1+nMerge; iStore++){
              fts5BufferZero(&aBuf[iStore]);
            fts5BufferZero(&aBuf[i]);
            }
          }
        }
        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){
    for(i=0; i<nBuf; i++){
      int iFree;
      if( p->rc==SQLITE_OK ){
        xMerge(p, &doclist, nMerge, &aBuf[i]);
        xMerge(p, &doclist, &aBuf[i]);
      }
      for(iFree=i; iFree<i+nMerge; iFree++){
        fts5BufferFree(&aBuf[iFree]);
      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;
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
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







-
+










-
+














-








/*
** Commit data to disk.
*/
int sqlite3Fts5IndexSync(Fts5Index *p){
  assert( p->rc==SQLITE_OK );
  fts5IndexFlush(p);
  sqlite3Fts5IndexCloseReader(p);
  fts5CloseReader(p);
  return fts5IndexReturn(p);
}

/*
** Discard any data stored in the in-memory hash tables. Do not write it
** to the database. Additionally, assume that the contents of the %_data
** table may have changed on disk. So any in-memory caches of %_data 
** records must be invalidated.
*/
int sqlite3Fts5IndexRollback(Fts5Index *p){
  sqlite3Fts5IndexCloseReader(p);
  fts5CloseReader(p);
  fts5IndexDiscardData(p);
  fts5StructureInvalidate(p);
  /* assert( p->rc==SQLITE_OK ); */
  return SQLITE_OK;
}

/*
** The %_data table is completely empty when this function is called. This
** function populates it with the initial structure objects for each index,
** and the initial version of the "averages" record (a zero-byte blob).
*/
int sqlite3Fts5IndexReinit(Fts5Index *p){
  Fts5Structure s;
  fts5StructureInvalidate(p);
  fts5IndexDiscardData(p);
  memset(&s, 0, sizeof(Fts5Structure));
  fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
  fts5StructureWrite(p, &s);
  return fts5IndexReturn(p);
}

/*
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400

5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5300
5301
5302
5303
5304
5305
5306

5307
5308

5309



5310
5311
5312
5313
5314
5315
5316







-


-
+
-
-
-







  int nChar
){
  int n = 0;
  int i;
  for(i=0; i<nChar; i++){
    if( n>=nByte ) return 0;      /* Input contains fewer than nChar chars */
    if( (unsigned char)p[n++]>=0xc0 ){
      if( n>=nByte ) return 0;
      while( (p[n] & 0xc0)==0x80 ){
        n++;
        if( n>=nByte ){
        if( n>=nByte ) break;
          if( i+1==nChar ) break;
          return 0;
        }
      }
    }
  }
  return n;
}

/*
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5387
5388
5389
5390
5391
5392
5393

5394
5395
5396
5397
5398
5399
5400







-







  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.
    **
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
5537
5538
5539
5540
5541

5542
5543
5544
5545
5546
5547
5548
5408
5409
5410
5411
5412
5413
5414

5415


5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432

5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444

5445
5446
5447
5448
5449
5450
5451
5452







-
+
-
-
















+
-
+











-
+







      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( pConfig->aPrefix[iIdx-1]==nChar ) break;
        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;
      buf.p[0] = FTS5_MAIN_PREFIX;
      fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
      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);
      }
    }

    if( p->rc ){
      sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
      pRet = 0;
      sqlite3Fts5IndexCloseReader(p);
      fts5CloseReader(p);
    }

    *ppIter = (Fts5IndexIter*)pRet;
    sqlite3Fts5BufferFree(&buf);
  }
  return fts5IndexReturn(p);
}
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604

5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615

5616
5617
5618
5619
5620
5621
5622
5499
5500
5501
5502
5503
5504
5505

5506

5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517

5518
5519
5520
5521
5522
5523
5524
5525







-

-
+










-
+








/*
** 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);
  return &z[1];
}

/*
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
*/
void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
  if( pIndexIter ){
    Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
    Fts5Index *pIndex = pIter->pIndex;
    fts5MultiIterFree(pIter);
    sqlite3Fts5IndexCloseReader(pIndex);
    fts5CloseReader(pIndex);
  }
}

/*
** Read and decode the "averages" record from the database. 
**
** Parameter anSize must point to an array of size nCol, where nCol is
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5704
5705
5706
5707
5708
5709
5710































5711
5712
5713
5714
5715
5716
5717







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







  }
  sqlite3Fts5IterClose(pIter);

  *pCksum = cksum;
  return rc;
}

/*
** Check if buffer z[], size n bytes, contains as series of valid utf-8
** encoded codepoints. If so, return 0. Otherwise, if the buffer does not
** contain valid utf-8, return non-zero.
*/
static int fts5TestUtf8(const char *z, int n){
  int i = 0;
  assert_nc( n>0 );
  while( i<n ){
    if( (z[i] & 0x80)==0x00 ){
      i++;
    }else
    if( (z[i] & 0xE0)==0xC0 ){
      if( i+1>=n || (z[i+1] & 0xC0)!=0x80 ) return 1;
      i += 2;
    }else
    if( (z[i] & 0xF0)==0xE0 ){
      if( i+2>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1;
      i += 3;
    }else
    if( (z[i] & 0xF8)==0xF0 ){
      if( i+3>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1;
      if( (z[i+2] & 0xC0)!=0x80 ) return 1;
      i += 3;
    }else{
      return 1;
    }
  }

  return 0;
}

/*
** This function is also purely an internal test. It does not contribute to 
** FTS functionality, or even the integrity-check, in any way.
*/
static void fts5TestTerm(
  Fts5Index *p, 
5872
5873
5874
5875
5876
5877
5878
5879

5880
5881
5882
5883
5884
5885
5886

5887
5888
5889
5890
5891
5892
5893
5744
5745
5746
5747
5748
5749
5750

5751







5752
5753
5754
5755
5756
5757
5758
5759







-
+
-
-
-
-
-
-
-
+








    /* If this is a prefix query, check that the results returned if the
    ** the index is disabled are the same. In both ASC and DESC order. 
    **
    ** This check may only be performed if the hash table is empty. This
    ** is because the hash table only supports a single scan query at
    ** a time, and the multi-iter loop from which this function is called
    ** is already performing such a scan. 
    ** is already performing such a scan. */
    **
    ** Also only do this if buffer zTerm contains nTerm bytes of valid
    ** utf-8. Otherwise, the last part of the buffer contents might contain
    ** a non-utf-8 sequence that happens to be a prefix of a valid utf-8
    ** character stored in the main fts index, which will cause the
    ** test to fail.  */
    if( p->nPendingData==0 && 0==fts5TestUtf8(zTerm, nTerm) ){
    if( p->nPendingData==0 ){
      if( iIdx>0 && rc==SQLITE_OK ){
        int f = flags|FTS5INDEX_QUERY_TEST_NOIDX;
        ck2 = 0;
        rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
        if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
      }
      if( iIdx>0 && rc==SQLITE_OK ){
6002
6003
6004
6005
6006
6007
6008
6009

6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020

6021
6022
6023
6024
6025
6026
6027
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







-
+
-








-

+







  int rc2;
  int iIdxPrevLeaf = pSeg->pgnoFirst-1;
  int iDlidxPrevLeaf = pSeg->pgnoLast;

  if( pSeg->pgnoFirst==0 ) return;

  fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf(
      "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d "
      "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d",
      "ORDER BY 1, 2",
      pConfig->zDb, pConfig->zName, pSeg->iSegid
  ));

  /* Iterate through the b-tree hierarchy.  */
  while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
    i64 iRow;                     /* Rowid for this leaf */
    Fts5Data *pLeaf;              /* Data for this leaf */

    const char *zIdxTerm = (const char*)sqlite3_column_blob(pStmt, 1);
    int nIdxTerm = sqlite3_column_bytes(pStmt, 1);
    const char *zIdxTerm = (const char*)sqlite3_column_text(pStmt, 1);
    int iIdxLeaf = sqlite3_column_int(pStmt, 2);
    int bIdxDlidx = sqlite3_column_int(pStmt, 3);

    /* If the leaf in question has already been trimmed from the segment, 
    ** ignore this b-tree entry. Otherwise, load it into memory. */
    if( iIdxLeaf<pSeg->pgnoFirst ) continue;
    iRow = FTS5_SEGMENT_ROWID(pSeg->iSegid, iIdxLeaf);
6134
6135
6136
6137
6138
6139
6140
6141

6142
6143
6144
6145
6146
6147
6148
5999
6000
6001
6002
6003
6004
6005

6006
6007
6008
6009
6010
6011
6012
6013







-
+







** as calculated by sqlite3Fts5IndexEntryCksum() is cksum.
**
** Return SQLITE_CORRUPT if any of the internal checks fail, or if the
** checksum does not match. Return SQLITE_OK if all checks pass without
** error, or some other SQLite error code if another error (e.g. OOM)
** occurs.
*/
int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){
int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
  int eDetail = p->pConfig->eDetail;
  u64 cksum2 = 0;                 /* Checksum based on contents of indexes */
  Fts5Buffer poslist = {0,0,0};   /* Buffer used to hold a poslist */
  Fts5Iter *pIter;                /* Used to iterate through entire index */
  Fts5Structure *pStruct;         /* Index structure */

#ifdef SQLITE_DEBUG
6195
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
6060
6061
6062
6063
6064
6065
6066

6067
6068
6069
6070
6071
6072
6073
6074
6075
6076

6077
6078
6079
6080
6081
6082
6083
6084







-










-
+







    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);
      }
    }
  }
  fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);

  fts5MultiIterFree(pIter);
  if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
  if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;

  fts5StructureRelease(pStruct);
#ifdef SQLITE_DEBUG
  fts5BufferFree(&term);
#endif
  fts5BufferFree(&poslist);
  return fts5IndexReturn(p);

Changes to ext/fts5/fts5_main.c.

285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
285
286
287
288
289
290
291




292
293
294
295
296
297
298
299







-
-
-
-
+







      assert( iSavepoint<=p->ts.iSavepoint );
      p->ts.iSavepoint = iSavepoint-1;
      break;

    case FTS5_ROLLBACKTO:
      assert( p->ts.eState==1 );
      assert( iSavepoint>=-1 );
      /* The following assert() can fail if another vtab strikes an error
      ** within an xSavepoint() call then SQLite calls xRollbackTo() - without
      ** having called xSavepoint() on this vtab.  */
      /* assert( iSavepoint<=p->ts.iSavepoint ); */
      assert( iSavepoint<=p->ts.iSavepoint );
      p->ts.iSavepoint = iSavepoint;
      break;
  }
}
#else
# define fts5CheckTransactionState(x,y,z)
#endif
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
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







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




-
+

-
-
-
-
+
+
+

-
+




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







#endif
  {
    pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
  }
#endif
}

static int fts5UsePatternMatch(
  Fts5Config *pConfig, 
  struct sqlite3_index_constraint *p
){
  assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB );
  assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE );
  if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){
    return 1;
  }
  if( pConfig->ePattern==FTS5_PATTERN_LIKE 
   && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB)
  ){
    return 1;
  }
  return 0;
}

/*
** Implementation of the xBestIndex method for FTS5 tables. Within the 
** WHERE constraint, it searches for the following:
**
**   1. A MATCH constraint against the table column.
**   1. A MATCH constraint against the special column.
**   2. A MATCH constraint against the "rank" column.
**   3. A MATCH constraint against some other column.
**   4. An == constraint against the rowid column.
**   5. A < or <= constraint against the rowid column.
**   6. A > or >= constraint against the rowid column.
**   3. An == constraint against the rowid column.
**   4. A < or <= constraint against the rowid column.
**   5. A > or >= constraint against the rowid column.
**
** Within the ORDER BY, the following are supported:
** Within the ORDER BY, either:
**
**   5. ORDER BY rank [ASC|DESC]
**   6. ORDER BY rowid [ASC|DESC]
**
** Information for the xFilter call is passed via both the idxNum and 
** idxStr variables. Specifically, idxNum is a bitmask of the following
** flags used to encode the ORDER BY clause:
**
**     FTS5_BI_ORDER_RANK
**     FTS5_BI_ORDER_ROWID
**     FTS5_BI_ORDER_DESC
**
** idxStr is used to encode data from the WHERE clause. For each argument
** passed to the xFilter method, the following is appended to idxStr:
**
**   Match against table column:            "m"
**   Match against rank column:             "r"
**   Match against other column:            "M<column-number>"
**   LIKE  against other column:            "L<column-number>"
**   GLOB  against other column:            "G<column-number>"
**   Equality constraint against the rowid: "="
**   A < or <= against the rowid:           "<"
**   A > or >= against the rowid:           ">"
**
** This function ensures that there is at most one "r" or "=". And that if
** there exists an "=" then there is no "<" or ">".
**
** Costs are assigned as follows:
**
**  a) If an unusable MATCH operator is present in the WHERE clause, the
**     cost is unconditionally set to 1e50 (a really big number).
**
**  a) If a MATCH operator is present, the cost depends on the other
**     constraints also present. As follows:
543
544
545
546
547
548
549


550
551
552
553
554

















555
556
557
558



559
560
561

562
563
564
565
566
567
568
569
570
571
572
573
574
575

576
577
578
579
580
581
582
583

584
585


586
587
588




589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606

607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625

626
627
628
629



630
631
632
633
634

635
636
637
638
639

640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671







672
673











674
675
676
677
678
679
680
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







+
+


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

-
-
-
+
+
+
-
-
-
+







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



+
-
-
+
+


-
+
+
+
+



-
-

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




-




-
+













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

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







** Costs are not modified by the ORDER BY clause.
*/
static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
  Fts5Table *pTab = (Fts5Table*)pVTab;
  Fts5Config *pConfig = pTab->pConfig;
  const int nCol = pConfig->nCol;
  int idxFlags = 0;               /* Parameter passed through to xFilter() */
  int bHasMatch;
  int iNext;
  int i;

  char *idxStr;
  int iIdxStr = 0;
  int iCons = 0;
  struct Constraint {
    int op;                       /* Mask against sqlite3_index_constraint.op */
    int fts5op;                   /* FTS5 mask for idxFlags */
    int iCol;                     /* 0==rowid, 1==tbl, 2==rank */
    int omit;                     /* True to omit this if found */
    int iConsIndex;               /* Index in pInfo->aConstraint[] */
  } aConstraint[] = {
    {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, 
                                    FTS5_BI_MATCH,    1, 1, -1},
    {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, 
                                    FTS5_BI_RANK,     2, 1, -1},
    {SQLITE_INDEX_CONSTRAINT_EQ,    FTS5_BI_ROWID_EQ, 0, 0, -1},
    {SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE, 
                                    FTS5_BI_ROWID_LE, 0, 0, -1},
    {SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE, 
                                    FTS5_BI_ROWID_GE, 0, 0, -1},
  };

  int bSeenEq = 0;
  int bSeenGt = 0;
  int bSeenLt = 0;
  int aColMap[3];
  aColMap[0] = -1;
  aColMap[1] = nCol;
  int bSeenMatch = 0;
  int bSeenRank = 0;

  aColMap[2] = nCol+1;

  assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
  assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
  assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
  assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH );
  assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );

  if( pConfig->bLock ){
    pTab->base.zErrMsg = sqlite3_mprintf(
        "recursively defined fts5 content table"
    );
    return SQLITE_ERROR;
  }

  /* Set idxFlags flags for all WHERE clause terms that will be used. */
  idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1);
  if( idxStr==0 ) return SQLITE_NOMEM;
  pInfo->idxStr = idxStr;
  pInfo->needToFreeIdxStr = 1;

  for(i=0; i<pInfo->nConstraint; i++){
    struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
    int iCol = p->iColumn;

    if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH
     || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol)
    if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
     || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
    ){
      /* A MATCH operator or equivalent */
      if( p->usable==0 || iCol<0 ){
      if( p->usable ){
        idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
        aConstraint[0].iConsIndex = i;
      }else{
        /* As there exists an unusable MATCH constraint this is an 
        ** unusable plan. Set a prohibitively high cost. */
        pInfo->estimatedCost = 1e50;
        assert( iIdxStr < pInfo->nConstraint*6 + 1 );
        idxStr[iIdxStr] = 0;
        return SQLITE_OK;
      }else{
        if( iCol==nCol+1 ){
          if( bSeenRank ) continue;
          idxStr[iIdxStr++] = 'r';
          bSeenRank = 1;
        }else if( iCol>=0 ){
          bSeenMatch = 1;
          idxStr[iIdxStr++] = 'M';
          sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
          idxStr += strlen(&idxStr[iIdxStr]);
          assert( idxStr[iIdxStr]=='\0' );
        }
      }
        pInfo->aConstraintUsage[i].argvIndex = ++iCons;
        pInfo->aConstraintUsage[i].omit = 1;
      }
    }else if( p->usable ){
    }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){
      if( iCol>=0 && iCol<nCol && fts5UsePatternMatch(pConfig, p) ){
        assert( p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB );
        idxStr[iIdxStr++] = p->op==FTS5_PATTERN_LIKE ? 'L' : 'G';
        sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
        idxStr += strlen(&idxStr[iIdxStr]);
        pInfo->aConstraintUsage[i].argvIndex = ++iCons;
        assert( idxStr[iIdxStr]=='\0' );
      }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
        idxStr[iIdxStr++] = '=';
        bSeenEq = 1;
        pInfo->aConstraintUsage[i].argvIndex = ++iCons;
      }
    }
  }

      int j;
  if( bSeenEq==0 ){
    for(i=0; i<pInfo->nConstraint; i++){
      struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
      if( p->iColumn<0 && p->usable ){
      for(j=1; j<ArraySize(aConstraint); j++){
        struct Constraint *pC = &aConstraint[j];
        if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){
        int op = p->op;
        if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){
          if( bSeenLt ) continue;
          idxStr[iIdxStr++] = '<';
          pInfo->aConstraintUsage[i].argvIndex = ++iCons;
          pC->iConsIndex = i;
          bSeenLt = 1;
        }else
        if( op==SQLITE_INDEX_CONSTRAINT_GT || op==SQLITE_INDEX_CONSTRAINT_GE ){
          if( bSeenGt ) continue;
          idxStr[iIdxStr++] = '>';
          idxFlags |= pC->fts5op;
          pInfo->aConstraintUsage[i].argvIndex = ++iCons;
          bSeenGt = 1;
        }
      }
    }
  }
  idxStr[iIdxStr] = '\0';

  /* Set idxFlags flags for the ORDER BY clause */
  if( pInfo->nOrderBy==1 ){
    int iSort = pInfo->aOrderBy[0].iColumn;
    if( iSort==(pConfig->nCol+1) && bSeenMatch ){
    if( iSort==(pConfig->nCol+1) && BitFlagTest(idxFlags, FTS5_BI_MATCH) ){
      idxFlags |= FTS5_BI_ORDER_RANK;
    }else if( iSort==-1 ){
      idxFlags |= FTS5_BI_ORDER_ROWID;
    }
    if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
      pInfo->orderByConsumed = 1;
      if( pInfo->aOrderBy[0].desc ){
        idxFlags |= FTS5_BI_ORDER_DESC;
      }
    }
  }

  /* Calculate the estimated cost based on the flags set in idxFlags. */
  bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH);
  if( bSeenEq ){
    pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0;
    if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
  }else if( bSeenLt && bSeenGt ){
    pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0;
  }else if( bSeenLt || bSeenGt ){
    pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0;
  if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){
    pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0;
    if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo);
  }else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
    pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0;
  }else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
    pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0;
  }else{
    pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0;
    pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0;
  }

  /* Assign argvIndex values to each constraint in use. */
  iNext = 1;
  for(i=0; i<ArraySize(aConstraint); i++){
    struct Constraint *pC = &aConstraint[i];
    if( pC->iConsIndex>=0 ){
      pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
      pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
    }
  }

  pInfo->idxNum = idxFlags;
  return SQLITE_OK;
}

static int fts5NewTransaction(Fts5FullTable *pTab){
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
698
699
700
701
702
703
704

705
706
707
708
709
710
711







-







  sqlite3_free(pCsr->apRankArg);

  if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
    sqlite3_free(pCsr->zRank);
    sqlite3_free(pCsr->zRankArgs);
  }

  sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
  memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr));
}


/*
** Close the cursor.  For additional information see the documentation
** on the xClose method of the virtual table interface.
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
848
849
850
851
852
853
854

855


856

857
858
859





860
861
862
863

864
865
866
867
868
869
870







-
+
-
-

-



-
-
-
-
-




-







      }
  
      case FTS5_PLAN_SORTED_MATCH: {
        rc = fts5SorterNext(pCsr);
        break;
      }
  
      default: {
      default:
        Fts5Config *pConfig = ((Fts5Table*)pCursor->pVtab)->pConfig;
        pConfig->bLock++;
        rc = sqlite3_step(pCsr->pStmt);
        pConfig->bLock--;
        if( rc!=SQLITE_ROW ){
          CsrFlagSet(pCsr, FTS5CSR_EOF);
          rc = sqlite3_reset(pCsr->pStmt);
          if( rc!=SQLITE_OK ){
            pCursor->pVtab->zErrMsg = sqlite3_mprintf(
                "%s", sqlite3_errmsg(pConfig->db)
            );
          }
        }else{
          rc = SQLITE_OK;
        }
        break;
      }
    }
  }
  
  return rc;
}


999
1000
1001
1002
1003
1004
1005
1006

1007
1008
1009
1010
1011
1012
1013
921
922
923
924
925
926
927

928
929
930
931
932
933
934
935







-
+







  ** handles here, rather than preparing a new one for each query. But that
  ** is not possible as SQLite reference counts the virtual table objects.
  ** And since the statement required here reads from this very virtual 
  ** table, saving it creates a circular reference.
  **
  ** If SQLite a built-in statement cache, this wouldn't be a problem. */
  rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
      "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s",
      "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
      pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
      (zRankArgs ? ", " : ""),
      (zRankArgs ? zRankArgs : ""),
      bDesc ? "DESC" : "ASC"
  );

  pCsr->pSorter = pSorter;
1055
1056
1057
1058
1059
1060
1061
1062

1063
1064
1065

1066
1067
1068
1069
1070
1071
1072
977
978
979
980
981
982
983

984
985
986

987
988
989
990
991
992
993
994







-
+


-
+








  while( z[0]==' ' ) z++;
  for(n=0; z[n] && z[n]!=' '; n++);

  assert( pTab->p.base.zErrMsg==0 );
  pCsr->ePlan = FTS5_PLAN_SPECIAL;

  if( n==5 && 0==sqlite3_strnicmp("reads", z, n) ){
  if( 0==sqlite3_strnicmp("reads", z, n) ){
    pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex);
  }
  else if( n==2 && 0==sqlite3_strnicmp("id", z, n) ){
  else if( 0==sqlite3_strnicmp("id", z, n) ){
    pCsr->iSpecial = pCsr->iCsrId;
  }
  else{
    /* An unrecognized directive. Return an error message. */
    pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
    rc = SQLITE_ERROR;
  }
1199
1200
1201
1202
1203
1204
1205
1206

1207
1208
1209
1210
1211
1212
1213

1214
1215

1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229


1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253







1254
1255

1256
1257
1258
1259
1260
1261
1262
1263

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

1280
1281
1282
1283
1284
1285
1286

1287
1288
1289
1290
1291
1292

1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
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







-
+







+


+






-
-
-

-
-
-
-
+
+
-
-












-




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







**   1. Full-text search using a MATCH operator.
**   2. A by-rowid lookup.
**   3. A full-table scan.
*/
static int fts5FilterMethod(
  sqlite3_vtab_cursor *pCursor,   /* The cursor used for this query */
  int idxNum,                     /* Strategy index */
  const char *idxStr,             /* Unused */
  const char *zUnused,            /* Unused */
  int nVal,                       /* Number of elements in apVal */
  sqlite3_value **apVal           /* Arguments for the indexing scheme */
){
  Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
  Fts5Config *pConfig = pTab->p.pConfig;
  Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
  int rc = SQLITE_OK;             /* Error code */
  int iVal = 0;                   /* Counter for apVal[] */
  int bDesc;                      /* True if ORDER BY [rank|rowid] DESC */
  int bOrderByRank;               /* True if ORDER BY rank */
  sqlite3_value *pMatch = 0;      /* <tbl> MATCH ? expression (or NULL) */
  sqlite3_value *pRank = 0;       /* rank MATCH ? expression (or NULL) */
  sqlite3_value *pRowidEq = 0;    /* rowid = ? expression (or NULL) */
  sqlite3_value *pRowidLe = 0;    /* rowid <= ? expression (or NULL) */
  sqlite3_value *pRowidGe = 0;    /* rowid >= ? expression (or NULL) */
  int iCol;                       /* Column on LHS of MATCH operator */
  char **pzErrmsg = pConfig->pzErrmsg;
  int i;
  int iIdxStr = 0;
  Fts5Expr *pExpr = 0;

  if( pConfig->bLock ){
    pTab->p.base.zErrMsg = sqlite3_mprintf(
        "recursively defined fts5 content table"
    );
  UNUSED_PARAM(zUnused);
  UNUSED_PARAM(nVal);
    return SQLITE_ERROR;
  }

  if( pCsr->ePlan ){
    fts5FreeCursorComponents(pCsr);
    memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
  }

  assert( pCsr->pStmt==0 );
  assert( pCsr->pExpr==0 );
  assert( pCsr->csrflags==0 );
  assert( pCsr->pRank==0 );
  assert( pCsr->zRank==0 );
  assert( pCsr->zRankArgs==0 );
  assert( pTab->pSortCsr==0 || nVal==0 );

  assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
  pConfig->pzErrmsg = &pTab->p.base.zErrMsg;

  /* Decode the arguments passed through to this function. */
  for(i=0; i<nVal; i++){
    switch( idxStr[iIdxStr++] ){
      case 'r':
        pRank = apVal[i];
  /* Decode the arguments passed through to this function.
  **
  ** Note: The following set of if(...) statements must be in the same
  ** order as the corresponding entries in the struct at the top of
  ** fts5BestIndexMethod().  */
  if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++];
  if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++];
        break;
      case 'M': {
  if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
        const char *zText = (const char*)sqlite3_value_text(apVal[i]);
        if( zText==0 ) zText = "";
        iCol = 0;
        do{
          iCol = iCol*10 + (idxStr[iIdxStr]-'0');
          iIdxStr++;
        }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );

  if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
        if( zText[0]=='*' ){
          /* The user has issued a query of the form "MATCH '*...'". This
          ** indicates that the MATCH expression is not a full text query,
          ** but a request for an internal parameter.  */
          rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
          goto filter_out;
        }else{
          char **pzErr = &pTab->p.base.zErrMsg;
          rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr);
          if( rc==SQLITE_OK ){
            rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
            pExpr = 0;
          }
          if( rc!=SQLITE_OK ) goto filter_out;
        }

  if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
        break;
      }
      case 'L':
      case 'G': {
        int bGlob = (idxStr[iIdxStr-1]=='G');
        const char *zText = (const char*)sqlite3_value_text(apVal[i]);
        iCol = 0;
  iCol = (idxNum>>16);
        do{
          iCol = iCol*10 + (idxStr[iIdxStr]-'0');
          iIdxStr++;
        }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
        if( zText ){
          rc = sqlite3Fts5ExprPattern(pConfig, bGlob, iCol, zText, &pExpr);
  assert( iCol>=0 && iCol<=pConfig->nCol );
        }
        if( rc==SQLITE_OK ){
          rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
          pExpr = 0;
        }
        if( rc!=SQLITE_OK ) goto filter_out;
        break;
      }
      case '=':
        pRowidEq = apVal[i];
        break;
      case '<':
        pRowidLe = apVal[i];
        break;
      default: assert( idxStr[iIdxStr-1]=='>' );
  assert( iVal==nVal );
        pRowidGe = apVal[i];
        break;
    }
  }
  bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
  pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);

  /* Set the cursor upper and lower rowid limits. Only some strategies 
  ** actually use them. This is ok, as the xBestIndex() method leaves the
  ** sqlite3_index_constraint.omit flag clear for range constraints
  ** on the rowid field.  */
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
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







-
+












-
+
+
+
+


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
















-
+








-
-







    /* If pSortCsr is non-NULL, then this call is being made as part of 
    ** processing for a "... MATCH <expr> ORDER BY rank" query (ePlan is
    ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will
    ** return results to the user for this query. The current cursor 
    ** (pCursor) is used to execute the query issued by function 
    ** fts5CursorFirstSorted() above.  */
    assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
    assert( nVal==0 && bOrderByRank==0 && bDesc==0 );
    assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
    assert( pCsr->iLastRowid==LARGEST_INT64 );
    assert( pCsr->iFirstRowid==SMALLEST_INT64 );
    if( pTab->pSortCsr->bDesc ){
      pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid;
      pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid;
    }else{
      pCsr->iLastRowid = pTab->pSortCsr->iLastRowid;
      pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid;
    }
    pCsr->ePlan = FTS5_PLAN_SOURCE;
    pCsr->pExpr = pTab->pSortCsr->pExpr;
    rc = fts5CursorFirst(pTab, pCsr, bDesc);
  }else if( pCsr->pExpr ){
  }else if( pMatch ){
    const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
    if( zExpr==0 ) zExpr = "";

    rc = fts5CursorParseRank(pConfig, pCsr, pRank);
    if( rc==SQLITE_OK ){
      if( zExpr[0]=='*' ){
        /* The user has issued a query of the form "MATCH '*...'". This
        ** indicates that the MATCH expression is not a full text query,
        ** but a request for an internal parameter.  */
        rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
      }else{
        char **pzErr = &pTab->p.base.zErrMsg;
        rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
        if( rc==SQLITE_OK ){
      if( bOrderByRank ){
        pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
        rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
      }else{
        pCsr->ePlan = FTS5_PLAN_MATCH;
        rc = fts5CursorFirst(pTab, pCsr, bDesc);
          if( bOrderByRank ){
            pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
            rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
          }else{
            pCsr->ePlan = FTS5_PLAN_MATCH;
            rc = fts5CursorFirst(pTab, pCsr, bDesc);
          }
        }
      }
    }
  }else if( pConfig->zContent==0 ){
    *pConfig->pzErrmsg = sqlite3_mprintf(
        "%s: table does not support scanning", pConfig->zName
    );
    rc = SQLITE_ERROR;
  }else{
    /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup
    ** by rowid (ePlan==FTS5_PLAN_ROWID).  */
    pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
    rc = sqlite3Fts5StorageStmt(
        pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
    );
    if( rc==SQLITE_OK ){
      if( pCsr->ePlan==FTS5_PLAN_ROWID ){
        sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
        sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
      }else{
        sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
        sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
      }
      rc = fts5NextMethod(pCursor);
    }
  }

 filter_out:
  sqlite3Fts5ExprFree(pExpr);
  pConfig->pzErrmsg = pzErrmsg;
  return rc;
}

/* 
** This is the xEof method of the virtual table. SQLite calls this 
** routine to find out if it has reached the end of a result set.
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
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







-



-

-







-
-
-
-







        pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->p.base.zErrMsg:0)
    );
    assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 );
    assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
  }

  if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){
    Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
    assert( pCsr->pExpr );
    sqlite3_reset(pCsr->pStmt);
    sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr));
    pTab->pConfig->bLock++;
    rc = sqlite3_step(pCsr->pStmt);
    pTab->pConfig->bLock--;
    if( rc==SQLITE_ROW ){
      rc = SQLITE_OK;
      CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT);
    }else{
      rc = sqlite3_reset(pCsr->pStmt);
      if( rc==SQLITE_OK ){
        rc = FTS5_CORRUPT;
      }else if( pTab->pConfig->pzErrmsg ){
        *pTab->pConfig->pzErrmsg = sqlite3_mprintf(
            "%s", sqlite3_errmsg(pTab->pConfig->db)
        );
      }
    }
  }
  return rc;
}

static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){
1541
1542
1543
1544
1545
1546
1547
1548
1549

1550
1551
1552
1553
1554
1555
1556
1412
1413
1414
1415
1416
1417
1418


1419
1420
1421
1422
1423
1424
1425
1426







-
-
+







    }
  }else if( 0==sqlite3_stricmp("optimize", zCmd) ){
    rc = sqlite3Fts5StorageOptimize(pTab->pStorage);
  }else if( 0==sqlite3_stricmp("merge", zCmd) ){
    int nMerge = sqlite3_value_int(pVal);
    rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
  }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
    int iArg = sqlite3_value_int(pVal);
    rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, iArg);
    rc = sqlite3Fts5StorageIntegrity(pTab->pStorage);
#ifdef SQLITE_DEBUG
  }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
    pConfig->bPrefixIndex = sqlite3_value_int(pVal);
#endif
  }else{
    rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
    if( rc==SQLITE_OK ){
2173
2174
2175
2176
2177
2178
2179
2180
2181

2182
2183
2184
2185
2186
2187
2188
2043
2044
2045
2046
2047
2048
2049


2050
2051
2052
2053
2054
2055
2056
2057







-
-
+







  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);
    pIter->b = &pIter->a[n];
    *piCol = 0;
    *piOff = 0;
    fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
  }
  return rc;
}

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
2102
2103
2104
2105
2106
2107
2108


2109
2110
2111
2112
2113
2114
2115
2116


2117
2118
2119
2120
2121
2122
2123
2124







-
-
+







-
-
+







      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);
      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 ){
      assert( pIter->a || n==0 );
      pIter->b = (pIter->a ? &pIter->a[n] : 0);
      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;
      }
2361
2362
2363
2364
2365
2366
2367
2368

2369
2370
2371
2372
2373
2374
2375
2228
2229
2230
2231
2232
2233
2234

2235
2236
2237
2238
2239
2240
2241
2242







-
+







  i64 iCsrId;

  assert( argc>=1 );
  pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
  iCsrId = sqlite3_value_int64(argv[0]);

  pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
  if( pCsr==0 || pCsr->ePlan==0 ){
  if( pCsr==0 ){
    char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
    sqlite3_result_error(context, zErr, -1);
    sqlite3_free(zErr);
  }else{
    fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
  }
}
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2364
2365
2366
2367
2368
2369
2370

2371
2372
2373
2374

2375
2376
2377
2378
2379
2380
2381







-




-







     || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
    ){
      if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
        fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
      }
    }
  }else if( !fts5IsContentless(pTab) ){
    pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
    rc = fts5SeekCursor(pCsr, 1);
    if( rc==SQLITE_OK ){
      sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
    }
    pConfig->pzErrmsg = 0;
  }
  return rc;
}


/*
** This routine implements the xFindFunction method for the FTS3
2708
2709
2710
2711
2712
2713
2714
2715


2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727

2728
2729
2730
2731
2732



2733
2734
2735
2736
2737
2738
2739
2740
2741
2742


2743
2744
2745
2746
2747
2748
2749
2573
2574
2575
2576
2577
2578
2579

2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592

2593





2594
2595
2596




2597
2598
2599
2600


2601
2602
2603
2604
2605
2606
2607
2608
2609







-
+
+











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




-
-
+
+







  return rc;
}

int sqlite3Fts5GetTokenizer(
  Fts5Global *pGlobal, 
  const char **azArg,
  int nArg,
  Fts5Config *pConfig,
  Fts5Tokenizer **ppTok,
  fts5_tokenizer **ppTokApi,
  char **pzErr
){
  Fts5TokenizerModule *pMod;
  int rc = SQLITE_OK;

  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(
    rc = pMod->x.xCreate(pMod->pUserData, &azArg[1], (nArg?nArg-1:0), ppTok);
        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");
    *ppTokApi = &pMod->x;
    if( rc!=SQLITE_OK && pzErr ){
      *pzErr = sqlite3_mprintf("error in tokenizer constructor");
    }else{
      pConfig->ePattern = sqlite3Fts5TokenizerPattern(
          pMod->x.xCreate, pConfig->pTok
      );
    }
  }

  if( rc!=SQLITE_OK ){
    pConfig->pTokApi = 0;
    pConfig->pTok = 0;
    *ppTokApi = 0;
    *ppTok = 0;
  }

  return rc;
}

static void fts5ModuleDestroy(void *pCtx){
  Fts5TokenizerModule *pTok, *pNextTok;

Changes to ext/fts5/fts5_storage.c.

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
134
135
136
137
138
139
140

141

142
143
144
145
146
147
148







-

-







    }

    if( zSql==0 ){
      rc = SQLITE_NOMEM;
    }else{
      int f = SQLITE_PREPARE_PERSISTENT;
      if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
      p->pConfig->bLock++;
      rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
      p->pConfig->bLock--;
      sqlite3_free(zSql);
      if( rc!=SQLITE_OK && pzErrMsg ){
        *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
      }
    }
  }

425
426
427
428
429
430
431
432
433
434
435


436
437
438
439
440

441
442
443
444
445
446
447
448
423
424
425
426
427
428
429




430
431





432

433
434
435
436
437
438
439







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







        nText = sqlite3_value_bytes(apVal[iCol-1]);
      }
      ctx.szCol = 0;
      rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, 
          zText, nText, (void*)&ctx, fts5StorageInsertCallback
      );
      p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
      if( p->aTotalSize[iCol-1]<0 ){
        rc = FTS5_CORRUPT;
      }
    }
    }
  }
  }
  if( rc==SQLITE_OK && p->nTotalRow<1 ){
    rc = FTS5_CORRUPT;
  }else{
    p->nTotalRow--;
  p->nTotalRow--;
  }

  rc2 = sqlite3_reset(pSeek);
  if( rc==SQLITE_OK ) rc = rc2;
  return rc;
}


563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
554
555
556
557
558
559
560


561
562
563
564
565
566
567







-
-







/*
** Delete all entries in the FTS5 index.
*/
int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
  Fts5Config *pConfig = p->pConfig;
  int rc;

  p->bTotalsValid = 0;

  /* Delete the contents of the %_data and %_docsize tables. */
  rc = fts5ExecPrintf(pConfig->db, 0,
      "DELETE FROM %Q.'%q_data';" 
      "DELETE FROM %Q.'%q_idx';",
      pConfig->zDb, pConfig->zName,
      pConfig->zDb, pConfig->zName
  );
616
617
618
619
620
621
622
623
624
625
626
627


628
629
630
631
632
633
634
605
606
607
608
609
610
611


612
613

614
615
616
617
618
619
620
621
622







-
-


-
+
+







    i64 iRowid = sqlite3_column_int64(pScan, 0);

    sqlite3Fts5BufferZero(&buf);
    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
    for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
      ctx.szCol = 0;
      if( pConfig->abUnindexed[ctx.iCol]==0 ){
        const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1);
        int nText = sqlite3_column_bytes(pScan, ctx.iCol+1);
        rc = sqlite3Fts5Tokenize(pConfig, 
            FTS5_TOKENIZE_DOCUMENT,
            zText, nText,
            (const char*)sqlite3_column_text(pScan, ctx.iCol+1),
            sqlite3_column_bytes(pScan, ctx.iCol+1),
            (void*)&ctx,
            fts5StorageInsertCallback
        );
      }
      sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
      p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
    }
742
743
744
745
746
747
748
749
750
751
752
753


754
755
756
757
758
759
760
730
731
732
733
734
735
736


737
738

739
740
741
742
743
744
745
746
747







-
-


-
+
+








  if( rc==SQLITE_OK ){
    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
  }
  for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
    ctx.szCol = 0;
    if( pConfig->abUnindexed[ctx.iCol]==0 ){
      const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]);
      int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]);
      rc = sqlite3Fts5Tokenize(pConfig, 
          FTS5_TOKENIZE_DOCUMENT,
          zText, nText,
          (const char*)sqlite3_value_text(apVal[ctx.iCol+2]),
          sqlite3_value_bytes(apVal[ctx.iCol+2]),
          (void*)&ctx,
          fts5StorageInsertCallback
      );
    }
    sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
    p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
  }
877
878
879
880
881
882
883
884

885
886

887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926























927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952

























953
954
955
956
957
958
959
960
961








962
963
964
965
966
967
968
969
970
971
972
973











974
975
976
977
978
979
980
981

982
983
984
985
986
987
988
864
865
866
867
868
869
870

871
872

873
874
875
876
877

878
879
880
881
882
883
884
885



























886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908


























909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934








935
936
937
938
939
940
941
942
943











944
945
946
947
948
949
950
951
952
953
954

955
956
957
958
959
960

961
962
963
964
965
966
967
968







-
+

-
+




-








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

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

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






-
+








/*
** Check that the contents of the FTS index match that of the %_content
** table. Return SQLITE_OK if they do, or SQLITE_CORRUPT if not. Return
** some other SQLite error code if an error occurs while attempting to
** determine this.
*/
int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
  Fts5Config *pConfig = p->pConfig;
  int rc = SQLITE_OK;             /* Return code */
  int rc;                         /* Return code */
  int *aColSize;                  /* Array of size pConfig->nCol */
  i64 *aTotalSize;                /* Array of size pConfig->nCol */
  Fts5IntegrityCtx ctx;
  sqlite3_stmt *pScan;
  int bUseCksum;

  memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
  ctx.pConfig = p->pConfig;
  aTotalSize = (i64*)sqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64)));
  if( !aTotalSize ) return SQLITE_NOMEM;
  aColSize = (int*)&aTotalSize[pConfig->nCol];
  memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);

  bUseCksum = (pConfig->eContent==FTS5_CONTENT_NORMAL
           || (pConfig->eContent==FTS5_CONTENT_EXTERNAL && iArg)
  );
  if( bUseCksum ){
    /* Generate the expected index checksum based on the contents of the
    ** %_content table. This block stores the checksum in ctx.cksum. */
    rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
    if( rc==SQLITE_OK ){
      int rc2;
      while( SQLITE_ROW==sqlite3_step(pScan) ){
        int i;
        ctx.iRowid = sqlite3_column_int64(pScan, 0);
        ctx.szCol = 0;
        if( pConfig->bColumnsize ){
          rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
        }
        if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
          rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
        }
        for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
          if( pConfig->abUnindexed[i] ) continue;
          ctx.iCol = i;
          ctx.szCol = 0;
          if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
            rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
          }
          if( rc==SQLITE_OK ){
  /* Generate the expected index checksum based on the contents of the
  ** %_content table. This block stores the checksum in ctx.cksum. */
  rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
  if( rc==SQLITE_OK ){
    int rc2;
    while( SQLITE_ROW==sqlite3_step(pScan) ){
      int i;
      ctx.iRowid = sqlite3_column_int64(pScan, 0);
      ctx.szCol = 0;
      if( pConfig->bColumnsize ){
        rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
      }
      if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
        rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
      }
      for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
        if( pConfig->abUnindexed[i] ) continue;
        ctx.iCol = i;
        ctx.szCol = 0;
        if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
          rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
        }
        if( rc==SQLITE_OK ){
            const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
            int nText = sqlite3_column_bytes(pScan, i+1);
            rc = sqlite3Fts5Tokenize(pConfig, 
                FTS5_TOKENIZE_DOCUMENT,
                zText, nText,
                (void*)&ctx,
                fts5StorageIntegrityCallback
            );
          }
          if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
            rc = FTS5_CORRUPT;
          }
          aTotalSize[i] += ctx.szCol;
          if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
            sqlite3Fts5TermsetFree(ctx.pTermset);
            ctx.pTermset = 0;
          }
        }
        sqlite3Fts5TermsetFree(ctx.pTermset);
        ctx.pTermset = 0;
  
        if( rc!=SQLITE_OK ) break;
      }
      rc2 = sqlite3_reset(pScan);
      if( rc==SQLITE_OK ) rc = rc2;
    }
          rc = sqlite3Fts5Tokenize(pConfig, 
              FTS5_TOKENIZE_DOCUMENT,
              (const char*)sqlite3_column_text(pScan, i+1),
              sqlite3_column_bytes(pScan, i+1),
              (void*)&ctx,
              fts5StorageIntegrityCallback
          );
        }
        if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
          rc = FTS5_CORRUPT;
        }
        aTotalSize[i] += ctx.szCol;
        if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
          sqlite3Fts5TermsetFree(ctx.pTermset);
          ctx.pTermset = 0;
        }
      }
      sqlite3Fts5TermsetFree(ctx.pTermset);
      ctx.pTermset = 0;

      if( rc!=SQLITE_OK ) break;
    }
    rc2 = sqlite3_reset(pScan);
    if( rc==SQLITE_OK ) rc = rc2;
  }

    /* Test that the "totals" (sometimes called "averages") record looks Ok */
    if( rc==SQLITE_OK ){
      int i;
      rc = fts5StorageLoadTotals(p, 0);
      for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
        if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
      }
    }
  /* Test that the "totals" (sometimes called "averages") record looks Ok */
  if( rc==SQLITE_OK ){
    int i;
    rc = fts5StorageLoadTotals(p, 0);
    for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
      if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
    }
  }

    /* Check that the %_docsize and %_content tables contain the expected
    ** number of rows.  */
    if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
      i64 nRow = 0;
      rc = fts5StorageCount(p, "content", &nRow);
      if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
    }
    if( rc==SQLITE_OK && pConfig->bColumnsize ){
      i64 nRow = 0;
      rc = fts5StorageCount(p, "docsize", &nRow);
      if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
  /* Check that the %_docsize and %_content tables contain the expected
  ** number of rows.  */
  if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
    i64 nRow = 0;
    rc = fts5StorageCount(p, "content", &nRow);
    if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
  }
  if( rc==SQLITE_OK && pConfig->bColumnsize ){
    i64 nRow = 0;
    rc = fts5StorageCount(p, "docsize", &nRow);
    if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
    }
  }

  /* Pass the expected checksum down to the FTS index module. It will
  ** verify, amongst other things, that it matches the checksum generated by
  ** inspecting the index itself.  */
  if( rc==SQLITE_OK ){
    rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum, bUseCksum);
    rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum);
  }

  sqlite3_free(aTotalSize);
  return rc;
}

/*

Changes to ext/fts5/fts5_test_tok.c.

207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
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);
      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);

Changes to ext/fts5/fts5_tokenize.c.

1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
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







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











-







  sCtx.pCtx = pCtx;
  sCtx.aBuf = p->aBuf;
  return p->tokenizer.xTokenize(
      p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
  );
}

/**************************************************************************
** Start of trigram implementation.
*/
typedef struct TrigramTokenizer TrigramTokenizer;
struct TrigramTokenizer {
  int bFold;                      /* True to fold to lower-case */
};

/*
** Free a trigram tokenizer.
*/
static void fts5TriDelete(Fts5Tokenizer *p){
  sqlite3_free(p);
}

/*
** Allocate a trigram tokenizer.
*/
static int fts5TriCreate(
  void *pUnused,
  const char **azArg,
  int nArg,
  Fts5Tokenizer **ppOut
){
  int rc = SQLITE_OK;
  TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
  UNUSED_PARAM(pUnused);
  if( pNew==0 ){
    rc = SQLITE_NOMEM;
  }else{
    int i;
    pNew->bFold = 1;
    for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
      const char *zArg = azArg[i+1];
      if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
        if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
          rc = SQLITE_ERROR;
        }else{
          pNew->bFold = (zArg[0]=='0');
        }
      }else{
        rc = SQLITE_ERROR;
      }
    }
    if( rc!=SQLITE_OK ){
      fts5TriDelete((Fts5Tokenizer*)pNew);
      pNew = 0;
    }
  }
  *ppOut = (Fts5Tokenizer*)pNew;
  return rc;
}

/*
** Trigram tokenizer tokenize routine.
*/
static int fts5TriTokenize(
  Fts5Tokenizer *pTok,
  void *pCtx,
  int unusedFlags,
  const char *pText, int nText,
  int (*xToken)(void*, int, const char*, int, int, int)
){
  TrigramTokenizer *p = (TrigramTokenizer*)pTok;
  int rc = SQLITE_OK;
  char aBuf[32];
  const unsigned char *zIn = (const unsigned char*)pText;
  const unsigned char *zEof = &zIn[nText];
  u32 iCode;

  UNUSED_PARAM(unusedFlags);
  while( 1 ){
    char *zOut = aBuf;
    int iStart = zIn - (const unsigned char*)pText;
    const unsigned char *zNext; 

    READ_UTF8(zIn, zEof, iCode);
    if( iCode==0 ) break;
    zNext = zIn;
    if( zIn<zEof ){
      if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
      WRITE_UTF8(zOut, iCode);
      READ_UTF8(zIn, zEof, iCode);
      if( iCode==0 ) break;
    }else{
      break;
    }
    if( zIn<zEof ){
      if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
      WRITE_UTF8(zOut, iCode);
      READ_UTF8(zIn, zEof, iCode);
      if( iCode==0 ) break;
      if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
      WRITE_UTF8(zOut, iCode);
    }else{
      break;
    }
    rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf);
    if( rc!=SQLITE_OK ) break;
    zIn = zNext;
  }

  return rc;
}

/*
** Argument xCreate is a pointer to a constructor function for a tokenizer.
** pTok is a tokenizer previously created using the same method. This function
** returns one of FTS5_PATTERN_NONE, FTS5_PATTERN_LIKE or FTS5_PATTERN_GLOB
** indicating the style of pattern matching that the tokenizer can support.
** In practice, this is:
**
**     "trigram" tokenizer, case_sensitive=1 - FTS5_PATTERN_GLOB
**     "trigram" tokenizer, case_sensitive=0 (the default) - FTS5_PATTERN_LIKE
**     all other tokenizers - FTS5_PATTERN_NONE
*/
int sqlite3Fts5TokenizerPattern(
    int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
    Fts5Tokenizer *pTok
){
  if( xCreate==fts5TriCreate ){
    TrigramTokenizer *p = (TrigramTokenizer*)pTok;
    return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
  }
  return FTS5_PATTERN_NONE;
}

/*
** Register all built-in tokenizers with FTS5.
*/
int sqlite3Fts5TokenizerInit(fts5_api *pApi){
  struct BuiltinTokenizer {
    const char *zName;
    fts5_tokenizer x;
  } aBuiltin[] = {
    { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
    { "ascii",     {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
    { "porter",    {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
    { "trigram",   {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
  };
  
  int rc = SQLITE_OK;             /* Return code */
  int i;                          /* To iterate through builtin functions */

  for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
    rc = pApi->xCreateTokenizer(pApi,

Changes to ext/fts5/fts5_unicode2.c.

769
770
771
772
773
774
775
776
777
778
769
770
771
772
773
774
775

776








-

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

Changes to ext/fts5/fts5_vocab.c.

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
46
47
48
49
50
51
52

53
54
55
56
57
58
59







-







struct Fts5VocabTable {
  sqlite3_vtab base;
  char *zFts5Tbl;                 /* Name of fts5 table */
  char *zFts5Db;                  /* Db containing fts5 table */
  sqlite3 *db;                    /* Database handle */
  Fts5Global *pGlobal;            /* FTS5 global object for this database */
  int eType;                      /* FTS5_VOCAB_COL, ROW or INSTANCE */
  unsigned bBusy;                 /* True if busy */
};

struct Fts5VocabCursor {
  sqlite3_vtab_cursor base;
  sqlite3_stmt *pStmt;            /* Statement holding lock on pIndex */
  Fts5Table *pFts5;               /* Associated FTS5 table */

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







-
-
-
-
-
-











-




-







  Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
  Fts5Table *pFts5 = 0;
  Fts5VocabCursor *pCsr = 0;
  int rc = SQLITE_OK;
  sqlite3_stmt *pStmt = 0;
  char *zSql = 0;

  if( pTab->bBusy ){
    pVTab->zErrMsg = sqlite3_mprintf(
       "recursive definition for %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
    );
    return SQLITE_ERROR;
  }
  zSql = sqlite3Fts5Mprintf(&rc,
      "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
      pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl
  );
  if( zSql ){
    rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
  }
  sqlite3_free(zSql);
  assert( rc==SQLITE_OK || pStmt==0 );
  if( rc==SQLITE_ERROR ) rc = SQLITE_OK;

  pTab->bBusy = 1;
  if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
    i64 iId = sqlite3_column_int64(pStmt, 0);
    pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId);
  }
  pTab->bBusy = 0;

  if( rc==SQLITE_OK ){
    if( pFts5==0 ){
      rc = sqlite3_finalize(pStmt);
      pStmt = 0;
      if( rc==SQLITE_OK ){
        pVTab->zErrMsg = sqlite3_mprintf(
578
579
580
581
582
583
584
585
586


587
588
589
590
591
592
593
594
595
569
570
571
572
573
574
575


576
577


578
579
580
581
582
583
584







-
-
+
+
-
-







          if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
        }
      }
    }
  }

  if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
    for(/* noop */; pCsr->iCol<nCol && pCsr->aDoc[pCsr->iCol]==0; pCsr->iCol++);
    if( pCsr->iCol==nCol ){
    while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
    assert( pCsr->iCol<pCsr->pFts5->pConfig->nCol );
      rc = FTS5_CORRUPT;
    }
  }
  return rc;
}

/*
** This is the xFilter implementation for the virtual table.
*/

Changes to ext/fts5/test/fts5colset.test.

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
78
79
80
81
82
83
84



















85
86







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


  }

  do_catchsql_test 4.1 {
    SELECT * FROM t1 WHERE rowid MATCH 'a'
  } {1 {unable to use function MATCH in the requested context}}
}

#-------------------------------------------------------------------------
# Confirm that the expression parser creates the same expression tree
# for:
#
#     {a b} : (abc AND def)
#    -{c d} : (abc AND def)
#
# Assuming that the table columns are (a, b, c, d).
#
do_execsql_test 5.1 {
  SELECT fts5_expr('abcd AND cdef');
} {{"abcd" AND "cdef"}}
do_execsql_test 5.2 {
  SELECT fts5_expr('{a b} : (abcd AND cdef)', 'a', 'b', 'c', 'd');
} {{{a b} : "abcd" AND {a b} : "cdef"}}
do_execsql_test 5.3 {
  SELECT fts5_expr('-{c d} : (abcd AND cdef)', 'a', 'b', 'c', 'd');
} {{{a b} : "abcd" AND {a b} : "cdef"}}


finish_test

Changes to ext/fts5/test/fts5content.test.

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
249
250
251
252
253
254
255



256





































257








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

-
  SELECT name FROM sqlite_master;
} {xx xx_data xx_idx xx_docsize xx_config}
do_execsql_test 6.2 {
  DROP TABLE xx;
  SELECT name FROM sqlite_master;
} {}

#---------------------------------------------------------------------------
# Check that an fts5 table cannot be its own content table.
#

reset_db
do_execsql_test 7.1.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(a, c=t1 );
  INSERT INTO t1( a ) VALUES('abc');
}
do_catchsql_test 7.1.2 { 
  SELECT * FROM t1; 
} {1 {recursively defined fts5 content table}}
do_catchsql_test 7.1.3 { 
  SELECT * FROM t1('abc'); 
} {1 {recursively defined fts5 content table}}
do_catchsql_test 7.1.4 { 
  SELECT count(*) FROM t1;
} {1 {recursively defined fts5 content table}}
do_catchsql_test 7.1.5 { 
  SELECT * FROM t1('abc') ORDER BY rank;
} {1 {recursively defined fts5 content table}}

reset_db
do_execsql_test 7.2.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(a, c=t2 );
  CREATE VIRTUAL TABLE t2 USING fts5(a, c=t1 );
  INSERT INTO t1( a ) VALUES('abc');
}
do_catchsql_test 7.2.2 { 
  SELECT * FROM t1; 
} {1 {recursively defined fts5 content table}}
do_catchsql_test 7.2.3 { 
  SELECT * FROM t1('abc'); 
} {1 {recursively defined fts5 content table}}
do_catchsql_test 7.2.4 { 
  SELECT count(*) FROM t1;
} {1 {recursively defined fts5 content table}}
do_catchsql_test 7.2.5 { 
  SELECT * FROM t1('abc') ORDER BY rank;
} {1 {recursively defined fts5 content table}}

finish_test

Changes to ext/fts5/test/fts5corrupt3.test.

763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777







-
+







|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c13.db
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
}]} {}

do_catchsql_test 13.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon'; 
} {/*malformed database schema*/}
} {1 {vtable constructor failed: t1}}

#-------------------------------------------------------------------------
reset_db
do_test 14.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c14b.db
954
955
956
957
958
959
960
961

962
963
964
965
966
967
968
954
955
956
957
958
959
960

961
962
963
964
965
966
967
968







-
+







|     48: 01 00 00 10 10 04 02 02 00 00 00 00 00 00 00 00   ................
|     64: 70 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00   p...........p...
| end c16.db
}]} {}

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

#---------------------------------------------------------------------------
#
reset_db
do_test 16.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
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
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







-
+



-
+



-
+



-
+







|    448: 54 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53   TUAL TABLE t1 US
|    464: 49 4e 47 20 66 74 73 35 28 61 2c 62 2c 63 29 00   ING fts5(a,b,c).
|    480: 00 00 39 00 00 00 00 00 00 00 00 00 00 00 00 00   ..9.............
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-fed6e90021ba5d.db
}]} {}

do_catchsql_test 33.1 {
do_execsql_test 33.1 {
  CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row');
  CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col');
  CREATE VIRTUAL TABLE t4 USING fts5vocab('t1','instance');
} {/*malformed database schema*/}
}

do_catchsql_test 33.2 {
  SELECT * FROM t2;
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

do_catchsql_test 33.3 {
  SELECT * FROM t2, t3, t4 WHERE t2.term=t3.term AND t3.term=t4.term;
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 34.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename crash-a60a9da4c8932f.db
4480
4481
4482
4483
4484
4485
4486
4487

4488
4489
4490
4491
4492
4493
4494
4480
4481
4482
4483
4484
4485
4486

4487
4488
4489
4490
4491
4492
4493
4494







-
+







|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 0c e9   ................
| end crash-a6651222df1bd1.db
}]} {}

do_catchsql_test 36.1 {
  INSERT INTO t1(b) VALUES(
      x'78de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bfef346e6a');
} {0 {}}
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 37.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename null-memcmp-param-1..db
4633
4634
4635
4636
4637
4638
4639
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
4673
4674
4675
4676
4677
4633
4634
4635
4636
4637
4638
4639

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
4673
4674
4675
4676
4677
4678







-
+



-
+





-
+




















+







|      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 null-memcmp-param-1..db
}]} {}

do_catchsql_test 37.1 {
  SELECT * FROM t3;
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 37a.0 {
do_execsql_test 37.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(b, c);
  INSERT INTO t1 VALUES('a', 'b');
  SELECT quote(block) FROM t1_data WHERE rowid=10;
} {X'000000000101010001010101'}

do_execsql_test 37a.1 {
do_execsql_test 37.1 {
  UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10;
  SELECT rowid FROM t1('a');
} {1}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 38.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(b, c);
  INSERT INTO t1 VALUES('a', 'b');
  INSERT INTO t1 VALUES('a', 'b');
  SELECT quote(block) FROM t1_data WHERE rowid=1;
} {X'020202'}

do_execsql_test 38.1 {
  SELECT * FROM t1('a b') ORDER BY rank;
} {a b a b}

do_execsql_test 38.2 {
  UPDATE t1_data SET block = X'000202' WHERE rowid=1;
}
breakpoint
do_catchsql_test 38.3 {
  SELECT * FROM t1('a b') ORDER BY rank;
} {1 {database disk image is malformed}}

db close
sqlite3 db test.db
do_catchsql_test 38.4 {
4890
4891
4892
4893
4894
4895
4896
4897

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

4898
4899
4900
4901
4902
4903
4904
4905







-
+







|   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 6d 69 7a 65   uild....optimize
| end crash-fd2a1313e5b5e9.db
}]} {}

do_catchsql_test 38.1 {
  UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*';
} {/*malformed database schema*/}
} {0 {}}

#-------------------------------------------------------------------------
reset_db
do_test 39.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
5322
5323
5324
5325
5326
5327
5328
5329

5330
5331
5332
5333
5334

5335
5336
5337
5338

5339
5340
5341
5342
5343
5344
5345
5323
5324
5325
5326
5327
5328
5329

5330
5331
5332
5333
5334

5335
5336
5337
5338

5339
5340
5341
5342
5343
5344
5345
5346







-
+




-
+



-
+







|   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| page 6 offset 20480
|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09   ................
| end crash2.txt.db
}]} {}

do_catchsql_test 40.1 {
do_execsql_test 40.1 {
  BEGIN;
  INSERT INTO t1(b) VALUES(X'819192e578de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bf');
  INSERT INTO t1(b) VALUES(X'c8ae0d0e7c3175946e62ba2b449511d4eb504079984a20f77969f62206c9f3d7ea25358ab705e6978627290b6d48db9032f815a06a79a4f4b809841a0942eed12954ed166f666111812a508abc3bec87958846edaec0a6fe14564bc0a4b78f1c35ebcacca6bae29cc37ae9b59d8a2d7593af1e47dda0ece2268a98d20febafad037964f139851f9a57f48b3706b01721769071991412044cd6006f1d72eb6eb4aa5ad77e378176db8c15575fbeee47165e38a7c6c5a557ac2dfe11813976eaf6741cf593a9e457053a3c34cddfbe605a6e25419f993de8374fafcd3636509d8416a51dc7bcc14cfca322ae343078f47e23522431c17d0da0c033');
  INSERT INTO t1(b) VALUES(X'dc29a94e873a45a4243fce9b912aaefbadf1d0423e0345793874b356eeb500b92fb05284c1601fe9bad3143f72162f10242cec27c44ebf764c8fc9fb0824e32c4161472a4f914f579e0e8274f08ca1a02e59b9d8eec1f31061f9ccb9ed97a6f06534e991f7992c761489e6a7724f6e9c2b581e77487ded3a986d53c4419bbd3e9747cee300e670dd7294874c77e2ed48da68eaa6c3ec954a09ac410493d98e34d6686e54fbbe80696705f10e040c66093efb40746b33600685c94c664c7942835a9e954866121d5dcfb2cb12e92521ea3df175ee17072502dad9b9c1565f801b2179799011eb7418bfa00323e3157589e648ff7378be233c79b7');
} {/*malformed database schema*/}
}

do_catchsql_test 40.2 {
  INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3, true ),(4,44);
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 41.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a,b,c);
  REPLACE INTO t1_data VALUES(1,X'255a5824');
  REPLACE INTO t1_data VALUES(10,X'0a1000000102020002010101020101');
5785
5786
5787
5788
5789
5790
5791
5792

5793
5794
5795
5796
5797
5798
5799
5786
5787
5788
5789
5790
5791
5792

5793
5794
5795
5796
5797
5798
5799
5800







-
+







|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09   ................
| end 89028ffd2c29b679e250.db
}]} {}

do_catchsql_test 43.1 {
  INSERT INTO t1(t1) VALUES('optimize');
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 44.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(a,b unindexed,c,tokenize="porter ascii");
  REPLACE INTO t1_data VALUES(1,X'03090009');
  REPLACE INTO t1_data VALUES(10,X'000000000103030003010101020101030101');
5808
5809
5810
5811
5812
5813
5814
5815

5816
5817
5818

5819
5820

5821
5822
5823
5824
5825
5826
5827
5809
5810
5811
5812
5813
5814
5815

5816
5817
5818

5819
5820

5821
5822
5823
5824
5825
5826
5827
5828







-
+


-
+

-
+







  INSERT INTO t1_content VALUES(3,'a b c','g h i','g h i');
  INSERT INTO t1_docsize VALUES(1,X'030003');
  INSERT INTO t1_docsize VALUES(2,X'030003');
  INSERT INTO t1_docsize VALUES(3,X'030003');
} {}

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

do_catchsql_test 44.3 {
do_catchsql_test 44.2 {
  SELECT snippet(t1, -1, '.', '..', '', 2 ) FROM t1('g h') ORDER BY rank; 
} {0 {{.g.. .h..} {.g.. h} {.g.. .h..}}}
} {1 {database disk image is malformed}}

#--------------------------------------------------------------------------
reset_db
do_test 45.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-0b162c9e69b999.db
6043
6044
6045
6046
6047
6048
6049
6050

6051
6052
6053
6054
6055
6056
6057
6044
6045
6046
6047
6048
6049
6050

6051
6052
6053
6054
6055
6056
6057
6058







-
+







  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
} {/*malformed database schema*/}
} {0 {}}

#--------------------------------------------------------------------------
reset_db
do_test 46.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-1ee8bd451dd1ad.db
6261
6262
6263
6264
6265
6266
6267
6268

6269
6270
6271
6272
6273
6274
6275
6262
6263
6264
6265
6266
6267
6268

6269
6270
6271
6272
6273
6274
6275
6276







-
+







|   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 6d 69 7a 65   uild....optimize
| end crash-1ee8bd451dd1ad.db
}]} {}

do_catchsql_test 46.1 {
  SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*');
} {/*malformed database schema*/}
} {0 {{}}}

#--------------------------------------------------------------------------
reset_db
do_test 47.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename 4b6fc659283f2735616c.db
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427



6428
6429

6430
6431
6432
6433
6434
6435
6436
6414
6415
6416
6417
6418
6419
6420








6421
6422
6423


6424
6425
6426
6427
6428
6429
6430
6431







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







| page 10 offset 36864
|      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 4b6fc659283f2735616c.db
}]} {}

do_catchsql_test 47.1 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {/*malformed database schema*/}

do_catchsql_test 47.2 {
  SELECT count(*) FROM (
      SELECT snippet(t1, -1, '.', '..', '[', 50), 
      highlight(t1, 2, '[', ']') FROM t1('g h') 
      WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank
  SELECT snippet(t1, -1, '.', '..', '[', 50), 
         highlight(t1, 2, '[', ']') FROM t1('g h') 
  WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank;
  )
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

#--------------------------------------------------------------------------
reset_db
do_test 48.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-44a8305b4bd86f.db
6904
6905
6906
6907
6908
6909
6910
6911

6912
6913
6914
6915
6916
6917
6918
6899
6900
6901
6902
6903
6904
6905

6906
6907
6908
6909
6910
6911
6912
6913







-
+








do_catchsql_test 50.1 {
  SELECT term FROM t4 WHERE term LIKE '»as';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 51.0 {
do_execsql_test 51.1 {
BEGIN TRANSACTION;
PRAGMA writable_schema=ON;
CREATE VIRTUAL TABLE t1 USING fts5(a,b,c);
CREATE TABLE IF NOT EXISTS 't1_data'(id INTEGER PRIMARY KEY, block BLOB);
REPLACE INTO t1_data VALUES(1,X'2eb1182424');
REPLACE INTO t1_data VALUES(10,X'000000000102080002010101020107');
INSERT INTO t1_data VALUES(137438953473,X'0000032b0230300102060102060102061f0203010203010203010832303136303630390102070102070102070101340102050102050102050101350102040102040102040207303030303030301c023d010204010204010662696e6172790306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020108636f6d70696c657201020201020201020201066462737461740702030102030102030204656275670402020102020102020107656e61626c6507020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020202087874656e73696f6e1f02040102040102040104667473340a02030102030102030401350d020301020301020301036763630102030102030102030206656f706f6c7910020301020301020301056a736f6e3113020301020301020301046c6f61641f020301020301020301036d61781c02020102020102020205656d6f72791c020301020301020304047379733516020301020301020301066e6f6361736502060102020306010202030601020213060102020306010202030601020203060102020306010202030601020203060102020306010202030601020201046f6d69741f0202010202010202010572747265651902030102030102030402696d010601020203060102020306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020306010202010a7468726561647361666522020201020201020201047674616207020401020401020401017801060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102ad060101020106010102010601010201060101020106010101010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020415130c0c124413110f47130efc0e11100f0e100f440f1040150f');
6972
6973
6974
6975
6976
6977
6978
6979

6980
6981
6982
6983
6984
6985
6986
6967
6968
6969
6970
6971
6972
6973

6974
6975
6976
6977
6978
6979
6980
6981







-
+







INSERT INTO t2 VALUES('integrity-check');
PRAGMA writable_schema=OFF;
COMMIT;
} {}

do_catchsql_test 51.1 {
  SELECT max(rowid)==0 FROM t1('e*');
} {1 {database disk image is malformed}}
} {0 0}

#--------------------------------------------------------------------------
reset_db
do_test 52.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename crash-2b92f77ddfe191.db
7126
7127
7128
7129
7130
7131
7132
7133

7134
7135
7136
7137
7138
7139
7140
7121
7122
7123
7124
7125
7126
7127

7128
7129
7130
7131
7132
7133
7134
7135







-
+







|      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-2b92f77ddfe191.db
}]} {}

do_catchsql_test 52.1 {
  SELECT fts5_decode(id, block) FROM t1_data;
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 53.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-dbe9b7614da103.db
7342
7343
7344
7345
7346
7347
7348
7349

7350
7351
7352
7353
7354
7355
7356
7337
7338
7339
7340
7341
7342
7343

7344
7345
7346
7347
7348
7349
7350
7351







-
+







|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 0c e9   ................
| end crash-dbe9b7614da103.db
}]} {}

do_catchsql_test 53.1 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10)
    INSERT INTO t1(a) SELECT randomblob(3000) FROM c;
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 54.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-03a1855566d9ae.db
7558
7559
7560
7561
7562
7563
7564
7565

7566
7567
7568
7569
7570
7571
7572
7553
7554
7555
7556
7557
7558
7559

7560
7561
7562
7563
7564
7565
7566
7567







-
+







|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 23 03 02 01 03 03 02 02 01 02 02 00 f2 09   ..#.............
| end crash-03a1855566d9ae.db
}]} {}

do_catchsql_test 54.1 {
  SELECT rowid==-1 FROM t1('t*');
} {/*malformed database schema*/}
} {0 {0 0 0}}

#-------------------------------------------------------------------------
reset_db
do_test 55.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-b366b5ac0d3887.db
7773
7774
7775
7776
7777
7778
7779
7780

7781
7782
7783

7784
7785
7786
7787
7788
7789
7790
7768
7769
7770
7771
7772
7773
7774

7775
7776
7777

7778
7779
7780
7781
7782
7783
7784
7785







-
+


-
+







|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 77 72   .........+intewr
|   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 6d 69 7a 65   uild....optimize
| end crash-b366b5ac0d3887.db
}]} {}

do_catchsql_test 55.1 {
do_execsql_test 55.1 {
  SAVEPOINT one;
  DELETE FROM t1 WHERE a MATCH 'ts';
} {/*malformed database schema*/}
}

do_execsql_test 55.2 {
  ROLLBACK TO one;
}

#-------------------------------------------------------------------------
reset_db
8009
8010
8011
8012
8013
8014
8015
8016

8017
8018
8019
8020
8021
8022
8023
8004
8005
8006
8007
8008
8009
8010

8011
8012
8013
8014
8015
8016
8017
8018







-
+







  # may return SQLITE_CONSTRAINT instead of SQLITE_CORRUPT. This is because
  # the corrupt db in the test over-reads the page buffer slightly, with
  # different results depending on whether or not the page-cache is in use.
  if {$res=="1 {constraint failed}"} {
    set res "1 {database disk image is malformed}"
  }
  set res
} {/*malformed database schema*/}
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 57.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename x.db
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
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
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
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
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
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
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
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
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
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
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
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
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
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
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
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
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
8122
8123
8124
8125
8126
8127
8128
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































8129




8130
8131
8132
8133
8134







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





|   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 x.db
}]} {}

do_catchsql_test 57.1 {
  INSERT INTO t1(t1) VALUES('optimize')
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 58.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-5a5acd0ab42d31.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 00 00 00 06 0e 0f 00 0f aa 0f 53   ...............S
|    112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00   .....3..........
|   3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22   ................
|   3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62   ......1tablebbbb
|   3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62   .CREATE TABLE bb
|   3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65   (a)V.......table
|   3648: 74 31 5f 63 2a 6e 66 69 68 74 31 5f 63 6f 6e 66   t1_c*nfiht1_conf
|   3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20   ig.CREATE TABLE 
|   3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52   't1_config'(k PR
|   3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49   IMARY KEY, v) WI
|   3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21   THOUT ROWID[...!
|   3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 73 73   !...tablet1_doss
|   3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52   izet1_docsize.CR
|   3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64   EATE TABLE 't1_d
|   3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47   ocsize'(id INTEG
|   3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20   ER PRIMARY KEY, 
|   3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81   sz BLOB)i.......
|   3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69   -tablet1_idxt1_i
|   3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20   dx.CREATE TABLE 
|   3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20   't1_idx'(segid, 
|   3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d   term, pgno, PRIM
|   3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74   ARY KEY(segid, t
|   3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f   erm)) WITHOUT RO
|   3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c   WIDU........tabl
|   3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02   et1_datat1_data.
|   3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31   CREATE TABLE 't1
|   3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45   _data'(id INTEGE
|   3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62   R PRIMARY KEY, b
|   4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11   lock BLOB)T.....
|   4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41   ...tablet1t1CREA
|   4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45   TE VIRTUAL TABLE
|   4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61    t1 USING fts5(a
|   4064: 2c 62 2c 70 72 65 66 69 78 3d 22 32 2c 32 2c 33   ,b,prefix=.2,2,3
|   4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29   ,4., content=..)
| page 2 offset 4096
|      0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4   ..j.7.L....L....
|     16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ae   ...m.K.,........
|     32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5   ...l.K.)........
|     48: 0d 97 0d 76 0d 54 0d 30 fd 15 0c f3 0c d3 0c b5   ...v.T.0........
|     64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0   ...s.T.2........
|     80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a ad   ...~.H..........
|     96: 0a 8c 0a 6d 0a 4d 0a 2b 0a 0c 00 00 00 00 00 00   ...m.M.+........
|   2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00   ................
|   2384: 30 00 00 00 9c 01 03 35 00 03 01 01 12 02 01 12   0......5........
|   2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00   ............>...
|   2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68   ....4tabl.....wh
|   2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c   er.............<
|   2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e   .....4fts4.....n
|   2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03   umb.............
|   2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04   .<.....3the.....
|   2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80   ..whe...........
|   2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01   ...<.....3num...
|   2528: 01 05 01 03 74 61 62 05 62 03 04 0a 19 8c 80 80   ....tab.b.......
|   2544: 80 80 0c 03 00 38 00 00 00 14 03 39 a7 68 03 02   .....8.....9.h..
|   2560: 04 10 04 33 66 74 73 03 02 02 04 07 18 8c 80 80   ...3fts.........
|   2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02   .....6.....2ta..
|   2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80   ...h............
|   2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01   ....<.....2nu...
|   2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80   ....of..........
|   2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03   ......8.....2ft.
|   2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80   ....is..........
|   2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08   ......6.....1t..
|   2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80   ......w.........
|   2704: 80 80 07 03 00 3a ff 00 00 15 02 31 6e 03 08 01   .....:.....1n...
|   2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80   .....o..........
|   2736: 80 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03   ......6......1f.
|   2752: 02 01 f1 01 69 03 06 01 01 03 05 06 1c 8c 80 80   ....i...........
|   2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03   .....>.....0the.
|   2784: 06 01 01 14 01 05 77 68 65 72 65 03 02 04 0a 15   ......where.....
|   2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06   ........0.......
|   2816: 06 30 74 61 62 6c cc 03 02 03 07 1c 8c 80 80 80   .0tabl..........
|   2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65   ....>.....0numbe
|   2848: 72 03 06 01 01 05 01 02 6f 66 02 06 04 0d 13 8c   r.......of......
|   2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02   .......,........
|   2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03   0n..............
|   2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03   .<.....0fts4aux.
|   2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00   ....is........*.
|   2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88   .....$..........
|   2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80   ................
|   2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77   ......>.....4row
|   2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b   s.......ther....
|   2992: 15 88 80 80 80 80 10 03 00 3e 10 00 00 11 02 01   .........>......
|   3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80   ...4betw........
|   3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77   .....<......3row
|   3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88   .......the......
|   3056: 80 80 80 80 0e 03 05 0c 00 00 00 16 01 01 02 04   ................
|   3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08   3are.....bet....
|   3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32   .........<.....2
|   3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06   th........3and..
|   3120: 04 01 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16   ...........<....
|   3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01   .2in.......ro...
|   3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00   .............6..
|   3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02   ....2ar.....be..
|   3184: 04 05 07 1b 88 80 bf 80 80 0a 03 00 3c 00 00 00   ............<...
|   3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02   ..1t........2an.
|   3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00   ..............8.
|   3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06   ....1n.......r..
|   3248: 01 01 05 03 08 17 88 80 80 80 80 08 03 00 34 00   ..............4.
|   3264: 01 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01   ....1b.....i....
|   3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00   ............8...
|   3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01   ...12.....a.....
|   3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00   ............<...
|   3328: 16 06 30 74 68 65 72 65 02 12 02 00 02 31 31 02   ..0there.....11.
|   3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00   ..............0.
|   3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 71 01 07   .......0the..q..
|   3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01   ..........>.....
|   3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73   ...0n.......rows
|   3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00   .............<..
|   3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02   ...0between.....
|   3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a   in.............:
|   3456: 08 f0 00 15 04 30 61 6e 64 02 06 01 01 02 02 02   .....0and.......
|   3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00   re..............
|   3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32   4.....01.......2
|   3504: 02 02 07 04 08 08 84 80 80 80 80 12 03 00 16 00   ................
|   3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00   .............<..
|   3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65   ...4tabl.......e
|   3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c   rm.............<
|   3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70   .....4each.....p
|   3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03   res.............
|   3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02   .:.....3ter.....
|   3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e   he..............
|   3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01   ..<.....3pre....
|   3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80   .tab............
|   3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02   ....:.....3for..
|   3680: 02 02 02 74 73 01 06 01 01 04 03 f8 1b 84 80 80   ...ts...........
|   3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06   .....<.....2th..
|   3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84   .....3eac.......
|   3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61   .......6.....2ta
|   3744: 01 06 01 01 05 02 01 65 00 02 04 04 09 19 84 80   .......e........
|   3760: 80 80 80 0a 03 10 38 00 00 00 14 03 32 69 6e 01   ......8.....2in.
|   3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80   ......pr........
|   3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01   ......6.....2fo.
|   3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80   ....t...........
|   3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04   .....<.....1t...
|   3840: 01 00 03 04 00 03 32 65 61 01 02 03 04 0a 17 84   ......2ea.......
|   3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01   .......4.....1i.
|   3872: 06 01 01 02 de 01 70 01 02 05 04 08 18 84 80 80   ......p.........
|   3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03   .....6.....1e...
|   3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80   ..f.............
|   3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01   ....<.....0term.
|   3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80   ....he..........
|   3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62   ............0tab
|   3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03   le..............
|   3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74   .0......0present
|   4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00   .............<..
|   4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e   ...0fts.......in
|   4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a   ...............:
|   4048: 00 00 00 15 05 30 65 61 63 68 00 f2 03 01 03 66   .....0each.....f
|   4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00   or..............
|   4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04   ................
| page 3 offset 8192
|      0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1   ....2.O.........
|     16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f c1 0f a9 0f a0   ................
|     32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f   .........x.q.h._
|     48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13   .V.M.A.8./.&....
|     64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d7 0e cd   ................
|     80: 0e c3 0e ba 0e b0 0e a8 0e 9f 0e 96 0e 8e 0e 85   ................
|   3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08   ................
|   3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e   .....4t ......4.
|   3680: 09 04 01 12 34 03 33 74 68 1c 08 04 01 10 01 03   ....4.3th.......
|   3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10   3n.......2w.....
|   3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04   ..2t.......2n...
|   3728: 01 0e 01 03 32 12 08 04 01 0f f1 03 31 74 10 08   ....2.......1t..
|   3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 30 fc   .....1n.......0.
|   3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03   ......0th.......
|   3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01   0t.......0nu....
|   3792: 10 01 03 30 6e 04 06 04 01 0c 01 05 52 08 04 01   ...0n.......R...
|   3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04   ...4r.......4 ..
|   3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72   ....3r.......3ar
|   3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 b3 02   .......2t.......
|   3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01   2i.......2ar....
|   3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08   ...1t.......1n..
|   3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32   .....1b.......12
|   3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01   .......0ther....
|   3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08   ...0t.......0n..
|   3936: 04 01 10 01 02 30 62 06 09 04 01 10 01 02 30 61   .....0b.......0a
|   3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22   .............4t.
|   3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e   .....4 .....3te.
|   3984: 07 04 09 10 01 33 70 1c 07 f4 09 11 01 33 66 1a   .....3p......3f.
|   4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 e4   .....2th......2.
|   4016: 16 07 04 09 10 01 32 69 14 07 04 09 10 01 32 66   ......2i......2f
|   4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69   ......1t......1i
|   4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65   ......1......0te
|   4064: 0a 07 04 09 10 01 30 74 08 00 00 00 00 00 00 00   ......0t........
| page 4 offset 12288
|   4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10   ................
|   4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04   ................
| page 5 offset 16384
|      0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70   ...............p
|   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| page 6 offset 20480
|   4080: 00 00 23 03 02 01 03 03 02 00 00 00 00 00 00 00   ..#.............
| end crash-5a5acd0ab42d31.db
}]} {}

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
|    112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 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 3 offset 8192
|      0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00   ................
|   3216: 00 00 00 00 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 31 31 36 30   ...........21160
|   3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1   609...........3.
|   3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 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 01 f2 03 06 4e 02 02 03 06 01   ..........N.....
|   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 13 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 02 02 01 02   nable...........
|   3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02   ................
|   3472: 01 02 02 01 02 02 01 02 01 f1 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 25 0d 02 03 01 02 03 01   ........%.......
|   3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03   ....gcc.........
|   3568: 02 06 65 6f 70 6f 6c 79 0f f2 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: 00 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 13 06 00 f2 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 0a 22 74 72 65 65 19 02 03 01 02 03 01 02 03   ...tree.........
|   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 02 03 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 02   ................
|   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 11 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 01 f1 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 07 01 03 00 14 24 5a 24 24 0f   D..@.......$Z$$.
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 4 offset 12288
|      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 5 offset 16384
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   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 45 ed   0XRTRIM.!..3..E.
|   3168: 49 54 20 4c 4f 41 44 21 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 5a 29   MIT LOAD EXTENZ)
|   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 56 a9 4d 1f 1e 05 00 33 0f 19   IONXRTV.M....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 31 52 59 1f 1d 05 00 33 0f   000WBIN1RY....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 32   0000XNOCASE....2
|   3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30   ..NAX 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 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52   .f.%..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 76 35 58 52 54 52 49 4d 18 15 05 10 25   MSYv5XRTRIM....%
|   3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42   ..EN@BLE 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 32 58 4e 4f 43 41 53 45 17   LE JSON2XNOCASE.
|   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 5f 81 42 4c   NARY....)..E_.BL
|   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 1a 45 4e 41 42 4c 45 20 56 54 43 35 58 42 49   ..ENABLE VTC5XBI
|   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 48 4e 4f 43 41 53 45 16 1d 05   E FTS5HNOCASE...
|   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: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e   WNOCASE....#..EN
|   3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e   ABLE FTS4.RTRIM.
|   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 3f 87   ...C..COMPILER?.
|   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: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 00   E.`YLER=gcc-5.4.
| page 6 offset 20480
|   3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01   .$.......#......
|   3824: 06 22 03 01 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 02 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 10 12 02 01 01   ................
|   4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01   ................
|   4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01   ................
|   4048: 07 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01   ................
|   4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01   ................
|   4080: 06 02 03 00 12 06 01 01 06 01 03 00 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
|   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
|    112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 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 3 offset 8192
|      0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00   ................
|   3216: 00 00 00 00 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 31 31 36 30   ...........21160
|   3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1   609...........3.
|   3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 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 01 f2 03 06 4e 02 02 03 06 01   ..........N.....
|   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 13 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 02 02 01 02   nable...........
|   3456: 02 01 02 02 01 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 76 b4 65 6e 73 69 6f 6e 1f 02   ......v.ension..
|   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 25 0d 02 03 01 02 03 01   ........%.......
|   3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03   ....gcc.........
|   3568: 02 06 65 6f 70 6f 6c 79 0f f2 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: 00 03 6d 61 78 1c 02 0c 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 13 06 00 f2 02 03   ocase...........
|   3680: 06 01 12 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 02 03 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 02   ................
|   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 11 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 01 f1 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 07 01 03 00 14 24 5a 24 24 0f   D..@.......$Z$$.
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 4 offset 12288
|      0: 0a 00 00 00 01 0f 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 5 offset 16384
|      0: 0d 00 00 00 24 0c 0a 00 0f 00 00 00 00 00 00 00   ....$...........
|   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 43 41 46 45 3d   ..%..THREADCAFE=
|   3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d   0XRTRIM.!..3..OM
|   3168: 49 54 20 4b 4f 41 44 21 45 58 54 45 4e 53 49 4f   IT KOAD!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 56 a9 4d 1f 1e 05 00 33 0f 19   IONXRTV.M....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 31 52 59 1f 1d 05 00 33 0f   000WBIN1RY....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 32   0000XNOCASE....2
|   3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30   ..NAX 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 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52   .f.%..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 10 25   MSYS5XRTRIM....%
|   3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42   ..EN@BLE 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 32 58 4e 4f 43 41 53 45 17   LE JSON2XNOCASE.
|   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 81 42 4c   NARY....)..EO.BL
|   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 1a 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 48 4e 4f 43 41 53 45 16 1d 05   E FTS5HNOCASE...
|   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: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e   WNOCASE....#..EN
|   3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e   ABLE FTS4.RTRIM.
|   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 8a 4e 41 52   .....DEBUGXB.NAR
|   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 3f 87   ...C..COMPILER?.
|   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: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 2e   E.`YLER=gcc-5.4.
|   4080: 30 20 32 30 31 36 30 36 30 39 68 52 54 52 49 4d   0 20160609hRTRIM
| page 6 offset 20480
|      0: 0d 00 00 00 24 0e 00 00 00 00 00 00 00 00 00 00   ....$...........
|   3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01   .$.......#......
|   3824: 06 22 03 01 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 02 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: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01   ................
|   4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01   ................
|   4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01   ................
|   4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01   ................
|   4080: 06 02 03 00 12 06 01 01 06 01 03 00 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
|   4048: 00 00 00 00 00 00 5d 03 00 00 00 00 00 00 00 00   ......].........
| end crash-c77b90b929dc92.db
}]} {}


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

#-------------------------------------------------------------------------
do_test 61.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-e5fa281edabddf.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 06 0d b6 00 0f 8d 0f 36   ...............6
|    112: 0e cb 0e 6b 0e 0e 0d b6 00 00 00 00 00 00 00 00   ...k............
|   3504: 00 00 00 00 00 00 56 07 06 17 1f 1f 01 7d 74 61   ......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 51 62 6c 65 74 31 5f 64   ..!!...tQblet1_d
|   3616: 6f 63 73 69 7a 65 74 31 5f 63 6f 63 73 69 7a 65   ocsizet1_cocsize
|   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 20 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 ea 74 31 43 52   ...._tablet.t1CR
|   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 3 offset 8192
|      0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00   ................
|   3216: 00 00 00 00 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 13 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 01   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 04   ......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 06 65   ebug...........e
|   3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02   nable...........
|   3456: 02 01 02 02 01 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 03 01 02 03 01 02 03   ....gcc.........
|   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 11 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 03 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 02 03 06 01 02 02 03 06 01 02 01 13 05 01 02   ................
|   3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02   ................
|   3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01   ..threadsafe....
|   3840: 02 02 01 01 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 0e 16 01 01 02 01 06 01 01 02 01 06 01 02 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 01 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 02 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 07 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 0f 0c 0e 11 10 0f 0e 10 0f   .D...G..........
|   4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f   D..@.......$Z$$.
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 4 offset 12288
|      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 5 offset 16384
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   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 e2 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 22   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 40 52 59 1f 20 05 00 33 0f 19 4f   NXBIN@RY. ..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 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT 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 4e 45 4d 4f 52 59 3d 35 30 30 30 30   MAX NEMORY=50000
|   3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....3.
|   3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 45 30 30 30   .MAX MEMORY=E000
|   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 58 4e 4f 43 41 53 45 17   LE RTREEXNOCASE.
|   3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 20 54 52   ...%..ENABLE  TR
|   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 4e 41 42 4c   NARY....)..ENABL
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45   E GEOPOLYXNOCASE
|   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 e5 54 53 35 58 42 49   ..ENABLE .TS5XBI
|   3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4d   NARY....#..ENABM
|   3712: 45 b5 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05   E.FTS5XNOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 b7 4e 41 52 59 17 0b   LE FTS4XB.NARY..
|   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 53   9XNOCASE&...C..S
|   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 2f 31 00 00 00 00 00 00 00 00 00 00 00   0 2/1...........
| page 6 offset 20480
|   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 10 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 10 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: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01   ................
|   4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01   ................
|   4048: 06 06 03 00 12 01 01 01 06 05 03 01 12 01 01 01   ................
|   4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01   ................
|   4080: 06 02 03 00 12 06 01 01 06 01 03 00 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.
| end crash-e5fa281edabddf.db
}]} {}

do_catchsql_test 61.1 {
  CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' );
} {/*malformed database schema*/}

do_catchsql_test 61.2 {
  SELECT * FROM t3 ORDER BY rowid;
} {/*malformed database schema*/}

breakpoint
#-------------------------------------------------------------------------
do_test 62.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-44942694542e1e.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
|    112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 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 79 67 74 31 5f 63   blet1_confygt1_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 52 4c 4f 42 29 5e 05 07 17 21   Y, sz RLOB)^...!
|   3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74   !...tablet1_cont
|   3712: 65 6e 74 74 35 ff 63 6f 6e 74 65 6e 74 05 43 52   entt5.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 20 63 42 29 69 04 07 17 19   c0, c1, cB)i....
|   3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74   ...-tablet1_idxt
|   3808: 31 5f 79 64 78 04 43 52 45 41 54 45 20 54 41 42   1_ydx.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 74 61   ablet1_datat1_ta
|   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 3 offset 8192
|      0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00   ................
|   3216: 00 00 00 00 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: 2f 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 01   609...........4.
|   3280: 02 05 01 02 c7 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 04   ......0000000...
|   3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06   ........binary..
|   3328: 01 02 02 04 16 01 02 02 03 06 01 02 02 02 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 02 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 00 02 03 01 02 03 02 04   bstat...........
|   3424: 65 62 74 67 04 02 02 01 02 02 01 02 02 01 06 65   ebtg...........e
|   3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02   nable...........
|   3456: 02 01 02 02 01 02 02 01 02 02 01 02 01 f1 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 45 02 02 01 02 02 01 02 02 01 02   .....E..........
|   3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02   ......xtension..
|   3520: 04 01 02 09 c1 02 04 01 04 66 74 73 34 0a 02 03   .........fts4...
|   3536: 01 02 03 01 02 03 04 00 35 0d 02 03 01 02 04 01   ........5.......
|   3552: 02 03 01 0f d7 63 63 01 02 03 01 02 03 01 02 03   .....cc.........
|   3568: 02 06 65 6f 70 6f 6b 79 10 02 03 01 02 03 01 02   ..eopoky........
|   3584: 03 01 05 6a 73 6f 6e 31 13 02 03 14 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 12 03 06 01 02 02 03   ocase...........
|   3680: 06 01 02 02 03 06 01 02 02 09 f6 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 11 02   ................
|   3728: 02 01 04 6f 7d 69 74 1f 02 02 01 02 02 01 02 02   ...o.it.........
|   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 02 03 06 01 02 02 03 06 01 02 02 03 06 11 02   ................
|   3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02   ................
|   3824: 00 fa 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 03 04 01 40   .......vtab....@
|   3856: 04 01 02 04 11 01 78 01 06 01 01 02 01 06 01 01   ......x.........
|   3872: 02 01 06 01 00 02 01 06 01 01 02 01 03 91 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 01 06 01 01 02   ................
|   3968: 01 06 01 01 02 01 76 01 01 02 01 06 01 01 02 5c   ......v.........
|   3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 11 06   ................
|   4000: 01 02 02 01 06 08 11 02 01 06 01 01 02 01 06 01   ................
|   4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 05 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 0f 0c 0e 11 10 ca 0e 10 0f   .D...G..........
|   4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 14 24 0f   D..@.......$Z.$.
|   4080: 0a 03 00 24 ff ff ff ff 01 01 02 00 01 01 01 01   ...$............
| page 4 offset 12288
|      0: 0a 00 00 00 01 0f fb 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 5 offset 16384
|      0: 0d 00 00 00 24 0c 09 00 00 00 00 00 00 00 00 00   ....$...........
|   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 47 17 22   DSAFE=0XNOCASG..
|   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 3f 41 44 20 45 58 54 45 4e 53 49 4f   IT L?AD EXTENSIO
|   3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f   NXBINARY. ..3..O
|   3200: 4d 49 64 20 4c 4f 41 44 20 45 58 54 45 d9 53 49   MId LOAD EXTE.SI
|   3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17   ONXNOCASE....3..
|   3232: 4f 4d 39 54 20 4c 4f 41 44 20 45 58 55 45 4e 53   OM9T LOAD EXUENS
|   3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19   IONXRTRIM....3..
|   3264: 4c 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30   LAX MEMORY=50000
|   3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 af 4f 43 41 53 45 1e 1c 05 00 33   0000X.OCASE....3
|   3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30   ..MAX MEMORY=500
|   3344: 30 30 ab 30 30 58 62 54 52 49 4d 18 1b 05 00 25   00.00XbTRIM....%
|   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 1b 05 00 25 0f 19 45 4e 41 42   INARY....%..ENAB
|   3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17   LE RTREEXNOCASE.
|   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 63 35 58 42 49   NABLE MEMSYc5XBI
|   3456: 4e 41 52 59 1a 17 04 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 3d 45   ....)..ENABLE =E
|   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 46 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17   LF 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 46 45 46 50 4f 4c 59 57 42 49   NABLE FEFPOLYWBI
|   3616: 4e 41 52 59 18 11 05 00 29 0f 19 45 4e 41 42 4c   NARY....)..ENABL
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 5f 43 41 53 45   E GEOPOLYXN_CASE
|   3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 42   ....)..ENABLE GB
|   3664: 2f 50 4f 4c 59 58 51 54 52 49 4d 17 0f 05 00 23   /POLYXQTRIM....#
|   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 0d 05   E FTS5XNOCASE...
|   3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58   .#..ENABLE FTS5X
|   3744: 52 54 52 49 4d 17 1c 05 00 23 0f 19 45 4e 41 42   RTRIM....#..ENAB
|   3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 16 0b   LE FTS4XBINARY..
|   3776: 05 00 22 0f e9 45 4e 41 42 4c 35 20 46 54 53 34   .....ENABL5 FTS4
|   3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 00 47 45 4e   XNOCASE....#.GEN
|   3808: 41 42 4c 45 20 46 54 53 34 57 52 54 52 49 4d 1e   ABLE FTS4WRTRIM.
|   3824: 60 05 00 31 0f 19 45 4e 41 42 4c 55 20 43 42 53   `..1..ENABLU CBS
|   3840: 54 41 54 20 56 54 42 42 58 42 49 4e 41 52 59 1e   TAT VTBBXBINARY.
|   3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53   ...1..ENABLE DBS
|   3872: 54 40 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d   T@T VTABXNOCASE.
|   3888: 07 05 00 31 0f 17 45 4e 41 42 4c 55 20 44 42 53   ...1..ENABLU DBS
|   3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 12 06   TAT VTABXRTRIM..
|   3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52   .....DEBUGXBINAR
|   3936: 59 21 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 18 44 45 42 55 47   CASE.......DEBUG
|   3968: 58 42 54 52 49 4d 27 11 05 00 43 0f 19 43 4f 4d   XBTRIM'...C..COM
|   3984: 50 49 48 f5 52 3d 67 63 63 2d 35 2e 34 2e 30 20   PIH.R=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 22 32 30 31 36 30 36 30   cc-5.4.0.2016060
|   4048: 39 c2 3e 4f 43 41 53 45 26 01 05 00 43 0f 17 43   9.>OCASE&...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 30 32 30 31 26 30 36 30 39 58 52 54 52 49 4d   00201&0609XRTRIM
| page 6 offset 20480
|      0: 0d 00 00 00 24 0e e0 00 00 00 00 00 00 00 00 00   ....$...........
|   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 00 f6 17 03 00 19 e2 f9 01   ................
|   3920: 06 16 03 00 12 02 05 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 10 03 10 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 00 f1   ................
|   4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01   ................
|   4016: 06 0a 03 00 12 02 01 01 05 09 03 00 12 03 01 01   ................
|   4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01   ................
|   4048: 06 06 03 00 12 01 01 01 06 05 02 ff 84 01 01 01   ................
|   4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01   ................
|   4080: 07 02 03 00 12 06 01 01 06 01 03 00 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.
| end crash-44942694542e1e.db
}]} {}

do_catchsql_test 62.1 {
  WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {/*malformed database schema*/}

#---------------------------------------------------------------------------
do_test 63.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-8230e6c3b368f5.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 00 00 00 06 0e 0f 00 0f aa 0f 53   ...............S
|    112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00   .....3..........
|   3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22   ................
|   3600: 06 06 17 11 11 01 31 74 61 62 7c 65 62 63 62 62   ......1tab|ebcbb
|   3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62   .CREATE TABLE bb
|   3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65   (a)V.......table
|   3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66   t1_configt1_conf
|   3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20   ig.CREATE TABLE 
|   3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52   't1_config'(k PR
|   3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49   IMARY KEY, v) WI
|   3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21   THOUT ROWID[...!
|   3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73   !...tablet1_docs
|   3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52   izet1_docsize.CR
|   3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 9d   EATE TABLE 't1_.
|   3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47   ocsize'(id INTEG
|   3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20   ER PRIMARY KEY, 
|   3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81   sz BLOB)i.......
|   3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69   -tablet1_idxt1_i
|   3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20   dx.CREATE TABLE 
|   3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20   't1_idx'(segid, 
|   3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d   term, pgno, PRIM
|   3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74   ARY KEY(segid, t
|   3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f   erm)) WITHOUT RO
|   3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c   WIDU........tabl
|   3936: 65 64 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02   ed1_datat1_data.
|   3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31   CREATE TABLE 't1
|   3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45   _data'(id INTEGE
|   3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62   R PRIMARY KEY, b
|   4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 10 11   lock BLOB)T.....
|   4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41   ...tablet1t1CREA
|   4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45   TE VIRTUAL TABLE
|   4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61    t1 USING fts5(a
|   4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33   ,b,prefix=.1,2,3
|   4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29   ,4., content=..)
| page 2 offset 4096
|      0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4   ..j.7.L....L....
|     16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad   ...m.K.,........
|     32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5   ...l.K.)........
|     48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5   ...v.T.1........
|     64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0   ...s.T.2........
|     80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a ad   ...~.H..........
|     96: 0a 8c 0a 6d 0a 4d 0a 2b 0a 0c 09 ec 09 ca 09 a8   ...m.M.+........
|    112: 09 86 09 63 0f f1 00 00 00 00 00 00 00 00 00 00   ...c............
|   2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00   ................
|   2384: 30 00 00 00 01 01 03 35 00 03 01 01 12 02 01 12   0......5........
|   2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00   ............>...
|   2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68   ....4tabl.....wh
|   2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c   er.............<
|   2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e   .....4fts4.....n
|   2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03   umb.............
|   2480: 00 3c 00 00 00 16 04 33 74 68 65 13 06 01 01 04   .<.....3the.....
|   2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80   ..whe...........
|   2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01   ...<.....3num...
|   2528: 01 05 01 03 75 61 62 03 02 03 04 0a 19 8c 80 80   ....uab.........
|   2544: 80 80 0c 03 00 38 00 00 00 14 03 32 ec 68 03 02   .....8.....2.h..
|   2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80   ...3fts.........
|   2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02   .....6.....2ta..
|   2592: 03 02 01 68 03 06 01 01 04 04 17 1b 8c 80 80 80   ...h............
|   2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01   ....<.....2nu...
|   2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80   ....of..........
|   2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03   ......8.....2ft.
|   2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80   ....is..........
|   2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08   ......6.....1t..
|   2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80   ......w.........
|   2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01   .....:.....1n...
|   2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80   .....o..........
|   2736: 80 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03   ......6......1f.
|   2752: 02 02 01 01 69 03 06 01 01 03 05 06 1c 8c 80 80   ....i...........
|   2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03   .....>.....0the.
|   2784: 06 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15   ......where.....
|   2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06   ........0.......
|   2816: 06 30 74 61 62 6c 65 03 02 03 07 1c 8c 80 80 80   .0table.........
|   2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65   ....>.....0numbe
|   2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c   r.......of......
|   2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02   .......,........
|   2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03   0n..............
|   2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03   .<.....0fts4aux.
|   2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00   ....is........*.
|   2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88   .....$..........
|   2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80   ................
|   2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77   ......>.....4row
|   2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b   s.......ther....
|   2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01   .........0......
|   3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80   ...4betw........
|   3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77   .....<......3row
|   3040: 02 06 01 01 05 01 03 74 68 64 02 08 05 0a 1b 88   .......thd......
|   3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04   .......<........
|   3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08   3are.....bet....
|   3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32   .........<.....2
|   3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06   th........3and..
|   3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16   ...........<....
|   3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01   .2in.......ro...
|   3152: 01 43 04 09 18 88 80 80 80 80 0b 03 00 36 00 00   .C...........6..
|   3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02   ....2ar.....be..
|   3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 00 00   ............<...
|   3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02   ..1t........2an.
|   3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00   ..............8.
|   3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06   ....1n.......r..
|   3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00   ..............4.
|   3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01   ....1b.....i....
|   3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00   ............8...
|   3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01   ...12.....a.....
|   3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00   ............<...
|   3328: 16 06 30 74 68 65 72 65 02 02 01 00 02 30 21 02   ..0there.....0!.
|   3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00   ..............0.
|   3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07   .......0the.....
|   3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01   ..........>.....
|   3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73   ...0n.......rows
|   3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 51   .............<.Q
|   3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02   ...0between.....
|   3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a   in.............:
|   3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02   .....0and.......
|   3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00   re..............
|   3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32   4.....01.......2
|   3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00   ................
|   3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00   .............<..
|   3536: 00 16 05 34 74 51 62 6c 01 06 01 01 05 02 03 65   ...4tQbl.......e
|   3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c   rm.............<
|   3568: 00 00 00 16 05 34 65 17 63 68 01 02 03 01 04 70   .....4e.ch.....p
|   3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03   res.............
|   3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02   .:.....3ter.....
|   3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e   he..............
|   3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01   ..<.....3pre....
|   3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80   .tab............
|   3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 03   ....:.....3for..
|   3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80   ...ts...........
|   3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06   .....<.....2th..
|   3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84   .....3eac.......
|   3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61   .......6.....2ta
|   3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80   .......e........
|   3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01   ......8.....2in.
|   3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80   ......pr........
|   3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01   ......6.....2fo.
|   3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80   ....t...........
|   3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04   .....<.....1t...
|   3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84   ......2ea.......
|   3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01   .......4.....1i.
|   3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80   ......p.........
|   3888: 80 80 06 03 00 36 00 00 00 12 02 31 65 01 02 02   .....6.....1e...
|   3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80   ..f.............
|   3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01   ....<.....0term.
|   3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80   ....he..........
|   3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62   ............0tab
|   3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03   le..............
|   3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74   .0......0present
|   4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00   .............<..
|   4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e   ...0fts.......in
|   4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a   ...............:
|   4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 03 66   .....0each.....f
|   4064: 6f 72 01 02 01 f4 09 06 01 03 00 12 03 0b 0f 00   or..............
|   4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04   ................
| page 3 offset 8192
|      0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1   ....2.O.........
|     16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0   ................
|     32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f   .........x.q.h._
|     48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13   .V.M.A.8./.&....
|     64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd   ................
|     80: 0e c3 0e ba 0e b0 0e a8 0e 9f 0e 00 00 00 00 00   ................
|   3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08   ................
|   3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e   .....4t ......4.
|   3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03   ......3th.......
|   3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10   3n.......2w.....
|   3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04   ..2t.......2n...
|   3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 07   ....2.......1t..
|   3744: f4 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c   .....1n.......1.
|   3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03   ......0th.......
|   3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01   0t.......0nu....
|   3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01   ...0n...........
|   3808: 10 01 02 34 73 22 07 04 01 0e 01 02 34 20 08 04   ...4s.......4 ..
|   3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72   ....3r.......3ar
|   3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02   .......2t.......
|   3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01   2i.......2ar....
|   3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08   ...1t.......1n..
|   3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32   .....1b.......12
|   3904: 0e 0b 04 01 16 01 02 30 74 00 00 00 00 00 00 00   .......0t.......
| page 4 offset 12288
|   4064: 00 00 00 00 00 00 00 00 00 00 00 05 02 03 00 10   ................
|   4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04   ................
| page 5 offset 16384
|      0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70   ...............p
|   4080: 67 73 7a 08 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| end crash-8230e6c3b368f5.db
}]} {}

do_catchsql_test 63.1 {
  SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
} {/*malformed database schema*/}

do_catchsql_test 63.2 {
  INSERT INTO t1(t1) VALUES('optimize');
} {/*malformed database schema*/}

do_catchsql_test 63.3 {
  SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
} {/*malformed database schema*/}

#---------------------------------------------------------------------------
do_test 64.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-4470f0b94422f7.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 01 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 1a 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: 07 f3 03 02 01 65 03 1e 03 05 05 04 05 05 01 00   .....e..........
|   3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 06 05 04   ........6.......
|   3824: 06 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 06 f5 05 01 01   ......e.........
|   3856: 02 08 09 01 20 04 05 07 05 07 05 07 05 05 01 00   .... ...........
|   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 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 03 02 01 65 01 12 03   ............e...
|   4048: 05 05 01 01 03 06 04 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 01 01 00 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 03 0f ec 00 0f 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 0e 1a 00 0f c7 0f 5b 0e ef 0e 1a   ...........[....
|   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 66 20 65    eee e ee eeef 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 1f 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 03 ff 75 71 65 20 65 65 1f 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 65 65 20   e e e ee eee ee 
|   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 65 65 20 65 65 6a 02 04 00 75   e eee ee eej...u
|   3936: 40 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65   @e 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 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 0f e4 00 0f f9 0f f2 0f eb 0f e4   ................
|   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-4470f0b94422f7.db
}]} {}

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

#---------------------------------------------------------------------------
do_test 65.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-3aef66940ace0c.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
|    112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 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 3 offset 8192
|      0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00   ................
|   3216: 00 00 00 00 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 31 31 36 30   ...........21160
|   3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1   609...........3.
|   3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 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 01 f2 03 06 4e 02 02 03 06 01   ..........N.....
|   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 13 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 02 02 01 02   nable...........
|   3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02   ................
|   3472: 01 02 02 01 02 01 f1 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 76 b4 65 6e 73 69 6f 6e 1f 02   ......v.ension..
|   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 25 0d 02 03 01 02 03 01   ........%.......
|   3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03   ....gcc.........
|   3568: 02 06 65 6f 70 6f 6c 79 0f f2 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: 00 03 6d 61 78 1c 02 0c 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 13 06 00 f2 02 03   ocase...........
|   3680: 06 01 12 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 02 03 06 01 02 02 03 06 01 02 02 8e 06 01 02   ................
|   3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02   ................
|   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 11 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 01 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 01 f1 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 07 01 03 00 14 24 5a 24 24 0f   D..@.......$Z$$.
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 4 offset 12288
|      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 5 offset 16384
|      0: 0d 00 00 00 24 0c 0a 00 00 00 00 00 00 00 00 00   ....$...........
|   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 43 41 46 45 3d   ..%..THREADCAFE=
|   3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d   0XRTRIM.!..3..OM
|   3168: 49 54 20 4b 4f 41 44 21 45 58 54 45 4e 53 49 4f   IT KOAD!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 56 a9 4d 1f 1e 05 00 33 0f 19   IONXRTV.M....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 31 52 59 1f 1d 05 00 33 0f   000WBIN1RY....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 32   0000XNOCASE....2
|   3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30   ..NAX 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 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52   .f.%..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 10 25   MSYS5XRTRIM....%
|   3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42   ..EN@BLE 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 32 58 4e 4f 43 41 53 45 17   LE JSON2XNOCASE.
|   3568: 13 05 00 25 0f 17 45 4d 41 42 4c 45 20 4a 53 4f   ...%..EMABLE 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 81 42 4c   NARY....)..EO.BL
|   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 1a 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 48 4e 4f 43 41 53 45 16 1d 05   E FTS5HNOCASE...
|   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: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e   WNOCASE....#..EN
|   3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e   ABLE FTS4.RTRIM.
|   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 8a 4e 41 52   .....DEBUGXB.NAR
|   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 3f 87   ...C..COMPILER?.
|   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: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 2d   E.`YLER=gcc-5.4-
|   4080: 30 20 32 30 31 36 30 36 30 39 00 00 00 00 00 00   0 20160609......
| page 6 offset 20480
|   3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01   .$.......#......
|   3824: 06 22 03 01 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 02 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: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01   ................
|   4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01   ................
|   4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01   ................
|   4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01   ................
|   4080: 06 02 03 00 12 06 01 01 06 01 03 00 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.
| end crash-3aef66940ace0c.db
}]} {}

do_catchsql_test 65.1 {
  SELECT ( MATCH (t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ'
} {1 {malformed database schema (t2) - invalid rootpage}}

#-------------------------------------------------------------------------
#
reset_db
do_test 66.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-37cecb4e784e9f.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 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 49 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARI 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 01   ................
|   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: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 00 01 01   ...$............
| 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 01 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 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 09 01 52 1b 72 65 62 75 69 6c   ........R.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 crash-37cecb4e784e9f.db
}]} {}

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

#-------------------------------------------------------------------------
#
reset_db
do_test 67.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-43ed0ad79c0194.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 00 00 00 06 0d e2 00 0f c4 0f 6a   ...............j
|    112: 0e fc 0e 9d 0e 3d 0d e2 01 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 51 52 49 4d 41 52 59 20   INTEGER QRIMARY 
|   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 f1 59 20   INTEGER PRIMA.Y 
|   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 55 52 20 50 52 49 4d   (id INTEGUR PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 50 42 29 3a 02 06 17 13 13 08 5f 74 61 62 6c   LPB):......_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 71 00 0f e7 0e 81 0f af 0f 58   ..D...q........X
|     16: 0e 98 01 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 12 05 05   ...L.....0e.....
|   3760: 07 05 01 01 04 03 03 08 04 03 01 2e 02 05 f7 07   ................
|   3776: 01 e6 f5 07 05 01 01 04 03 03 01 22 03 18 03 03   ................
|   3792: 08 03 03 02 01 65 03 1e 03 05 05 04 05 05 01 01   .....e..........
|   3808: 03 06 03 f4 06 04 03 00 36 03 ff 05 04 05 05 04   ........6.......
|   3824: 05 05 04 05 04 f1 01 03 06 04 04 06 04 04 06 04   ................
|   3840: 04 07 04 03 03 01 65 03 14 04 05 07 05 05 01 01   ......e.........
|   3856: 02 08 a5 01 20 04 05 01 94 f7 05 07 05 05 01 01   .... ...........
|   3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 00 06 0a 0a 0a   .......e........
|   3888: 05 01 65 03 06 a7 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 11 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 e6 01 07 aa e3 08 03 03 02 01 65 02 1e 03 05   ...........e....
|   3968: 05 05 04 f5 01 01 03 06 04 04 06 04 13 03 01 65   ...............e
|   3984: 02 14 04 05 07 05 05 01 f7 f2 08 0a 04 01 65 02   ..............e.
|   4000: 02 0a 05 01 65 02 06 00 f1 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 00 01 04 03 03 02 01 65 01 12 03   ............e...
|   4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 04 05 04   ..........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 02   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
| page 4 offset 12288
|   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 28 15 20 65 65 20 65 65 65 65 20 65    eee(. 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 66 20 65 65 55 20    ee eeee ef eeU 
|   3680: 65 20 65 55 20 65 65 65 20 65 20 65 65 20 65 65   e eU eee e ee ee
|   3696: 65 64 20 65 61 c0 65 65 65 20 65 20 65 65 20 65   ed ea.eee e ee e
|   3712: 65 65 20 79 20 65 65 20 65 65 65 65 65 65 20 65   ee y ee eeeeee e
|   3728: 65 1f 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 65 65 20 6b 85 20 65 65 65 66 65    ee eee k. eeefe
|   3776: 20 65 65 10 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 30   ...uqe ee eee e0
|   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 1f 65 65 20 65 65 65    ee eee e.ee eee
|   3872: 20 65 20 65 65 20 65 65 65 65 65 66 20 65 65 20    e ee eeeeef ee 
|   3888: 65 21 27 20 65 20 55 65 20 66 65 64 20 65 65 00   e!' e Ue fed ee.
| page 5 offset 16384
|   4064: 00 00 00 00 05 04 03 00 10 11 20 05 03 03 00 10   .......... .....
|   4080: 11 11 05 02 03 00 00 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 01 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-43ed0ad79c0194.db
}]} {}

do_catchsql_test 67.1 {
  SELECT snippet(ttt, null,null,
      EXISTS(SELECT 1 FROM ttt('e NuOT ee*e*ÏNuOY ee*') ) , '', 
      (SELECT 1 FROM ttt('eu NuOT ee*e* NuOY ee*'))
  ), * FROM ttt('e') 
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 68.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-41234e232809e7.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 08   .....@  ........
|     32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04   ................
|     96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36   ...............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 20 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 3 offset 8192
|      0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00   ................
|     16: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00   ................
|   3216: 00 00 00 00 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 00 01 34 01   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 04   ......0000000...
|   3312: 01 02 04 01 02 03 f1 06 62 69 6e 62 72 79 03 06   ........binbry..
|   3328: 01 02 02 03 06 01 02 02 03 06 01 02 01 03 16 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 04 71 02 02 03 06 11 02 02 01 08 63 6f 6d 70   ..q.........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 06 65   ebug...........e
|   3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02   nable...........
|   3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 03 02   ................
|   3472: 00 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 66 63 63 01 02 03 01 02 03 01 02 03   ....fcc.........
|   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 5e 31 13 02 03 01 02 03 01 02   ...jso^1........
|   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 03 06 01 02 02 03 06 01 02 02 13 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 12 02 03 06   ..im............
|   3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01   ................
|   3792: 02 02 03 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 02   ................
|   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 05 f1 01 02 01   ................
|   3904: 06 01 01 02 01 06 01 5b 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 01 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 02 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 0f 0c 0e 11 10 0f 0e 10 0f   .D...G..........
|   4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f   D..@.......$Z$$.
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 4 offset 12288
|      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 0b 01 02   ................
| page 5 offset 16384
|      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 0d ef 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 3e 0c 24 0c 0a   .......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: 4f 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41   OARY.#..%..THREA
|   3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22   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 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT 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 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 46 45 58 4e 4f 43 41 53 45 17   LE RTRFEXNOCASE.
|   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: 49 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49   IABLE 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 57 42 49   NABLE GEOPOLYWBI
|   3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c   NARY....)..ENABL
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 42 41 53 45   E GEOPOLYXNOBASE
|   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 0d 05   E FTS5XNOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   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 b7 4e 41 42 4c 45 20 44 42 53   ...1...NABLE DBS
|   3904: 54 41 54 20 66 54 41 42 58 52 54 52 49 4d 11 06   TAT fTABXRTRIM..
|   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 62 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d   XbTRIM'...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 52 02 4a 4e 41 52 59 27   20160609R.JNARY'
|   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 52 49 4d   0 20160609XRTRIM
| page 6 offset 20480
|      0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0   ....$...........
|     16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f b0 0f a8 0f a0   ................
|     32: 0f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60   .........x.p.h.`
|     48: 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 0f 28 0f 20   .X.P.H.@.8.0.(. 
|     64: 0f 18 0f 10 0f 08 0f 00 0e f8 0e f0 0e e8 0e e0   ................
|   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 10 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: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01   ................
|   4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01   ................
|   4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01   ................
|   4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01   ................
|   4080: 06 02 03 00 12 06 01 01 06 01 03 00 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 00   ................
|   4048: 00 00 00 00 00 00 11 04 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 5d 69 71 a5   uild....opti]iq.
| end crash-41234e232809e7.db
.testctrl prng_seed 1 db
}]} {}

do_catchsql_test 68.1 { 
  PRAGMA reverse_unordered_selects=ON;
  INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 69.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-31c462b8b665d0.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 08   .....@  ........
|     32: 00 00 00 02 00 00 00 00 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
|    112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 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 39 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19   c9, 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 3 offset 8192
|      0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00   ................
|   3216: 00 00 00 00 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 01   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 04   ......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 00 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 06 65   ebug...........e
|   3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02   nable...........
|   3456: 02 01 02 02 01 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: 01 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 1a 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 aa 03 01 02 03 01 02 03   ....gcc.........
|   3568: 02 06 65 6f 70 6f 6c 79 10 02 03 02 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 03 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 01   ...omit.........
|   3744: ff ff ff ff ff ff ff ff f0 00 00 00 00 00 01 02   ................
|   3760: 58 81 96 4d 01 06 01 02 02 03 06 01 02 02 03 06   X..M............
|   3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01   ................
|   3792: 02 02 03 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 02   ................
|   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 1e 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: 00 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 01 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 02 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 0f 0b 0e 11 10 0f 0e 10 0f   .D...G..........
|   4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f   D..@.......$Z$$.
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 4 offset 12288
|      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 5 offset 16384
|      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 0d ef 0d d5   ...t.[.@.$......
|     48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 00 00 00 00 00   .......h.O......
|   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 22   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 d3 19 4f   NXBINARY. ..3..O
|   3200: 4d 49 54 28 2c 4f 41 44 b2 04 55 85 44 54 e5 34   MIT(,OAD..U.DT.4
|   3216: 94 f4 e5 84 e4 f4 34 15 34 51 e1 f0 50 03 30 f1   ......4.4Q..P.0.
|   3232: 74 f4 d4 95 42 04 c4 f4 14 42 04 55 85 44 54 e5   t...B....B.U.DT.
|   3248: 34 94 f4 e5 85 25 45 24 94 d1 f1 e0 50 03 30 f1   4....%E$....P.0.
|   3264: 94 d4 15 82 04 d4 54 d4 f5 25 93 d3 53 03 03 03   ......T..%..S...
|   3280: 03 03 03 05 84 24 94 e4 15 25 91 f1 d0 50 03 30   .....$...%...P.0
|   3296: f1 94 d4 15 82 04 d4 54 d4 f5 25 93 d3 53 03 03   .......T..%..S..
|   3312: 03 03 03 03 05 84 e4 f4 34 15 34 51 e1 c0 50 03   ........4.4Q..P.
|   3328: 30 f1 74 d4 15 82 04 d4 54 d4 f5 25 93 d3 53 03   0.t.....T..%..S.
|   3344: 03 03 03 03 03 05 85 25 45 24 94 d1 81 b0 50 02   .......%E$....P.
|   3360: 50 f1 94 54 e4 14 24 c4 52 05 25 45 24 54 55 84   P..T..$.R.%E$TU.
|   3376: 24 94 e4 15 25 91 81 a0 50 02 50 f1 94 54 e4 14   $...%...P.P..T..
|   3392: 24 c4 52 05 25 45 24 54 55 84 e4 f4 34 15 34 51   $.R.%E$TU...4.4Q
|   3408: 71 90 50 02 50 f1 74 54 e4 14 24 c4 52 05 25 45   q.P.P.tT..$.R.%E
|   3424: 24 54 55 85 25 45 24 94 d1 a1 80 50 02 90 f1 94   $TU.%E$....P....
|   3440: 54 e4 14 24 c4 52 04 d4 54 d5 35 95 33 55 84 24   T..$.R..T.5.3U.$
|   3456: 94 e4 15 25 91 a1 70 50 02 90 f1 94 54 e4 14 24   ...%..pP....T..$
|   3472: c4 52 04 d4 54 d5 35 95 33 55 84 e4 f4 34 15 34   .R..T.5.3U...4.4
|   3488: 51 91 60 50 02 90 f1 74 54 e4 14 24 c4 52 04 d4   Q.`P...tT..$.R..
|   3504: 54 d5 35 95 33 55 85 25 45 24 94 d1 81 50 50 02   T.5.3U.%E$...PP.
|   3520: 50 f1 94 54 e4 14 24 c4 52 04 a5 34 f4 e3 15 84   P..T..$.R..4....
|   3536: 24 94 e4 15 25 91 81 40 50 02 50 f1 94 54 e4 14   $...%..@P.P..T..
|   3552: 24 c4 52 04 a5 34 f4 e3 15 84 e4 f4 34 15 34 51   $.R..4......4.4Q
|   3568: 71 30 50 02 4f f1 74 54 e4 14 24 c4 52 04 a5 34   q0P.O.tT..$.R..4
|   3584: f4 e3 15 85 25 45 24 94 d1 a1 20 50 02 90 f1 94   ....%E$... P....
|   3600: 54 e4 14 24 c4 52 04 74 54 f5 04 f4 c5 95 84 24   T..$.R.tT......$
|   3616: 94 e4 15 25 91 a1 10 50 02 90 f1 94 54 e4 14 24   ...%...P....T..$
|   3632: c4 52 04 74 54 f5 04 f4 c5 95 84 e4 f4 34 15 34   .R.tT........4.4
|   3648: 51 91 00 50 02 90 f1 74 54 e4 14 24 c4 51 f4 74   Q..P...tT..$.Q.t
|   3664: 54 f5 04 f4 c5 95 85 25 45 24 94 d1 70 f0 50 02   T......%E$..p.P.
|   3680: 30 f1 94 54 e4 14 24 c5 20 46 54 53 35 58 42 49   0..T..$. 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 4f 4f 43 41 53 45 16 0d 05   E FTS5XOOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4e 41 52 59 97 0b   LE FTS4XBINARY..
|   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 3e 5f 19 45 4e 41 42 4c 45 20 44 42 53   ...>_.ENABLE DBS
|   3840: 44 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e   DAT 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 4d e3 45 1d   TAT VTABXNOCM.E.
|   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 02 02 50 08 5f 17 44 45 42 55 47   CASE...P._.DEBUG
|   3968: 58 52 54 52 49 4d 27 03 05 00 44 0f 19 43 4f 4d   XRTRIM'...D..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 c9 17 43   9XNOCASE&...C..C
|   4064: 4f 4d 50 49 4c 47 02 3d 67 63 63 2d 35 2e 34 2e   OMPILG.=gcc-5.4.
|   4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d   0 20160609XRTRIM
| page 6 offset 20480
|      0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0   ....$...........
|     16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f b0 0f a8 0f a0   ................
|     32: 0f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60   .........x.p.h.`
|     48: 0f 58 0f 50 0f 48 0f 40 0f 38 00 00 00 00 00 00   .X.P.H.@.8......
|   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 10 03 00 12 02 01 01 06 1f 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: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01   ................
|   4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01   ................
|   4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01   ................
|   4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01   ................
|   4080: 06 02 03 00 12 06 01 01 06 01 03 00 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 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   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 00 00 00 00 00 00   ity-check.......
| end crash-31c462b8b665d0.db
}]} {}


do_catchsql_test 69.2 {
  SELECT * FROM t1 WHERE a MATCH 'fx*'
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 70.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename sql022250.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 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 15 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 4d 54 45 47 45 52 20 50 52 49 4d 41 52 59 20   IMTEGER PRIMARY 
|   3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 20 29 5d 04 07   KEY, sz BLO )]..
|   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 54 00 05 0e 81 00 0f e7 0e 81 0f af 0f 58   ..T............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 14 03 03 08 03 03 08 03 bf   ................
|   3792: 07 f2 f3 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 15 04 05 05 01 01 03 06 04 04 06 04 04 a1 04   ................
|   3840: 04 06 04 03 03 01 65 03 14 04 05 07 05 05 01 01   ......e.........
|   3856: 02 09 0a 01 20 04 05 07 05 07 05 07 05 05 01 01   .... ...........
|   3872: 02 0f da 0a 0a 04 01 64 f3 02 0a 01 06 0a 0a 0a   .......d........
|   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 01 30 65 02 1a 02 05 05 07   ..$...G.0e......
|   3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1d f3 05   ...........e....
|   3968: 05 04 05 05 01 01 04 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 03 02 01 66 01 12 03   ............f...
|   4048: 05 05 01 01 03 06 04 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 01 01 00 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 2f 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ./..............
| page 4 offset 12288
|   3344: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 10 81   ...........R....
|   3360: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65   ].Ue ee eee e ee
|   3376: 20 65 65 65 20 65 20 65 65 20 65 65 65 65 20 65    eee e ee eeee e
|   3392: 65 20 65 65 65 24 a5 20 65 65 20 65 65 65 20 65   e eee$. ee eee e
|   3408: 24 05 65 20 65 65 65 65 20 65 65 20 65 65 65 20   $.e eeee ee eee 
|   3424: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65   e ee eee e ee ee
|   3440: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 10 65   ee ee eee e ee.e
|   3456: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65   ee e ee eeeeee e
|   3472: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65   e e e e ee eee e
|   3488: 1f 20 65 65 66 65 65 20 65 65 20 65 20 65 20 2d   . eefee ee e e -
| page 5 offset 16384
|   4064: 00 00 00 00 05 04 d0 00 10 21 21 05 03 03 00 10   .........!!.....
|   4080: 11 11 05 02 03 00 10 11 10 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 sql022250.txt.db
}]} {}

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

} {1 {database disk image is malformed}}
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

Deleted ext/fts5/test/fts5corrupt4.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































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 May 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.
#
#***********************************************************************
#
#

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

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

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"
}
db func mutate mutate

for {set j 1000} {$j <= 5000} {incr j 1000} {
  do_test 1.$j {
    for {set i 0} {$i < 1000} {incr i} {
      execsql {
        BEGIN;
          UPDATE ttt_data SET block = mutate(block, $i) WHERE id>10;
      }
      foreach sql {
        {SELECT snippet(ttt, -1, '.', '..', '[', ']'), * FROM ttt('e*')}
        {SELECT snippet(ttt, -1, '.', '..', '[', ']'), * FROM ttt('e* NOT ee*')}
      } {
        catch { execsql $sql }
      }
      execsql ROLLBACK
    }
  } {}
}

sqlite3_fts5_may_be_corrupt 0
finish_test

Changes to ext/fts5/test/fts5delete.test.

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
46
47
48
49
50
51
52































































53








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

-
  execsql { INSERT INTO t1(t1, rank) VALUES('usermerge', 2); }
  for {set i 0} {$i < 5} {incr i} {
    execsql { INSERT INTO t1(t1, rank) VALUES('merge', 1) }
    execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
  }
} {}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE test (
      id INTEGER PRIMARY KEY,
      name TEXT,
      value TEXT
  );
  CREATE VIRTUAL TABLE test_idx USING fts5(
      name, content=test, content_rowid=id
  );
}

do_catchsql_test 2.1 {
  INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 1, 'quick');
} {1 {database disk image is malformed}}

do_catchsql_test 2.2 {
  INSERT INTO test_idx(rowid, name) VALUES(123, 'one one one');
  INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
  INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
} {1 {database disk image is malformed}}

do_execsql_test 2.3 {
  DROP TABLE test_idx;
  CREATE VIRTUAL TABLE test_idx USING fts5(
      name, content=test, content_rowid=id
  );

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

Changes to ext/fts5/test/fts5eb.test.

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
55
56
57
58
59
60
61

62
63
64
65

















66
67
68
69
70
71
72







-
+



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







  do_execsql_test 1.$tn {SELECT fts5_expr($expr)} [list $res]
}

do_catchsql_test 2.1 {
  SELECT fts5_expr()
} {1 {wrong number of arguments to function fts5_expr}}

do_catchsql_test 2.2 {
do_catchsql_test 2.1 {
  SELECT fts5_expr_tcl()
} {1 {wrong number of arguments to function fts5_expr_tcl}}

do_catchsql_test 2.3 {
  SELECT fts5_expr('')
} {1 {fts5: syntax error near ""}}

do_catchsql_test 2.4 {
  SELECT fts5_expr(NULL)
} {1 {fts5: syntax error near ""}}

do_catchsql_test 2.5 {
  SELECT fts5_expr(NULL, NULL)
} {1 {parse error in ""}}

for {set i 0} {$i < 255} {incr i} {
  do_test 2.6.$i {
    lindex [catchsql {sELECT fts5_expr(NULL, char($i));}] 0
  } 1
}

do_execsql_test 3.0 {
  CREATE VIRTUAL TABLE e1 USING fts5(text, tokenize = 'porter unicode61');
  INSERT INTO e1 VALUES ("just a few words with a / inside");
}
do_execsql_test 3.1 {
  SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"just"' ORDER BY rank;

Changes to ext/fts5/test/fts5faultB.test.

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
143
144
145
146
147
148
149






















150
151







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


}
do_faultsim_test 5.1 -faults oom* -body {
  execsql { SELECT rowid FROM t1('^a OR ^b') }
} -test {
  faultsim_test_result {0 {1 4}}
}

#-------------------------------------------------------------------------
# Test OOM injection in a query with two MATCH expressions
#
reset_db
do_execsql_test 6.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
  INSERT INTO t1 VALUES('a b c d');  -- 1
  INSERT INTO t1 VALUES('d a b c');  -- 2
  INSERT INTO t1 VALUES('c d a b');  -- 3
  INSERT INTO t1 VALUES('b c d a');  -- 4
}
do_faultsim_test 6.1 -faults oom* -body {
  execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a' AND t1 MATCH 'b' }
} -test {
  faultsim_test_result {0 {1 2 3 4}}
}
do_faultsim_test 6.2 -faults oom* -body {
  execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a OR b' AND t1 MATCH 'c OR d' }
} -test {
  faultsim_test_result {0 {1 2 3 4}}
}


finish_test

Changes to ext/fts5/test/fts5faultD.test.

10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







#*************************************************************************
#
# This file is focused on OOM errors.
#

source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5faultD
set testprefix fts5faultA

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

Deleted ext/fts5/test/fts5faultE.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







































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2016 February 2
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
#
# This file is focused on OOM errors.
#

source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5faultE

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

faultsim_save_and_close
do_faultsim_test 1 -prep {
  faultsim_restore_and_reopen
} -body {
  execsql { CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram) }
} -test {
  faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} 
}

reset_db
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram);
}

faultsim_save_and_close
do_faultsim_test 2 -prep {
  faultsim_restore_and_reopen
} -body {
  execsql { 
    INSERT INTO t1 VALUES('abcdefghijklmnopqrstuvwxyz', NULL);
    SELECT count(*) FROM t1 WHERE x LIKE '%mnop%' AND t1 MATCH 'jkl';
  }
} -test {
  faultsim_test_result {0 1} {1 {vtable constructor failed: t1}}
}

reset_db
do_execsql_test 3.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram, detail=none);
  INSERT INTO t1 VALUES('abcdefghijklmnopqrstuvwxyz', NULL);
}

faultsim_save_and_close
do_faultsim_test 3 -prep {
  faultsim_restore_and_reopen
} -body {
  execsql { 
    SELECT count(*) FROM t1 WHERE x LIKE '%mnopqrs%' AND t1 MATCH 'abc'
  }
} -test {
  faultsim_test_result {0 1} {1 {vtable constructor failed: t1}}
}



finish_test

Changes to ext/fts5/test/fts5full.test.

32
33
34
35
36
37
38
39

40
41
42
32
33
34
35
36
37
38

39
40
41
42







-
+



db func rnddoc fts5_rnddoc
do_test 1.1 {
  list [catch {
    for {set i 0} {$i < 2500} {incr i} {
      execsql { INSERT INTO x8 VALUES( rnddoc(5) ); }
    }
  } msg] $msg
} {0 {}}
} {1 {database or disk is full}}


finish_test

Changes to ext/fts5/test/fts5hash.test.

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
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130





































131







-
+















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

    INSERT INTO eee(eee) VALUES('integrity-check');
  }

  #-----------------------------------------------------------------------
  # Add a small and very large token with the same hash value to an
  # empty table. At one point this would provoke an asan error.
  #
  do_test 1.5 {
  do_test 2.0 {
    set big [string repeat 12345 40]
    set hash [sqlite3_fts5_token_hash 1024 $big]
    while {1} {
      set small [random_token]
      if {[sqlite3_fts5_token_hash 1024 $small]==$hash} break
    }

    execsql { CREATE VIRTUAL TABLE t2 USING fts5(x, detail=%DETAIL%) }
    execsql {
      INSERT INTO t2 VALUES($small || ' ' || $big);
    }
  } {}

} ;# foreach_detail_mode

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(x);
  INSERT INTO t1(t1, rank) VALUES('hashsize', 1024);
  INSERT INTO t1(t1, rank) VALUES('automerge', 0);
  INSERT INTO t1(t1, rank) VALUES('crisismerge', 1000);
}

do_execsql_test 2.2 {
  BEGIN;
    INSERT INTO t1 VALUES('abc def ghi');
    SELECT count(*) FROM t1_data;
} {2}

do_execsql_test 2.3 {
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1024
  )
  INSERT INTO t1 SELECT 'abc def ghi' FROM s;
  SELECT (SELECT count(*) FROM t1_data) > 10;
} {1}

do_execsql_test 2.4 {
  COMMIT;
  DROP TABLE t1;
  CREATE VIRTUAL TABLE t1 USING fts5(x);
  INSERT INTO t1(t1, rank) VALUES('hashsize', 1024);
  INSERT INTO t1(t1, rank) VALUES('automerge', 0);
  INSERT INTO t1(t1, rank) VALUES('crisismerge', 1000);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1024
  )
  INSERT INTO t1 SELECT 'abc' || i || ' def' || i || ' ghi' || i FROM s;
  SELECT (SELECT count(*) FROM t1_data) > 100;
} {1}

finish_test

Changes to ext/fts5/test/fts5integrity.test.

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
206
207
208
209
210
211
212











































































































213







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

      set res2 [db eval { SELECT rowid FROM hh($T) ORDER BY rowid DESC }]
      if {$res == [lsort -integer $res2]} { incr ok }
    }
    set ok
  } {1000}
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 7.0 {
  PRAGMA encoding = 'UTF-16';
  CREATE VIRTUAL TABLE vt0 USING fts5(c0);
  INSERT INTO vt0 VALUES (x'46f0');
  SELECT quote(c0) FROM vt0;
} {X'46F0'}
do_execsql_test 7.1 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}
do_execsql_test 7.2 {
  INSERT INTO vt0(vt0) VALUES('rebuild');
}
do_execsql_test 7.3 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}
do_execsql_test 7.4 {
  UPDATE vt0 SET c0='';
}
do_execsql_test 7.5 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
# Ticket 7a458c2a5f4
#
reset_db
do_execsql_test 8.0 {
  PRAGMA locking_mode = EXCLUSIVE;
  PRAGMA journal_mode = PERSIST;
  CREATE VIRTUAL TABLE vt0 USING fts5(c0);
} {exclusive persist}
do_execsql_test 8.1 {
  PRAGMA data_version
} {1}
do_execsql_test 8.2 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
  PRAGMA data_version;
} {1}
do_execsql_test 8.1 {
  INSERT INTO vt0(vt0, rank) VALUES('usermerge', 2);
}

#-------------------------------------------------------------------------
# Ticket [771fe617]
#
reset_db
do_execsql_test 9.0 {
  PRAGMA encoding = 'UTF16';
  CREATE VIRTUAL TABLE vt0 USING fts5(c0);
}

#explain_i { SELECT quote(SUBSTR(x'37', 0)); }
#execsql { PRAGMA vdbe_trace = 1 }
do_execsql_test 9.1.1 {
  SELECT quote(SUBSTR(x'37', 0));
} {X'37'}
do_execsql_test 9.1.2 {
  SELECT quote(x'37');
} {X'37'}

do_execsql_test 9.2 {
  INSERT INTO vt0 VALUES (SUBSTR(x'37', 0));
--  INSERT INTO vt0 VALUES (x'37');
}
do_execsql_test 9.3 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 10.0 {
  CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b);
  CREATE VIRTUAL TABLE vt0 USING fts5(a, b, content=t1);
  INSERT INTO vt0(rowid, a, b) VALUES(1, 'abc', 'def');
}
do_catchsql_test 10.1 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
} {0 {}}
do_catchsql_test 10.2 {
  INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 0);
} {0 {}}
do_catchsql_test 10.3 {
  INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
} {1 {database disk image is malformed}}
do_catchsql_test 10.3 {
  INSERT INTO t1 VALUES(1, 'abc', 'def');
  INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
} {0 {}}

do_execsql_test 10.4 {
  CREATE VIRTUAL TABLE vt1 USING fts5(a, b, content=);
  INSERT INTO vt1(rowid, a, b) VALUES(1, 'abc', 'def');
}

do_catchsql_test 10.5.1 {
  INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 0);
} {0 {}}
do_catchsql_test 10.5.2 {
  INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
} {0 {}}
do_catchsql_test 10.5.3 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
} {0 {}}

finish_test

Changes to ext/fts5/test/fts5matchinfo.test.

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
487
488
489
490
491
492
493





























494







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

  INSERT INTO x1 VALUES('a b c a b c a b c');
} {}

do_catchsql_test 14.2 {
  SELECT matchinfo(x1, 'd') FROM x1('a b c');
} {1 {unrecognized matchinfo flag: d}}

#-------------------------------------------------------------------------
# Test using matchinfo() and similar on a non-full-text query
#
do_execsql_test 15.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y);
  INSERT INTO t1 VALUES('a', 'b');
  INSERT INTO t1 VALUES('c', 'd');
}

if {$tcl_platform(byteOrder)=="littleEndian"} {
  set res {X'02000000'}
} else {
  set res {X'00000002'}
}
do_execsql_test 15.1 {
  SELECT quote(matchinfo(t1, 'n')) FROM t1 LIMIT 1;
} $res
do_execsql_test 15.2 {
  DELETE FROM t1_content WHERE rowid=1;
  SELECT quote(matchinfo(t1, 'n')) FROM t1 LIMIT 1;
} $res

fts5_aux_test_functions db
do_execsql_test 15.3 {
  SELECT fts5_test_all(t1) FROM t1 LIMIT 1;
} {
  {columnsize {0 0} columntext {c d} columntotalsize {2 2} poslist {} tokenize {c d} rowcount 2}
}

finish_test

Deleted ext/fts5/test/fts5misc.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







































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 September 02
#
# 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 FTS5 module.
#

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

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

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
}

do_catchsql_test 1.1.1 { 
  SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*'); 
} {1 {unknown special query: }}
do_catchsql_test 1.1.2 {
  SELECT a FROM t1
    WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*'));
} {1 {unknown special query: }}

do_catchsql_test 1.2.1 { 
  SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*id'); 
} {0 {{}}}

do_catchsql_test 1.2.2 {
  SELECT a FROM t1
    WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*id'));
} {0 {}}

do_catchsql_test 1.3.1 { 
  SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'); 
} {1 {no such cursor: 1}}

do_catchsql_test 1.3.2 {
  SELECT a FROM t1
    WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'));
} {1 {no such cursor: 1}}

db close
sqlite3 db test.db

do_catchsql_test 1.3.3 {
  SELECT a FROM t1
    WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'));
} {1 {no such cursor: 1}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t0(c0);
  CREATE VIRTUAL TABLE vt0 USING fts5(c0);
}
do_execsql_test 2.1.1 {
  BEGIN TRANSACTION;
  INSERT INTO vt0(c0) VALUES ('xyz');
}
do_execsql_test 2.1.2 {
  ALTER TABLE t0 ADD COLUMN c5;
}
do_execsql_test 2.1.3 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}
do_execsql_test 2.1.4 {
  INSERT INTO vt0(c0) VALUES ('abc');
  COMMIT
}
do_execsql_test 2.1.5 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

reset_db
do_execsql_test 2.2.1 {
  CREATE TABLE t0(c0);
  CREATE VIRTUAL TABLE vt0 USING fts5(c0);
  BEGIN TRANSACTION;
  INSERT INTO vt0(c0) VALUES ('xyz');
}

breakpoint
do_execsql_test 2.2.2 {
  ALTER TABLE t0 RENAME TO t1;
}
do_execsql_test 2.2.3 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}
do_execsql_test 2.2.4 {
  INSERT INTO vt0(c0) VALUES ('abc');
  COMMIT;
}
do_execsql_test 2.2.5 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
  CREATE VIRTUAL TABLE vt0 USING fts5(a);
  PRAGMA reverse_unordered_selects = true;
  INSERT INTO vt0 VALUES('365062398'), (0), (0);
  INSERT INTO vt0(vt0, rank) VALUES('pgsz', '38');
}
do_execsql_test 3.1 {
  UPDATE vt0 SET a = 399905135; -- unexpected: database disk image is malformed
}
do_execsql_test 3.2 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE vt0 USING fts5(c0);
  INSERT INTO vt0(c0) VALUES ('xyz');
}

do_execsql_test 4.1 {
  BEGIN;
    INSERT INTO vt0(c0) VALUES ('abc');
    INSERT INTO vt0(vt0) VALUES('rebuild');
  COMMIT;
}

do_execsql_test 4.2 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

do_execsql_test 4.3 {
  BEGIN;
    INSERT INTO vt0(vt0) VALUES('rebuild');
    INSERT INTO vt0(vt0) VALUES('rebuild');
  COMMIT;
}

do_execsql_test 4.4 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
# Ticket [81a7f7b9].
#
reset_db
do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE vt0 USING fts5(c0, c1);
  INSERT INTO vt0(vt0, rank) VALUES('pgsz', '65536');
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1236
  )
  INSERT INTO vt0(c0) SELECT '0' FROM s;
} {}

do_execsql_test 5.1 {
  UPDATE vt0 SET c1 = 'T,D&p^y/7#3*v<b<4j7|f';
}

do_execsql_test 5.2 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

do_catchsql_test 5.3 {
  INSERT INTO vt0(vt0, rank) VALUES('pgsz', '65537');
} {1 {SQL logic error}}

#-------------------------------------------------------------------------
# Ticket [d392017c].
#
reset_db
do_execsql_test 6.0 {
  CREATE VIRTUAL TABLE vt0 USING fts5(c0);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000
  )
  INSERT INTO vt0(c0) SELECT '0' FROM s;
  INSERT INTO vt0(vt0, rank) VALUES('crisismerge', 2000);
  INSERT INTO vt0(vt0, rank) VALUES('automerge', 0);
} {}

do_execsql_test 6.1 {
  INSERT INTO vt0(vt0) VALUES('rebuild');
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 7.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(x);
  INSERT INTO t1(rowid, x) VALUES(1, 'hello world');
  INSERT INTO t1(rowid, x) VALUES(2, 'well said');
  INSERT INTO t1(rowid, x) VALUES(3, 'hello said');
  INSERT INTO t1(rowid, x) VALUES(4, 'well world');

  CREATE TABLE t2 (a, b);
  INSERT INTO t2 VALUES(1, 'hello');
  INSERT INTO t2 VALUES(2, 'world');
  INSERT INTO t2 VALUES(3, 'said');
  INSERT INTO t2 VALUES(4, 'hello');
}

do_execsql_test 7.1 {
  SELECT rowid FROM t1 WHERE (rowid, x) IN (SELECT a, b FROM t2); 
}

do_execsql_test 7.2 {
  SELECT rowid FROM t1 WHERE rowid=2 AND t1 = 'hello';
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 8.0 {
  CREATE VIRTUAL TABLE vt0 USING fts5(c0, tokenize = "ascii", prefix = 1);
  INSERT INTO vt0(c0) VALUES (x'd1');
}

do_execsql_test 8.1 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 9.0 {
  CREATE VIRTUAL TABLE t1 using FTS5(mailcontent);
  insert into t1(rowid, mailcontent) values
      (-4764623217061966105, 'we are going to upgrade'),
      (8324454597464624651, 'we are going to upgrade');
}

do_execsql_test 9.1 {
  INSERT INTO t1(t1) VALUES('integrity-check');
}

do_execsql_test 9.2 {
  SELECT rowid FROM t1('upgrade');
} {
  -4764623217061966105 8324454597464624651
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 10.0 {
  CREATE VIRTUAL TABLE vt1 USING fts5(c1, c2, prefix = 1, tokenize = "ascii");
  INSERT INTO vt1 VALUES (x'e4', '䔬');
}

do_execsql_test 10.1 {
  SELECT quote(CAST(c1 AS blob)), quote(CAST(c2 AS blob)) FROM vt1
} {X'E4' X'E494AC'}

do_execsql_test 10.2 {
  INSERT INTO vt1(vt1) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 11.0 {
  CREATE VIRTUAL TABLE vt0 USING fts5(
      c0, prefix = 71, tokenize = "porter ascii", prefix = 9
  );
} {}
do_execsql_test 11.1 {
  BEGIN;
  INSERT INTO vt0(c0) VALUES (x'e8');
}
do_execsql_test 11.2 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
# Ticket [752fdbf6] 
#
reset_db
do_execsql_test 11.0 {
  PRAGMA encoding = 'UTF-16';
  CREATE VIRTUAL TABLE vt0 USING fts5(c0, c1);
  INSERT INTO vt0(vt0, rank) VALUES('pgsz', '37');
  INSERT INTO vt0(c0, c1) VALUES (0.66077, 1957391816);
}
do_execsql_test 11.1 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
# Ticket [7c0e06b16] 
#
do_execsql_test 12.0 {
  CREATE TABLE t1(a, b, rank);
  INSERT INTO t1 VALUES('a', 'hello', '');
  INSERT INTO t1 VALUES('b', 'world', '');

  CREATE VIRTUAL TABLE ft USING fts5(a);
  INSERT INTO ft VALUES('b');
  INSERT INTO ft VALUES('y');

  CREATE TABLE t2(x, y, ft);
  INSERT INTO t2 VALUES(1, 2, 'x');
  INSERT INTO t2 VALUES(3, 4, 'b');
}

do_execsql_test 12.1 {
  SELECT * FROM t1 NATURAL JOIN ft WHERE ft MATCH('b')
} {b world {}}
do_execsql_test 12.2 {
  SELECT * FROM ft NATURAL JOIN t1 WHERE ft MATCH('b')
} {b world {}}
do_execsql_test 12.3 {
  SELECT * FROM t2 JOIN ft USING (ft)
} {3 4 b b}

finish_test

Deleted ext/fts5/test/fts5multi.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



































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2014 September 13
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the FTS5 module.
#

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

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

fts5_aux_test_functions db

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a, b, c);
  INSERT INTO t1 VALUES('gg bb bb'   ,'gg ff gg'   ,'ii ii');
  INSERT INTO t1 VALUES('dd dd hh kk','jj'         ,'aa');
  INSERT INTO t1 VALUES('kk gg ee'   ,'hh cc'      ,'hh jj aa cc');
  INSERT INTO t1 VALUES('hh'         ,'bb jj cc'   ,'kk ii');
  INSERT INTO t1 VALUES('kk dd kk ii','aa ee aa'   ,'ee');
  INSERT INTO t1 VALUES('ee'         ,'ff gg kk aa','ee ff ee');
  INSERT INTO t1 VALUES('ff jj'      ,'gg ee'      ,'kk ee gg kk');
  INSERT INTO t1 VALUES('ff ee dd hh','kk ee'      ,'gg dd');
  INSERT INTO t1 VALUES('bb'         ,'aa'         ,'bb aa');
  INSERT INTO t1 VALUES('hh cc bb'   ,'ff bb'      ,'cc');
  INSERT INTO t1 VALUES('jj'         ,'ff dd bb aa','dd dd ff ff');
  INSERT INTO t1 VALUES('ff dd gg dd','gg aa bb ff','cc');
  INSERT INTO t1 VALUES('ff aa cc jj','kk'         ,'ii dd');
  INSERT INTO t1 VALUES('jj dd'      ,'cc'         ,'ii hh ee aa');
  INSERT INTO t1 VALUES('ff ii hh'   ,'dd'         ,'gg');
  INSERT INTO t1 VALUES('ff dd gg hh','hh'         ,'ff dd');
  INSERT INTO t1 VALUES('cc cc'      ,'ff dd ff'   ,'bb');
  INSERT INTO t1 VALUES('ii'         ,'bb ii'      ,'jj kk');
  INSERT INTO t1 VALUES('ff hh'      ,'hh bb'      ,'bb dd ee');
  INSERT INTO t1 VALUES('jj kk'      ,'jj'         ,'gg ff cc');
  INSERT INTO t1 VALUES('dd kk'      ,'ii gg'      ,'dd');
  INSERT INTO t1 VALUES('cc'         ,'aa ff'      ,'ii');
  INSERT INTO t1 VALUES('bb ff bb ii','bb kk bb aa','hh ff ii dd');
  INSERT INTO t1 VALUES('aa'         ,'ee bb jj jj','dd');
  INSERT INTO t1 VALUES('kk dd cc'   ,'aa jj'      ,'ee aa ff');
  INSERT INTO t1 VALUES('aa gg aa'   ,'jj'         ,'ii kk hh gg');
  INSERT INTO t1 VALUES('ff hh aa'   ,'jj ii'      ,'hh dd bb jj');
  INSERT INTO t1 VALUES('hh'         ,'aa gg kk'   ,'bb ee');
  INSERT INTO t1 VALUES('bb'         ,'ee'         ,'gg');
  INSERT INTO t1 VALUES('dd kk'      ,'kk bb aa'   ,'ee');
}

foreach {tn c1 e1 c2 e2} {
  1     t1 aa     t1 bb
  2     a  aa     b  bb
  3     a  "aa OR bb OR cc"    b  "jj OR ii OR hh"
  4     t1  "aa AND bb"       t1  "cc"
  5     c   "kk"               b  "aa OR bb OR cc OR dd OR ee"
} {
  if {$c1=="t1"} {
    set lhs "( $e1 )"
  } else {
    set lhs "$c1 : ( $e1 )"
  }
  if {$c2=="t1"} {
    set rhs "( $e2 )"
  } else {
    set rhs "$c2 : ( $e2 )"
  }

  set q1 "t1 MATCH '($lhs) AND ($rhs)'"
  set q2 "$c1 MATCH '$e1' AND $c2 MATCH '$e2'"

  set ret [execsql "SELECT rowid FROM t1 WHERE $q1"]
  set N [llength $ret]
  do_execsql_test 1.$tn.1.($N) "SELECT rowid FROM t1 WHERE $q2" $ret

  set ret [execsql "SELECT fts5_test_poslist(t1) FROM t1 WHERE $q1"]
  do_execsql_test 1.$tn.2.($N) "
    SELECT fts5_test_poslist(t1) FROM t1 WHERE $q2
  " $ret
}

do_catchsql_test 2.1.1 {
  SELECT rowid FROM t1 WHERE t1 MATCH '(NOT' AND t1 MATCH 'aa bb';
} {1 {fts5: syntax error near "NOT"}}
do_catchsql_test 2.1.2 {
  SELECT rowid FROM t1 WHERE t1 MATCH 'aa bb' AND t1 MATCH '(NOT';
} {1 {fts5: syntax error near "NOT"}}

finish_test

Changes to ext/fts5/test/fts5plan.test.

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







-
+














-
+













-
+


}

do_eqp_test 1.1 {
  SELECT * FROM t1, f1 WHERE f1 MATCH t1.x
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:M1
  `--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
}

do_eqp_test 1.2 {
  SELECT * FROM t1, f1 WHERE f1 > t1.x
} {
  QUERY PLAN
  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:
  `--SCAN TABLE t1
}

do_eqp_test 1.3 {
  SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
} {
  QUERY PLAN
  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:M1
  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
  `--USE TEMP B-TREE FOR ORDER BY
}

do_eqp_test 1.4 {
  SELECT * FROM f1 ORDER BY rank
} {
  QUERY PLAN
  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:
  `--USE TEMP B-TREE FOR ORDER BY
}

do_eqp_test 1.5 {
  SELECT * FROM f1 WHERE rank MATCH ?
} {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:r}
} {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}

finish_test

Deleted 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/fts5/test/fts5rank.test.

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
158
159
160
161
162
163
164


















165







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

  INSERT INTO ttt SELECT 'word ' || i FROM s;
}

do_execsql_test 5.1 {
  SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
} {30 31 32 33 34 35 36 37 38 39 40}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
  CREATE VIRTUAL TABLE "My.Table" USING fts5(Text);

  INSERT INTO "My.Table" VALUES ('hello this is a test');
  INSERT INTO "My.Table" VALUES ('of trying to order by');
  INSERT INTO "My.Table" VALUES ('rank on an fts5 table');
  INSERT INTO "My.Table" VALUES ('that have periods in');
  INSERT INTO "My.Table" VALUES ('the table names.');
  INSERT INTO "My.Table" VALUES ('table table table');
}
do_execsql_test 6.1 {
  SELECT * FROM "My.Table" WHERE Text MATCH 'table' ORDER BY rank;
} {
  {table table table} {the table names.} {rank on an fts5 table}
}

finish_test

Deleted ext/fts5/test/fts5savepoint.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





















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 Dec 26
#
# 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.
#
#***********************************************************************
#

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

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

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE ft USING fts5(c);
  BEGIN;
    SAVEPOINT one;
      INSERT INTO ft VALUES('a');
      SAVEPOINT two;
        INSERT INTO ft VALUES('b');
      RELEASE two;
      SAVEPOINT four;
        INSERT INTO ft VALUES('c');
      RELEASE four;
      SAVEPOINT three;
        INSERT INTO ft VALUES('d');
      ROLLBACK TO three;
  COMMIT;
  SELECT * FROM ft
} {a b c}

reset_db
do_catchsql_test 2.0 {
  CREATE VIRTUAL TABLE ft1 USING fts5(c);
  CREATE VIRTUAL TABLE ft2 USING fts5(c);
  DROP TABLE ft2_idx;
  BEGIN;
      INSERT INTO ft2 VALUES('a');
      INSERT INTO ft1 VALUES('a');
      SAVEPOINT two;
        INSERT INTO ft1 VALUES('b');
  COMMIT;
} {1 {SQL logic error}}

reset_db
ifcapable fts3 {
  do_execsql_test 3.0 {
    CREATE VIRTUAL TABLE vt0 USING fts5(c0);
    CREATE VIRTUAL TABLE vt1 USING fts4(c0);
    INSERT INTO vt1(c0) VALUES(0);
  }

  do_execsql_test 3.1 {
    BEGIN;
      UPDATE vt1 SET c0 = 0;
      INSERT INTO vt1(c0) VALUES (0), (0);
      UPDATE vt0 SET c0 = 0;
      INSERT INTO vt1(c0) VALUES (0);
      UPDATE vt1 SET c0 = 0;
      INSERT INTO vt1(vt1) VALUES('automerge=1');
      UPDATE vt1 SET c0 = 0;
  }

  do_catchsql_test 3.2 {
    DROP TABLE vt1;
  } {1 {SQL logic error}}

  do_execsql_test 3.3 {
    SAVEPOINT x;
      INSERT INTO vt0 VALUES('x');
    COMMIT;
    INSERT INTO vt0(vt0) VALUES('integrity-check');
  }
}

finish_test

Changes to ext/fts5/test/fts5simple.test.

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
463
464
465
466
467
468
469













470







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

} {11111 11112}
do_execsql_test 21.3 {
  DELETE FROM x1 WHERE rowid=11111;
  INSERT INTO x1(x1) VALUES('integrity-check');
  SELECT rowid FROM x1($doc);
} {11112}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 22.0 {
  CREATE VIRTUAL TABLE x1 USING fts5(x);
  INSERT INTO x1(x) VALUES('a b c');
  INSERT INTO x1(x) VALUES('x y z');
  INSERT INTO x1(x) VALUES('c b a');
  INSERT INTO x1(x) VALUES('z y x');
}

do_catchsql_test 22.1 {SELECT * FROM x1('')}   {1 {fts5: syntax error near ""}}
do_catchsql_test 22.2 {SELECT * FROM x1(NULL)} {1 {fts5: syntax error near ""}}

finish_test

Changes to ext/fts5/test/fts5tok1.test.

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
107
108
109
110
111
112
113



































114
115







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


} {1 {vtable constructor failed: tX}}

do_catchsql_test 2.1 {
  CREATE VIRTUAL TABLE t4 USING fts5tokenize;
  SELECT * FROM t4;
} {1 {SQL logic error}}

#-------------------------------------------------------------------------
# Embedded 0x00 characters.
#
reset_db
do_execsql_test 3.1.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(z);
  CREATE VIRTUAL TABLE tt USING fts5vocab(t1, 'instance');
  INSERT INTO t1 VALUES('abc' || char(0) || 'def');
  SELECT * FROM tt;
} { abc 1 z 0 def 1 z 1 }
do_execsql_test 3.1.1 {
  SELECT hex(z) FROM t1;
} {61626300646566}
do_execsql_test 3.1.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {}

do_execsql_test 3.2.0 {
  CREATE VIRTUAL TABLE t2 USING fts5(z, 
      tokenize="unicode61 categories 'L* N* Co Cc'"
  );
  CREATE VIRTUAL TABLE tu USING fts5vocab(t2, 'instance');

  INSERT INTO t2 VALUES('abc' || char(0) || 'def');
  SELECT * FROM tu;
} { abc 1 z 0 def 1 z 1 }

do_execsql_test 3.2.1 {
  SELECT hex(z) FROM t1;
} {61626300646566}

do_execsql_test 3.2.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {}


finish_test

Deleted ext/fts5/test/fts5trigram.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









































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 September 30
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
#
# Tests for the fts5 "trigram" tokenizer.
#

source [file join [file dirname [info script]] fts5_common.tcl]
ifcapable !fts5 { finish_test ; return }
set ::testprefix fts5trigram

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize=trigram);
  INSERT INTO t1 VALUES('abcdefghijklm');
  INSERT INTO t1 VALUES('กรุงเทพมหานคร');
}

foreach {tn s res} {
  1 abc           "(abc)defghijklm"
  2 defgh         "abc(defgh)ijklm"
  3 abcdefghijklm "(abcdefghijklm)"
  4 กรุ            "(กรุ)งเทพมหานคร"
  5 งเทพมห        "กรุ(งเทพมห)านคร"
  6 กรุงเทพมหานคร  "(กรุงเทพมหานคร)"
  7 Abc           "(abc)defghijklm"
  8 deFgh         "abc(defgh)ijklm"
  9 aBcdefGhijKlm "(abcdefghijklm)"
} {
  do_execsql_test 1.1.$tn {
    SELECT highlight(t1, 0, '(', ')') FROM t1($s)
  } $res
}

do_execsql_test 1.2.0 {
  SELECT fts5_expr('ABCD', 'tokenize=trigram')
} {{"abc" + "bcd"}}

do_execsql_test 1.2.1 {
  SELECT * FROM t1 WHERE y LIKE ? ESCAPE 'a'
}

foreach {tn like res} {
  1 {%cDef%}   1
  2 {cDef%}    {}
  3 {%f%}      1
  4 {%f_h%}    1
  5 {%f_g%}    {}
  6 {abc%klm}  1
  7 {ABCDEFG%} 1
  8 {%รุงเ%}    2
} {
  do_execsql_test 1.3.$tn {
    SELECT rowid FROM t1 WHERE y LIKE $like
  } $res
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize="trigram case_sensitive 1");
  INSERT INTO t1 VALUES('abcdefghijklm');
  INSERT INTO t1 VALUES('กรุงเทพมหานคร');
}

foreach {tn s res} {
  1 abc           "(abc)defghijklm"
  2 defgh         "abc(defgh)ijklm"
  3 abcdefghijklm "(abcdefghijklm)"
  4 กรุ            "(กรุ)งเทพมหานคร"
  5 งเทพมห        "กรุ(งเทพมห)านคร"
  6 กรุงเทพมหานคร  "(กรุงเทพมหานคร)"
  7 Abc           ""
  8 deFgh         ""
  9 aBcdefGhijKlm ""
} {
  do_execsql_test 2.1.$tn {
    SELECT highlight(t1, 0, '(', ')') FROM t1($s)
  } $res
}
foreach {tn like res} {
  1 {%cDef%}   1
  2 {cDef%}    {}
  3 {%f%}      1
  4 {%f_h%}    1
  5 {%f_g%}    {}
  6 {abc%klm}  1
  7 {ABCDEFG%} 1
  8 {%รุงเ%}    2
} {
  do_execsql_test 2.2.$tn {
    SELECT rowid FROM t1 WHERE y LIKE $like
  } $res
}
foreach {tn like res} {
  1 {*cdef*}     1
  2 {cdef*}      {}
  3 {*f*}        1
  4 {*f?h*}      1
  5 {*f?g*}      {}
  6 {abc*klm}    1
  7 {abcdefg*}   1
  8 {*รุงเ*}      2
  9 {abc[d]efg*} 1
 10 {abc[]d]efg*} 1
 11 {abc[^]d]efg*} {}
 12 {abc[^]XYZ]efg*} 1
} {
  do_execsql_test 2.3.$tn {
    SELECT rowid FROM t1 WHERE y GLOB $like
  } $res
}

do_execsql_test 2.3.null.1 {
  SELECT rowid FROM t1 WHERE y LIKE NULL
}

#-------------------------------------------------------------------------
reset_db
do_catchsql_test 3.1 {
  CREATE VIRTUAL TABLE ttt USING fts5(c, tokenize="trigram case_sensitive 2");
} {1 {error in tokenizer constructor}}
do_catchsql_test 3.2 {
  CREATE VIRTUAL TABLE ttt USING fts5(c, tokenize="trigram case_sensitive 11");
} {1 {error in tokenizer constructor}}
do_catchsql_test 3.3 {
  CREATE VIRTUAL TABLE ttt USING fts5(c, "tokenize=trigram case_sensitive 1");
} {0 {}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE t0 USING fts5(b, tokenize = "trigram");
}
do_execsql_test 4.1 {
  INSERT INTO t0 VALUES (x'000b01');
}
do_execsql_test 4.2 {
  INSERT INTO t0(t0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
reset_db
foreach_detail_mode $::testprefix {
  foreach {ci} {0 1} {
    reset_db
    do_execsql_test 5.cs=$ci.0.1 "
      CREATE VIRTUAL TABLE t1 USING fts5(
          y, tokenize=\"trigram case_sensitive $ci\", detail=%DETAIL%
      );
    "
    do_execsql_test 5.cs=$ci.0.2 {
      INSERT INTO t1 VALUES('abcdefghijklm');
      INSERT INTO t1 VALUES('กรุงเทพมหานคร');
    }

    foreach {tn like res} {
      1 {%cDef%}   1
      2 {cDef%}    {}
      3 {%f%}      1
      4 {%f_h%}    1
      5 {%f_g%}    {}
      6 {abc%klm}  1
      7 {ABCDEFG%} 1
      8 {%รุงเ%}    2
    } {
      do_execsql_test 5.cs=$ci.1.$tn {
        SELECT rowid FROM t1 WHERE y LIKE $like
      } $res
    }
  }
}

do_execsql_test 6.0 {
  CREATE VIRTUAL TABLE ci0 USING fts5(x, tokenize="trigram");
  CREATE VIRTUAL TABLE ci1 USING fts5(x, tokenize="trigram case_sensitive 1");
}

# LIKE and GLOB both work with case-insensitive tokenizers. Only GLOB works
# with case-sensitive.
do_eqp_test 6.1 {
  SELECT * FROM ci0 WHERE x LIKE ?
} {VIRTUAL TABLE INDEX 0:L0}
do_eqp_test 6.2 {
  SELECT * FROM ci0 WHERE x GLOB ?
} {VIRTUAL TABLE INDEX 0:G0}
do_eqp_test 6.3 {
  SELECT * FROM ci1 WHERE x LIKE ?
} {{SCAN TABLE ci1 VIRTUAL TABLE INDEX 0:}}
do_eqp_test 6.4 {
  SELECT * FROM ci1 WHERE x GLOB ?
} {VIRTUAL TABLE INDEX 0:G0}

finish_test

Changes to ext/fts5/test/fts5vocab.test.

538
539
540
541
542
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557
538
539
540
541
542
543
544





545






546








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

-
do_execsql_test 10.7.2 {
  SELECT * FROM t2 WHERE term>?;
}
do_execsql_test 10.7.3 {
  SELECT * FROM t2 WHERE term=?;
}

# 2020-02-16  Detect recursively define fts5vocab() tables.
# Error found by dbsqlfuzz.
#
reset_db
do_execsql_test 11.100 {
finish_test
  CREATE VIRTUAL TABLE t3 USING fts5vocab(rowid , 'col');
  CREATE VIRTUAL TABLE rowid USING fts5vocab(rowid , 'instance');
} {}
do_catchsql_test 11.110 {
  SELECT rowid+1,rowid, * FROM t3 WHERE null>rowid ;
} {1 {SQL logic error}}

finish_test

Changes to ext/fts5/tool/fts5txt2db.tcl.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21







-







#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
proc process_cmdline {} { 
  cmdline::process ::A $::argv {
    {fts5                 "use fts5 (this is the default)"}
    {fts4                 "use fts4"}
    {trigram              "Use tokenize=trigram"}
    {colsize   "10 10 10" "list of column sizes"}
    {tblname   "t1"       "table name to create"}
    {detail    "full"     "Fts5 detail mode to use"}
    {repeat    1          "Load each file this many times"}
    {prefix    ""         "Fts prefix= option"}
    {trans     1          "True to use a transaction"}
    database
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
171
172
173
174
175
176
177

178
179
180
181
182
183
184







-








  set nCol [llength $A(colsize)]
  set cols [lrange $cols 0 [expr $nCol-1]]

  set sql    "CREATE VIRTUAL TABLE IF NOT EXISTS $A(tblname) USING $A(fts) ("
  append sql [join $cols ,]
  if {$A(fts)=="fts5"} { append sql ",detail=$A(detail)" }
  if {$A(trigram)} { append sql ",tokenize=trigram" }
  append sql ", prefix='$A(prefix)');"

  db eval $sql
  return $cols
}

# Return a list of tokens from the named file.

Changes to ext/icu/README.txt.

112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
112
113
114
115
116
117
118


119
120
121
122
123
124
125
126







-
-
+








2  COMPILATION AND USAGE

  The easiest way to compile and use the ICU extension is to build
  and use it as a dynamically loadable SQLite extension. To do this
  using gcc on *nix:

    gcc -fPIC -shared icu.c `pkg-config --libs --cflags icu-uc icu-io` \
        -o libSqliteIcu.so
    gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so

  You may need to add "-I" flags so that gcc can find sqlite3ext.h
  and sqlite3.h. The resulting shared lib, libSqliteIcu.so, may be
  loaded into sqlite in the same way as any other dynamically loadable
  extension.


Changes to ext/icu/icu.c.

139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153







-
+







    /* There are now 4 possibilities:
    **
    **     1. uPattern is an unescaped match-all character "%",
    **     2. uPattern is an unescaped match-one character "_",
    **     3. uPattern is an unescaped escape character, or
    **     4. uPattern is to be handled as an ordinary character
    */
    if( uPattern==MATCH_ALL && !prevEscape && uPattern!=(uint32_t)uEsc ){
    if( !prevEscape && uPattern==MATCH_ALL ){
      /* Case 1. */
      uint8_t c;

      /* Skip any MATCH_ALL or MATCH_ONE characters that follow a
      ** MATCH_ALL. For each MATCH_ONE, skip one character in the 
      ** test string.
      */
165
166
167
168
169
170
171
172

173
174
175
176
177

178
179
180
181
182
183
184
165
166
167
168
169
170
171

172
173
174
175
176

177
178
179
180
181
182
183
184







-
+




-
+







        if( icuLikeCompare(zPattern, zString, uEsc) ){
          return 1;
        }
        SQLITE_ICU_SKIP_UTF8(zString);
      }
      return 0;

    }else if( uPattern==MATCH_ONE && !prevEscape && uPattern!=(uint32_t)uEsc ){
    }else if( !prevEscape && uPattern==MATCH_ONE ){
      /* Case 2. */
      if( *zString==0 ) return 0;
      SQLITE_ICU_SKIP_UTF8(zString);

    }else if( uPattern==(uint32_t)uEsc && !prevEscape ){
    }else if( !prevEscape && uPattern==(uint32_t)uEsc){
      /* Case 3. */
      prevEscape = 1;

    }else{
      /* Case 4. */
      uint32_t uString;
      SQLITE_ICU_READ_UTF8(zString, uString);
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
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







-



-
+



-
+

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







  }
}

/*
** Register the ICU extension functions with database db.
*/
int sqlite3IcuInit(sqlite3 *db){
# define SQLITEICU_EXTRAFLAGS (SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS)
  static const struct IcuScalar {
    const char *zName;                        /* Function name */
    unsigned char nArg;                       /* Number of arguments */
    unsigned int enc;                         /* Optimal text encoding */
    unsigned short enc;                       /* Optimal text encoding */
    unsigned char iContext;                   /* sqlite3_user_data() context */
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
  } scalars[] = {
    {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation},
    {"icu_load_collation",  2, SQLITE_UTF8,                1, icuLoadCollation},
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
    {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS,         0, icuRegexpFunc},
    {"lower",  1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS,       0, icuCaseFunc16},
    {"lower",  2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS,       0, icuCaseFunc16},
    {"upper",  1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS,       1, icuCaseFunc16},
    {"upper",  2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS,       1, icuCaseFunc16},
    {"lower",  1, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS,        0, icuCaseFunc16},
    {"lower",  2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS,        0, icuCaseFunc16},
    {"upper",  1, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS,        1, icuCaseFunc16},
    {"upper",  2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS,        1, icuCaseFunc16},
    {"like",   2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS,        0, icuLikeFunc},
    {"like",   3, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS,        0, icuLikeFunc},
    {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC,         0, icuRegexpFunc},
    {"lower",  1, SQLITE_UTF16|SQLITE_DETERMINISTIC,       0, icuCaseFunc16},
    {"lower",  2, SQLITE_UTF16|SQLITE_DETERMINISTIC,       0, icuCaseFunc16},
    {"upper",  1, SQLITE_UTF16|SQLITE_DETERMINISTIC,       1, icuCaseFunc16},
    {"upper",  2, SQLITE_UTF16|SQLITE_DETERMINISTIC,       1, icuCaseFunc16},
    {"lower",  1, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuCaseFunc16},
    {"lower",  2, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuCaseFunc16},
    {"upper",  1, SQLITE_UTF8|SQLITE_DETERMINISTIC,        1, icuCaseFunc16},
    {"upper",  2, SQLITE_UTF8|SQLITE_DETERMINISTIC,        1, icuCaseFunc16},
    {"like",   2, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuLikeFunc},
    {"like",   3, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuLikeFunc},
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
  };
  int rc = SQLITE_OK;
  int i;
  
  for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){
    const struct IcuScalar *p = &scalars[i];

Changes to ext/icu/sqliteicu.h.

20
21
22
23
24
25
26

20
21
22
23
24
25
26
27







+
#endif  /* __cplusplus */

int sqlite3IcuInit(sqlite3 *db);

#ifdef __cplusplus
}  /* extern "C" */
#endif  /* __cplusplus */

Changes to ext/lsm1/Makefile.

39
40
41
42
43
44
45
46

47
48
49

50
51
52
53
54
55
56
39
40
41
42
43
44
45

46
47
48

49
50
51
52
53
54
55
56







-
+


-
+







             $(LSMDIR)/lsm-test/lsmtest_main.c $(LSMDIR)/lsm-test/lsmtest_mem.c \
             $(LSMDIR)/lsm-test/lsmtest_tdb.c $(LSMDIR)/lsm-test/lsmtest_tdb3.c \
             $(LSMDIR)/lsm-test/lsmtest_util.c $(LSMDIR)/lsm-test/lsmtest_win32.c


# all: lsm.so

LSMOPTS += -fPIC -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB
LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB

lsm.so:	$(LSMOBJ)
	$(TCCX) -shared -fPIC -o lsm.so $(LSMOBJ)
	$(TCCX) -shared -o lsm.so $(LSMOBJ)

%.o:	$(LSMDIR)/%.c $(LSMHDR) sqlite3.h
	$(TCCX) $(LSMOPTS) -c $<
	
lsmtest$(EXE): $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) sqlite3.o
	# $(TCPPX) -c $(TOP)/lsm-test/lsmtest_tdb2.cc
	$(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) -lz

Changes to ext/lsm1/lsm-test/lsmtest1.c.

650
651
652
653
654
655
656


650
651
652
653
654
655
656
657
658







+
+
    char *zName = getName3(zSystem, &aTest[i]);
    if( testCaseBegin(pRc, zPattern, "%s", zName) ){
      doDataTest3(zSystem, &aTest[i], pRc);
    }
    testFree(zName);
  }
}


Changes to ext/lsm1/lsm-test/lsmtest8.c.

318
319
320
321
322
323
324


318
319
320
321
322
323
324
325
326







+
+
    if( testCaseBegin(pRc, zPattern, p->zName) ){
      p->xFunc(pRc);
      testCaseFinish(*pRc);
    }
  }

}


Changes to ext/lsm1/lsm-test/lsmtest9.c.

134
135
136
137
138
139
140



134
135
136
137
138
139
140
141
142
143







+
+
+
    char *zName = getName4(zSystem, &aTest[i]);
    if( testCaseBegin(pRc, zPattern, "%s", zName) ){
      doDataTest4(zSystem, &aTest[i], pRc);
    }
    testFree(zName);
  }
}



Changes to ext/lsm1/lsm-test/lsmtest_bt.c.

65
66
67
68
69
70
71




65
66
67
68
69
70
71
72
73
74
75







+
+
+
+
    return -4;
  }

  printf("%s\n", (char*)buf.output.p);
  sqlite4_buffer_clear(&buf.output);
  return 0;
}




Changes to ext/lsm1/lsm-test/lsmtest_tdb.c.

549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
549
550
551
552
553
554
555

556
557
558
559
560
561
562
563







-
+








  /* iLevel==0 is a no-op */
  if( iLevel==0 ) return 0;

  /* If there are no transactions at all open, open a read transaction. */
  if( pDb->nOpenTrans==0 ){
    int rc = sqlite3_exec(pDb->db, 
        "BEGIN; SELECT * FROM sqlite_schema LIMIT 1;" , 0, 0, 0
        "BEGIN; SELECT * FROM sqlite_master LIMIT 1;" , 0, 0, 0
    );
    if( rc!=0 ) return rc;
    pDb->nOpenTrans = 1;
  }

  /* Open any required write transactions */
  for(i=pDb->nOpenTrans; i<iLevel; i++){

Changes to ext/lsm1/lsm-test/lsmtest_tdb2.cc.

363
364
365
366
367
368
369

363
364
365
366
367
368
369
370







+
    }
  }

  return rc;
}

#endif /* HAVE_MDB */

Changes to ext/lsm1/lsm-test/lsmtest_tdb4.c.

974
975
976
977
978
979
980


974
975
976
977
978
979
980
981
982







+
+
  }
  return rc;
}

/*
** End of background checkpointer.
*************************************************************************/


Changes to ext/lsm1/lsm_unix.c.

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
224
225
226
227
228
229
230




231
232
233
234
235
236
237







-
-
-
-







    if( iSz<iMin ){
      iSz = ((iMin + nIncrSz-1) / nIncrSz) * nIncrSz;
      prc = ftruncate(p->fd, iSz);
      if( prc!=0 ) return LSM_IOERR_BKPT;
    }

    p->pMap = mmap(0, iSz, PROT_READ|PROT_WRITE, MAP_SHARED, p->fd, 0);
    if( p->pMap==MAP_FAILED ){
      p->pMap = 0;
      return LSM_IOERR_BKPT;
    }
    p->nMap = iSz;
  }

  *ppOut = p->pMap;
  *pnOut = p->nMap;
  return LSM_OK;
}
413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430
409
410
411
412
413
414
415

416



417
418
419
420
421
422
423







-
+
-
-
-







    p->nShm = nNew;
  }

  if( p->apShm[iChunk]==0 ){
    p->apShm[iChunk] = mmap(0, LSM_SHM_CHUNK_SIZE, 
        PROT_READ|PROT_WRITE, MAP_SHARED, p->shmfd, iChunk*LSM_SHM_CHUNK_SIZE
    );
    if( p->apShm[iChunk]==MAP_FAILED ){
    if( p->apShm[iChunk]==0 ) return LSM_IOERR_BKPT;
      p->apShm[iChunk] = 0;
      return LSM_IOERR_BKPT;
    }
  }

  *ppShm = p->apShm[iChunk];
  return LSM_OK;
}

static void lsmPosixOsShmBarrier(void){

Changes to ext/lsm1/lsm_vtab.c.

838
839
840
841
842
843
844
845

846
847
848
849
850
851
852
838
839
840
841
842
843
844

845
846
847
848
849
850
851
852







-
+







  int argIdx = -1;       /* Index of the key== constraint, or -1 if none */
  int iIdx2 = -1;        /* The index of the second key */
  int omit1 = 0;
  int omit2 = 0;

  const struct sqlite3_index_constraint *pConstraint;
  pConstraint = pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
  for(i=0; i<pIdxInfo->nConstraint && idxNum<16; i++, pConstraint++){
    if( pConstraint->usable==0 ) continue;
    if( pConstraint->iColumn!=0 ) continue;
    switch( pConstraint->op ){
      case SQLITE_INDEX_CONSTRAINT_EQ: {
        if( idxNum>0 ){
          argIdx = i;
          iIdx2 = -1;

Changes to ext/lsm1/test/lsm1_simple.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
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
84
85
86
87
88
89
90



91
























































92
93







-
-
-

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


  INSERT INTO x1(a,b,c,d) VALUES(15, 11, 22, 33),(8,'banjo',x'333231',NULL),
      (12,NULL,3.25,-559281390);
  SELECT quote(a), quote(b), quote(c), quote(d), '|' FROM x1;
} {'12' NULL 3.25 -559281390 | '15' 11 22 33 | '8' 'banjo' X'333231' NULL |}
do_execsql_test 211 {
  SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1;
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |}
do_execsql_test 212 {
  SELECT quote(a), quote(lsm1_key), quote(lsm1_value) FROM x1 WHERE a='12';
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB'}

#-------------------------------------------------------------------------
reset_db
forcedelete testlsm.db
load_lsm1_vtab db
do_execsql_test 300 {
  CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b,c,d);
}
do_eqp_test 310 {
  SELECT * FROM x1 WHERE a=?
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:}

do_eqp_test 320 {
  SELECT * FROM x1 WHERE a>?
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 2:}

do_eqp_test 330 {
  SELECT * FROM x1 WHERE a<?
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 3:}
do_eqp_test 340 {
  SELECT * FROM x1 WHERE a BETWEEN ? AND ?
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 1:}

#-------------------------------------------------------------------------
reset_db
forcedelete testlsm.db
load_lsm1_vtab db
do_execsql_test 400 {
  CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b);
  INSERT INTO x1 VALUES('one', 1);
  INSERT INTO x1 VALUES('two', 2);
  INSERT INTO x1 VALUES('three', 3);
  INSERT INTO x1 VALUES('four', 4);
  INSERT INTO x1 VALUES('five', 5);
}
do_execsql_test 410 {
  SELECT b FROM x1 WHERE a = 'two'
} {2}
do_execsql_test 411 {
  SELECT b FROM x1 WHERE a = 'one'
} {1}
do_execsql_test 412 {
  SELECT b FROM x1 WHERE a = 'five'
} {5}

do_execsql_test 420 {
  SELECT b FROM x1 WHERE a BETWEEN 'one' AND 'three';
} {1 3}
do_execsql_test 421 {
  SELECT b FROM x1 WHERE a BETWEEN 'five' AND 'two';
} {5 4 1 3 2}
do_execsql_test 421 {
  SELECT b FROM x1 WHERE a > 'five';
} {4 1 3 2}
do_execsql_test 421 {
  SELECT b FROM x1 WHERE a <= 'three';
} {3 1 4 5}

finish_test

Changes to ext/misc/amatch.c.

896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
896
897
898
899
900
901
902

903
904
905
906
907
908
909







-







  if( pNew->zCostTab==0 ){
    *pzErr = sqlite3_mprintf("no edit_distances table specified");
    rc = SQLITE_ERROR;
  }else{
    rc = amatchLoadRules(db, pNew, pzErr);
  }
  if( rc==SQLITE_OK ){
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
    rc = sqlite3_declare_vtab(db,
           "CREATE TABLE x(word,distance,language,"
           "command HIDDEN,nword HIDDEN)"
         );
#define AMATCH_COL_WORD       0
#define AMATCH_COL_DISTANCE   1
#define AMATCH_COL_LANGUAGE   2

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
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
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 the offset to the first page
** file as an appended database and provides an offset to page 1.  For
** 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.
** 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:
** 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
**  (1)  An empty file is an ordinary database.
**       database.
**
**  (2)  If the file ends with the appendvfs trailer string
**       "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
**  (3)  When opening a file that ends with the appendvfs trailer string
**       "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended
**
**  (3)  If the file begins with the standard SQLite prefix string
**       "SQLite format 3", that file is an ordinary database.
**       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 1GiB. (1073741824 bytes)
** This VFS will not read or write past the 1GiB mark.  This restriction
** might be lifted in future versions.  For now, if you need a larger
** database, then keep it in a separate file.
** 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 a plain database (not an appended one), then
** this shim is a pass-through into the default underlying VFS. (rule 3)
** 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, and also the length of the prefix content.
** the offset to page 1.
*/
#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)
#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  (0x40000000)
#define APND_MAX_SIZE  (65536*15259)

/*
** Try to align the database to an even multiple of APND_ROUNDUP bytes.
*/
#ifndef APND_ROUNDUP
#define APND_ROUNDUP 4096
#endif
#define APND_ALIGN_MASK         ((sqlite3_int64)(APND_ROUNDUP-1))
#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)

/*
** 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 appendvfs file
/* An open file */
**
** An instance of this structure describes the appended database file.
** A separate sqlite3_file object is always appended. The appended
** sqlite3_file object (which can be accessed using ORIGFILE()) describes
** the entire file, including the prefix, the database, and the
** append-mark.
**
** The structure of an AppendVFS database is like this:
**
**   +-------------+---------+----------+-------------+
**   | prefix-file | padding | database | append-mark |
**   +-------------+---------+----------+-------------+
**                           ^          ^
**                           |          |
**                         iPgOne      iMark
**
**
** "prefix file" -  file onto which the database has been appended.
** "padding"     -  zero or more bytes inserted so that "database"
**                  starts on an APND_ROUNDUP boundary
** "database"    -  The SQLite database file
** "append-mark" -  The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
**                  the offset from the start of prefix-file to the start
**                  of "database".
**
** The size of the database is iMark - iPgOne.
**
** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
** of iPgOne stored as a big-ending 64-bit integer.
**
** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
** Or, iMark is -1 to indicate that it has not yet been written.
*/
struct ApndFile {
  sqlite3_file base;        /* Subclass.  MUST BE FIRST! */
  sqlite3_int64 iPgOne;     /* Offset to the start of the database */
  sqlite3_int64 iMark;      /* Offset of the append mark.  -1 if unwritten */
  sqlite3_file base;              /* IO methods */
  sqlite3_int64 iPgOne;           /* File offset to page 1 */
  sqlite3_int64 iMark;            /* Start of the append-mark */
  /* Always followed by another sqlite3_file that describes the whole file */
};

/*
** Methods for ApndFile
*/
static int apndClose(sqlite3_file*);
static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
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
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







+
+


















-
+

-
+



-
+
-
-

-
+
-
-
-
+
-
-

-
-
-

-
-
+
+
-

-
-
-
+
-
-
-











+
-
+
-
-

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






+
-
+

-
-
-
-
+
+
+
+
+
+












-


-
-
-
+
+
+
+
+
+
+
+







  apndShmMap,                     /* xShmMap */
  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;
  ApndFile *p = (ApndFile *)pFile;
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
  return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne);
}

/*
** Add the append-mark onto what should become the end of the file.
** Add the append-mark onto 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(
static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){
  ApndFile *paf,
  sqlite3_file *pFile,
  sqlite_int64 iWriteEnd
  int i;
){
  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);
  for(i=0; i<8; i++){
    a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff;
    iPgOne >>= 8;
  }
  iWriteEnd += paf->iPgOne;
  if( SQLITE_OK==(rc = pFile->pMethods->xWrite
                  (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
  return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark);
    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
){
  int rc;
  ApndFile *paf = (ApndFile *)pFile;
  ApndFile *p = (ApndFile *)pFile;
  sqlite_int64 iWriteEnd = iOfst + iAmt;
  if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
  pFile = ORIGFILE(pFile);
  if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL;
  /* 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);
  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);
    if( SQLITE_OK!=rc ) return rc;
  }
  return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
      }
    }
  }
  return rc;
}

/*
** Truncate an apnd-file.
*/
static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
  int rc;
  ApndFile *paf = (ApndFile *)pFile;
  ApndFile *p = (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);
  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.
** 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;
  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);
346
347
348
349
350
351
352
353

354
355
356
357
358
359

360
361
362
363
364
365
366
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 *paf = (ApndFile *)pFile;
  ApndFile *p = (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);
    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg);
  }
  return rc;
}

/*
** Return the sector-size in bytes for an apnd-file.
*/
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
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;
  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);
}

/*
** 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 valid append-mark, return -1;
** start of the appended database if the append-mark is present.  If
** there is no 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;
  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)) << msbs;
  for(i=1; i<8; i++){
  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56;
  for(i=1; i<8; i++){    
    msbs -= 8;
    iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
    iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i);
  }
  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 the correct end-marker, the expected odd size, and the
    ** SQLite DB type marker where the end-marker puts it, then it
    ** is an appendvfs database.
    */
    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;
  }
}

/*
** Open an apnd file handle.
*/
static int apndOpen(
  sqlite3_vfs *pApndVfs,
  sqlite3_vfs *pVfs,
  const char *zName,
  sqlite3_file *pFile,
  int flags,
  int *pOutFlags
){
  ApndFile *pApndFile = (ApndFile*)pFile;
  sqlite3_file *pBaseFile = ORIGFILE(pFile);
  sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
  ApndFile *p;
  sqlite3_file *pSubFile;
  sqlite3_vfs *pSubVfs;
  int rc;
  sqlite3_int64 sz = 0;
  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.
    ** Just use the base VFS open to initialize the given file object and
    ** open the underlying file. (Appendvfs is then unused for this file.)
    */
    return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
    return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
  }
  p = (ApndFile*)pFile;
  memset(pApndFile, 0, sizeof(ApndFile));
  pFile->pMethods = &apnd_io_methods;
  memset(p, 0, sizeof(*p));
  pSubFile = ORIGFILE(pFile);
  p->base.pMethods = &apnd_io_methods;
  pApndFile->iMark = -1;    /* Append mark not yet written */

  rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
  if( rc==SQLITE_OK ){
    rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
  rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
  if( rc ) goto apnd_open_done;
  rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
  }
  if( rc ){
    pBaseFile->pMethods->xClose(pBaseFile);
    pSubFile->pMethods->xClose(pSubFile);
    pFile->pMethods = 0;
    return rc;
    goto apnd_open_done;
  }
  if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
  if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
    /* The file being opened appears to be just an ordinary DB. Copy
    ** the base dispatch-table so this instance mimics the base VFS. 
    */
    memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
    memmove(pFile, pSubFile, pSubVfs->szOsFile);
    return SQLITE_OK;
  }
  p->iMark = 0;
  pApndFile->iPgOne = apndReadMark(sz, pFile);
  if( pApndFile->iPgOne>=0 ){
  p->iPgOne = apndReadMark(sz, pFile);
  if( p->iPgOne>0 ){
    pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
    return SQLITE_OK;
  }
  if( (flags & SQLITE_OPEN_CREATE)==0 ){
    pBaseFile->pMethods->xClose(pBaseFile);
    pSubFile->pMethods->xClose(pSubFile);
    rc = SQLITE_CANTOPEN;
    pFile->pMethods = 0;
  }else{
    /* 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, paf->iMark value indicates it is not yet written.
    */
    pApndFile->iPgOne = APND_START_ROUNDUP(sz);
  }
  p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff;
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 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);

Changes to ext/misc/blobio.c.

72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86







-
+







    sqlite3_result_error(context, "cannot open BLOB pointer", -1);
    return;
  }
  rc = sqlite3_blob_read(pBlob, aData, nData, iOfst);
  sqlite3_blob_close(pBlob);
  if( rc ){
    sqlite3_free(aData);
    sqlite3_result_error(context, "BLOB read failed", -1);
    sqlite3_result_error(context, "BLOB write failed", -1);
  }else{
    sqlite3_result_blob(context, aData, nData, sqlite3_free);
  }
}    

static void writeblobFunc(
  sqlite3_context *context,

Changes to ext/misc/btreeinfo.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
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







-
+

-
+






-
+

-
+







** The schema is like this:
**
** CREATE TABLE sqlite_btreeinfo(
**    type TEXT,                   -- "table" or "index"
**    name TEXT,                   -- Name of table or index for this btree.
**    tbl_name TEXT,               -- Associated table
**    rootpage INT,                -- The root page of the btree
**    sql TEXT,                    -- SQL for this btree - from sqlite_schema
**    sql TEXT,                    -- SQL for this btree - from sqlite_master
**    hasRowid BOOLEAN,            -- True if the btree has a rowid
**    nEntry INT,                  -- Estimated number of entries
**    nEntry INT,                  -- Estimated number of enteries
**    nPage INT,                   -- Estimated number of pages
**    depth INT,                   -- Depth of the btree
**    szPage INT,                  -- Size of each page in bytes
**    zSchema TEXT HIDDEN          -- The schema to which this btree belongs
** );
**
** The first 5 fields are taken directly from the sqlite_schema table.
** The first 5 fields are taken directly from the sqlite_master table.
** Considering only the first 5 fields, the only difference between 
** this virtual table and the sqlite_schema table is that this virtual
** this virtual table and the sqlite_master table is that this virtual
** table omits all entries that have a 0 or NULL rowid - in other words
** it omits triggers and views.
**
** The value added by this table comes in the next 5 fields.
**
** Note that nEntry and nPage are *estimated*.  They are computed doing
** a single search from the root to a leaf, counting the number of cells
84
85
86
87
88
89
90
91

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

91
92
93
94
95
96
97
98







-
+







/* Forward declarations */
typedef struct BinfoTable BinfoTable;
typedef struct BinfoCursor BinfoCursor;

/* A cursor for the sqlite_btreeinfo table */
struct BinfoCursor {
  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
  sqlite3_stmt *pStmt;            /* Query against sqlite_schema */
  sqlite3_stmt *pStmt;            /* Query against sqlite_master */
  int rc;                         /* Result of previous sqlite_step() call */
  int hasRowid;                   /* hasRowid value.  Negative if unknown. */
  sqlite3_int64 nEntry;           /* nEntry value */
  int nPage;                      /* nPage value */
  int depth;                      /* depth value */
  int szPage;                     /* size of a btree page.  0 if unknown */
  char *zSchema;                  /* Schema being interrogated */
238
239
240
241
242
243
244
245

246
247
248

249
250
251
252
253
254
255
238
239
240
241
242
243
244

245
246
247

248
249
250
251
252
253
254
255







-
+


-
+







  sqlite3_free(pCsr->zSchema);
  if( idxNum==1 && sqlite3_value_type(argv[0])!=SQLITE_NULL ){
    pCsr->zSchema = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
  }else{
    pCsr->zSchema = sqlite3_mprintf("main");
  }
  zSql = sqlite3_mprintf(
      "SELECT 0, 'table','sqlite_schema','sqlite_schema',1,NULL "
      "SELECT 0, 'table','sqlite_master','sqlite_master',1,NULL "
      "UNION ALL "
      "SELECT rowid, type, name, tbl_name, rootpage, sql"
      " FROM \"%w\".sqlite_schema WHERE rootpage>=1",
      " FROM \"%w\".sqlite_master WHERE rootpage>=1",
       pCsr->zSchema);
  sqlite3_finalize(pCsr->pStmt);
  pCsr->pStmt = 0;
  pCsr->hasRowid = -1;
  rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
  sqlite3_free(zSql);
  if( rc==SQLITE_OK ){

Changes to ext/misc/carray.c.

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







** at the address $ptr.  $ptr is a pointer to the array of integers.
** The pointer value must be assigned to $ptr using the
** sqlite3_bind_pointer() interface with a pointer type of "carray".
** For example:
**
**    static int aX[] = { 53, 9, 17, 2231, 4, 99 };
**    int i = sqlite3_bind_parameter_index(pStmt, "$ptr");
**    sqlite3_bind_pointer(pStmt, i, aX, "carray", 0);
**    sqlite3_bind_value(pStmt, i, aX, "carray", 0);
**
** There is an optional third parameter to determine the datatype of
** the C-language array.  Allowed values of the third parameter are
** 'int32', 'int64', 'double', 'char*'.  Example:
**
**      SELECT * FROM carray($ptr,10,'char*');
**
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
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







-
-
-
-
-
-
-
-



-
+

-
+
+
+
+


-
+

-
-
-
-
+
-
-
-







** the array, element by element.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>

/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
** Must exactly match the definitions in carray.h.
*/
#define CARRAY_INT32     0      /* Data is 32-bit signed integers */
#define CARRAY_INT64     1      /* Data is 64-bit signed integers */
#define CARRAY_DOUBLE    2      /* Data is doubles */
#define CARRAY_TEXT      3      /* Data is char* */

#ifndef SQLITE_OMIT_VIRTUALTABLE

/*
** Names of allowed datatypes
** Allowed datatypes
*/
static const char *azType[] = { "int32", "int64", "double", "char*" };
#define CARRAY_INT32    0
#define CARRAY_INT64    1
#define CARRAY_DOUBLE   2
#define CARRAY_TEXT     3

/*
** Structure used to hold the sqlite3_carray_bind() information
** Names of types
*/
typedef struct carray_bind carray_bind;
struct carray_bind {
  void *aData;                /* The data */
  int nData;                  /* Number of elements */
static const char *azType[] = { "int32", "int64", "double", "char*" };
  int mFlags;                 /* Control flags */
  void (*xDel)(void*);        /* Destructor for aData */
};


/* carray_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans
** over rows of the result
*/
typedef struct carray_cursor carray_cursor;
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
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







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














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







*/
static int carrayFilter(
  sqlite3_vtab_cursor *pVtabCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  carray_cursor *pCur = (carray_cursor *)pVtabCursor;
  pCur->pPtr = 0;
  pCur->iCnt = 0;
  switch( idxNum ){
  if( idxNum ){
    case 1: {
      carray_bind *pBind = sqlite3_value_pointer(argv[0], "carray-bind");
      if( pBind==0 ) break;
      pCur->pPtr = pBind->aData;
      pCur->iCnt = pBind->nData;
      pCur->eType = pBind->mFlags & 0x03;
      break;
    }
    case 2:
    case 3: {
      pCur->pPtr = sqlite3_value_pointer(argv[0], "carray");
      pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0;
      if( idxNum<3 ){
        pCur->eType = CARRAY_INT32;
      }else{
        unsigned char i;
        const char *zType = (const char*)sqlite3_value_text(argv[2]);
        for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){
          if( sqlite3_stricmp(zType, azType[i])==0 ) break;
        }
        if( i>=sizeof(azType)/sizeof(azType[0]) ){
          pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf(
            "unknown datatype: %Q", zType);
          return SQLITE_ERROR;
        }else{
          pCur->eType = i;
        }
      }
    pCur->pPtr = sqlite3_value_pointer(argv[0], "carray");
    pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0;
    if( idxNum<3 ){
      pCur->eType = CARRAY_INT32;
    }else{
      unsigned char i;
      const char *zType = (const char*)sqlite3_value_text(argv[2]);
      for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){
        if( sqlite3_stricmp(zType, azType[i])==0 ) break;
      }
      if( i>=sizeof(azType)/sizeof(azType[0]) ){
        pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf(
          "unknown datatype: %Q", zType);
        return SQLITE_ERROR;
      }else{
        pCur->eType = i;
      }
    }
      break;
    }
  }else{
    pCur->pPtr = 0;
    pCur->iCnt = 0;
  }
  pCur->iRowid = 1;
  return SQLITE_OK;
}

/*
** SQLite will invoke this method one or more times while planning a query
** that uses the carray virtual table.  This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
**
** In this implementation idxNum is used to represent the
** query plan.  idxStr is unused.
**
** idxNum is:
**
**    1    If only the pointer= constraint exists.  In this case, the
**         parameter must be bound using sqlite3_carray_bind().
**
**    2    if the pointer= and count= constraints exist.
** idxNum is 2 if the pointer= and count= constraints exist,
**
**    3    if the ctype= constraint also exists.
** 3 if the ctype= constraint also exists, and is 0 otherwise.
**
** idxNum is 0 otherwise and carray becomes an empty table.
** If idxNum is 0, then carray becomes an empty table.
*/
static int carrayBestIndex(
  sqlite3_vtab *tab,
  sqlite3_index_info *pIdxInfo
){
  int i;                 /* Loop over constraints */
  int ptrIdx = -1;       /* Index of the pointer= constraint, or -1 if none */
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
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







-
+


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







        cntIdx = i;
        break;
      case CARRAY_COLUMN_CTYPE:
        ctypeIdx = i;
        break;
    }
  }
  if( ptrIdx>=0 ){
  if( ptrIdx>=0 && cntIdx>=0 ){
    pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1;
    pIdxInfo->aConstraintUsage[ptrIdx].omit = 1;
    pIdxInfo->estimatedCost = (double)1;
    pIdxInfo->estimatedRows = 100;
    pIdxInfo->idxNum = 1;
    if( cntIdx>=0 ){
      pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2;
      pIdxInfo->aConstraintUsage[cntIdx].omit = 1;
      pIdxInfo->idxNum = 2;
      if( ctypeIdx>=0 ){
        pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3;
        pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1;
        pIdxInfo->idxNum = 3;
    pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2;
    pIdxInfo->aConstraintUsage[cntIdx].omit = 1;
    pIdxInfo->estimatedCost = (double)1;
    pIdxInfo->estimatedRows = 100;
    pIdxInfo->idxNum = 2;
    if( ctypeIdx>=0 ){
      pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3;
      pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1;
      pIdxInfo->idxNum = 3;
      }
    }
  }else{
    pIdxInfo->estimatedCost = (double)2147483647;
    pIdxInfo->estimatedRows = 2147483647;
    pIdxInfo->idxNum = 0;
  }
  return SQLITE_OK;
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
348
349
350
351
352
353
354



















































































355
356
357
358
359
360
361







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







  0,                         /* xBegin */
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
};

/*
** Destructor for the carray_bind object
*/
static void carrayBindDel(void *pPtr){
  carray_bind *p = (carray_bind*)pPtr;
  if( p->xDel!=SQLITE_STATIC ){
     p->xDel(p->aData);
  }
  sqlite3_free(p);
}

/*
** Invoke this interface in order to bind to the single-argument
** version of CARRAY().
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_carray_bind(
  sqlite3_stmt *pStmt,
  int idx,
  void *aData,
  int nData,
  int mFlags,
  void (*xDestroy)(void*)
){
  carray_bind *pNew;
  int i;
  pNew = sqlite3_malloc64(sizeof(*pNew));
  if( pNew==0 ){
    if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){
      xDestroy(aData);
    }
    return SQLITE_NOMEM;
  }
  pNew->nData = nData;
  pNew->mFlags = mFlags;
  if( xDestroy==SQLITE_TRANSIENT ){
    sqlite3_int64 sz = nData;
    switch( mFlags & 0x03 ){
      case CARRAY_INT32:   sz *= 4;              break;
      case CARRAY_INT64:   sz *= 8;              break;
      case CARRAY_DOUBLE:  sz *= 8;              break;
      case CARRAY_TEXT:    sz *= sizeof(char*);  break;
    }
    if( (mFlags & 0x03)==CARRAY_TEXT ){
      for(i=0; i<nData; i++){
        const char *z = ((char**)aData)[i];
        if( z ) sz += strlen(z) + 1;
      }
    } 
    pNew->aData = sqlite3_malloc64( sz );
    if( pNew->aData==0 ){
      sqlite3_free(pNew);
      return SQLITE_NOMEM;
    }
    if( (mFlags & 0x03)==CARRAY_TEXT ){
      char **az = (char**)pNew->aData;
      char *z = (char*)&az[nData];
      for(i=0; i<nData; i++){
        const char *zData = ((char**)aData)[i];
        sqlite3_int64 n;
        if( zData==0 ){
          az[i] = 0;
          continue;
        }
        az[i] = z;
        n = strlen(zData);
        memcpy(z, zData, n+1);
        z += n+1;
      }
    }else{
      memcpy(pNew->aData, aData, sz*nData);
    }
    pNew->xDel = sqlite3_free;
  }else{
    pNew->aData = aData;
    pNew->xDel = xDestroy;
  }
  return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel);
}


/*
** For testing purpose in the TCL test harness, we need a method for
** setting the pointer value.  The inttoptr(X) SQL function accomplishes
** this.  Tcl script will bind an integer to X and the inttoptr() SQL
** function will use sqlite3_result_pointer() to convert that integer into
** a pointer.

Deleted ext/misc/carray.h.

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























-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** Interface definitions for the CARRAY table-valued function
** extension.
*/

/* Use this interface to bind an array to the single-argument version
** of CARRAY().
*/
int sqlite3_carray_bind(
  sqlite3_stmt *pStmt,        /* Statement to be bound */
  int i,                      /* Parameter index */
  void *aData,                /* Pointer to array data */
  int nData,                  /* Number of data elements */
  int mFlags,                 /* CARRAY flags */
  void (*xDel)(void*)         /* Destructgor for aData*/
);

/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
*/
#define CARRAY_INT32     0    /* Data is 32-bit signed integers */
#define CARRAY_INT64     1    /* Data is 64-bit signed integers */
#define CARRAY_DOUBLE    2    /* Data is doubles */
#define CARRAY_TEXT      3    /* Data is char* */

Deleted ext/misc/cksumvfs.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868




































































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2020-04-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 a VFS shim that writes a checksum on each page
** of an SQLite database file.  When reading pages, the checksum is verified
** and an error is raised if the checksum is incorrect.
**
** COMPILING
**
** This extension requires SQLite 3.32.0 or later.  It uses the
** sqlite3_database_file_object() interface which was added in
** version 3.32.0, so it will not link with an earlier version of
** SQLite.
**
** To build this extension as a separately loaded shared library or
** DLL, use compiler command-lines similar to the following:
**
**   (linux)    gcc -fPIC -shared cksumvfs.c -o cksumvfs.so
**   (mac)      clang -fPIC -dynamiclib cksumvfs.c -o cksumvfs.dylib
**   (windows)  cl cksumvfs.c -link -dll -out:cksumvfs.dll
**
** You may want to add additional compiler options, of course,
** according to the needs of your project.
**
** If you want to statically link this extension with your product,
** then compile it like any other C-language module but add the
** "-DSQLITE_CKSUMVFS_STATIC" option so that this module knows that
** it is being statically linked rather than dynamically linked
**
** LOADING
**
** To load this extension as a shared library, you first have to
** bring up a dummy SQLite database connection to use as the argument
** to the sqlite3_load_extension() API call.  Then you invoke the
** sqlite3_load_extension() API and shutdown the dummy database
** connection.  All subsequent database connections that are opened
** will include this extension.  For example:
**
**     sqlite3 *db;
**     sqlite3_open(":memory:", &db);
**     sqlite3_load_extention(db, "./cksumvfs");
**     sqlite3_close(db);
**
** If this extension is compiled with -DSQLITE_CKSUMVFS_STATIC and
** statically linked against the application, initialize it using
** a single API call as follows:
**
**     sqlite3_register_cksumvfs();
**
** Cksumvfs is a VFS Shim. When loaded, "cksmvfs" becomes the new
** default VFS and it uses the prior default VFS as the next VFS
** down in the stack.  This is normally what you want.  However, in
** complex situations where multiple VFS shims are being loaded,
** it might be important to ensure that cksumvfs is loaded in the
** correct order so that it sequences itself into the default VFS
** Shim stack in the right order.
**
** USING
**
** Open database connections using the sqlite3_open() or 
** sqlite3_open_v2() interfaces, as normal.  Ordinary database files
** (without a checksum) will operate normally.  Databases with 
** checksums will return an SQLITE_IOERR_DATA error if a page is
** encountered that contains an invalid checksum.
**
** Checksumming only works on databases that have a reserve-bytes
** value of exactly 8.  The default value for reserve-bytes is 0.
** Hence, newly created database files will omit the checksum by
** default.  To create a database that includes a checksum, change
** the reserve-bytes value to 8 by runing:
**
**    int n = 8;
**    sqlite3_file_control(db, 0, SQLITE_FCNTL_RESERVE_BYTES, &n);
**
** If you do this immediately after creating a new database file,
** before anything else has been written into the file, then that
** might be all that you need to do.  Otherwise, the API call
** above should be followed by:
**
**    sqlite3_exec(db, "VACUUM", 0, 0, 0);
**
** It never hurts to run the VACUUM, even if you don't need it.
** If the database is in WAL mode, you should shutdown and
** reopen all database connections before continuing.
**
** From the CLI, use the ".filectrl reserve_bytes 8" command, 
** followed by "VACUUM;".
**
** Note that SQLite allows the number of reserve-bytes to be
** increased but not decreased.  So if a database file already
** has a reserve-bytes value greater than 8, there is no way to
** activate checksumming on that database, other than to dump
** and restore the database file.  Note also that other extensions
** might also make use of the reserve-bytes.  Checksumming will
** be incompatible with those other extensions.
**
** VERIFICATION OF CHECKSUMS
**
** If any checksum is incorrect, the "PRAGMA quick_check" command
** will find it.  To verify that checksums are actually enabled
** and running, use the following query:
**
**   SELECT count(*), verify_checksum(data)
**     FROM sqlite_dbpage
**    GROUP BY 2;
**
** There are three possible outputs form the verify_checksum()
** function: 1, 0, and NULL.  1 is returned if the checksum is
** correct.  0 is returned if the checksum is incorrect.  NULL
** is returned if the page is unreadable.  If checksumming is
** enabled, the read will fail if the checksum is wrong, so the
** usual result from verify_checksum() on a bad checksum is NULL.
**
** If everything is OK, the query above should return a single
** row where the second column is 1.  Any other result indicates
** either that there is a checksum error, or checksum validation
** is disabled.
**
** CONTROLLING CHECKSUM VERIFICATION
**
** The cksumvfs extension implements a new PRAGMA statement that can
** be used to disable, re-enable, or query the status of checksum
** verification:
**
**    PRAGMA checksum_verification;          -- query status
**    PRAGMA checksum_verification=OFF;      -- disable verification
**    PRAGMA checksum_verification=ON;       -- re-enable verification
**
** The "checksum_verification" pragma will return "1" (true) or "0"
** (false) if checksum verification is enabled or disabled, respectively.
** "Verification" in this context means the feature that causes
** SQLITE_IOERR_DATA errors if a checksum mismatch is detected while
** reading.  Checksums are always kept up-to-date as long as the
** reserve-bytes value of the database is 8, regardless of the setting
** of this pragma.  Checksum verification can be disabled (for example)
** to do forensic analysis of a database that has previously reported
** a checksum error.
**
** The "checksum_verification" pragma will always respond with "0" if
** the database file does not have a reserve-bytes value of 8.  The
** pragma will return no rows at all if the cksumvfs extension is
** not loaded.
**
** IMPLEMENTATION NOTES
**
** The checksum is stored in the last 8 bytes of each page.  This
** module only operates if the "bytes of reserved space on each page"
** value at offset 20 the SQLite database header is exactly 8.  If
** the reserved-space value is not 8, this module is a no-op.
*/
#if defined(SQLITE_AMALGAMATION) && !defined(SQLITE_CKSUMVFS_STATIC)
# define SQLITE_CKSUMVFS_STATIC
#endif
#ifdef SQLITE_CKSUMVFS_STATIC
# include "sqlite3.h"
#else
# include "sqlite3ext.h"
  SQLITE_EXTENSION_INIT1
#endif
#include <string.h>
#include <assert.h>


/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs CksmVfs;
typedef struct CksmFile CksmFile;

/*
** Useful datatype abbreviations
*/
#if !defined(SQLITE_AMALGAMATION)
  typedef unsigned char u8;
  typedef unsigned int u32;
#endif

/* 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*)(((CksmFile*)(p))+1))

/* An open file */
struct CksmFile {
  sqlite3_file base;    /* IO methods */
  const char *zFName;   /* Original name of the file */
  char computeCksm;     /* True to compute checksums.
                        ** Always true if reserve size is 8. */
  char verifyCksm;      /* True to verify checksums */
  char isWal;           /* True if processing a WAL file */
  char inCkpt;          /* Currently doing a checkpoint */
  CksmFile *pPartner;   /* Ptr from WAL to main-db, or from main-db to WAL */
};

/*
** Methods for CksmFile
*/
static int cksmClose(sqlite3_file*);
static int cksmRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
static int cksmWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
static int cksmTruncate(sqlite3_file*, sqlite3_int64 size);
static int cksmSync(sqlite3_file*, int flags);
static int cksmFileSize(sqlite3_file*, sqlite3_int64 *pSize);
static int cksmLock(sqlite3_file*, int);
static int cksmUnlock(sqlite3_file*, int);
static int cksmCheckReservedLock(sqlite3_file*, int *pResOut);
static int cksmFileControl(sqlite3_file*, int op, void *pArg);
static int cksmSectorSize(sqlite3_file*);
static int cksmDeviceCharacteristics(sqlite3_file*);
static int cksmShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
static int cksmShmLock(sqlite3_file*, int offset, int n, int flags);
static void cksmShmBarrier(sqlite3_file*);
static int cksmShmUnmap(sqlite3_file*, int deleteFlag);
static int cksmFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
static int cksmUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);

/*
** Methods for CksmVfs
*/
static int cksmOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
static int cksmDelete(sqlite3_vfs*, const char *zName, int syncDir);
static int cksmAccess(sqlite3_vfs*, const char *zName, int flags, int *);
static int cksmFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
static void *cksmDlOpen(sqlite3_vfs*, const char *zFilename);
static void cksmDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
static void (*cksmDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
static void cksmDlClose(sqlite3_vfs*, void*);
static int cksmRandomness(sqlite3_vfs*, int nByte, char *zOut);
static int cksmSleep(sqlite3_vfs*, int microseconds);
static int cksmCurrentTime(sqlite3_vfs*, double*);
static int cksmGetLastError(sqlite3_vfs*, int, char *);
static int cksmCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
static int cksmSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
static sqlite3_syscall_ptr cksmGetSystemCall(sqlite3_vfs*, const char *z);
static const char *cksmNextSystemCall(sqlite3_vfs*, const char *zName);

static sqlite3_vfs cksm_vfs = {
  3,                            /* iVersion (set when registered) */
  0,                            /* szOsFile (set when registered) */
  1024,                         /* mxPathname */
  0,                            /* pNext */
  "cksmvfs",                    /* zName */
  0,                            /* pAppData (set when registered) */ 
  cksmOpen,                     /* xOpen */
  cksmDelete,                   /* xDelete */
  cksmAccess,                   /* xAccess */
  cksmFullPathname,             /* xFullPathname */
  cksmDlOpen,                   /* xDlOpen */
  cksmDlError,                  /* xDlError */
  cksmDlSym,                    /* xDlSym */
  cksmDlClose,                  /* xDlClose */
  cksmRandomness,               /* xRandomness */
  cksmSleep,                    /* xSleep */
  cksmCurrentTime,              /* xCurrentTime */
  cksmGetLastError,             /* xGetLastError */
  cksmCurrentTimeInt64,         /* xCurrentTimeInt64 */
  cksmSetSystemCall,            /* xSetSystemCall */
  cksmGetSystemCall,            /* xGetSystemCall */
  cksmNextSystemCall            /* xNextSystemCall */
};

static const sqlite3_io_methods cksm_io_methods = {
  3,                              /* iVersion */
  cksmClose,                      /* xClose */
  cksmRead,                       /* xRead */
  cksmWrite,                      /* xWrite */
  cksmTruncate,                   /* xTruncate */
  cksmSync,                       /* xSync */
  cksmFileSize,                   /* xFileSize */
  cksmLock,                       /* xLock */
  cksmUnlock,                     /* xUnlock */
  cksmCheckReservedLock,          /* xCheckReservedLock */
  cksmFileControl,                /* xFileControl */
  cksmSectorSize,                 /* xSectorSize */
  cksmDeviceCharacteristics,      /* xDeviceCharacteristics */
  cksmShmMap,                     /* xShmMap */
  cksmShmLock,                    /* xShmLock */
  cksmShmBarrier,                 /* xShmBarrier */
  cksmShmUnmap,                   /* xShmUnmap */
  cksmFetch,                      /* xFetch */
  cksmUnfetch                     /* xUnfetch */
};

/* Do byte swapping on a unsigned 32-bit integer */
#define BYTESWAP32(x) ( \
    (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8)  \
  + (((x)&0x00FF0000)>>8)  + (((x)&0xFF000000)>>24) \
)

/* Compute a checksum on a buffer */
static void cksmCompute(
  u8 *a,           /* Content to be checksummed */
  int nByte,       /* Bytes of content in a[].  Must be a multiple of 8. */
  u8 *aOut         /* OUT: Final 8-byte checksum value output */
){
  u32 s1 = 0, s2 = 0;
  u32 *aData = (u32*)a;
  u32 *aEnd = (u32*)&a[nByte];
  u32 x = 1;

  assert( nByte>=8 );
  assert( (nByte&0x00000007)==0 );
  assert( nByte<=65536 );

  if( 1 == *(u8*)&x ){
    /* Little-endian */
    do {
      s1 += *aData++ + s2;
      s2 += *aData++ + s1;
    }while( aData<aEnd );
  }else{
    /* Big-endian */
    do {
      s1 += BYTESWAP32(aData[0]) + s2;
      s2 += BYTESWAP32(aData[1]) + s1;
      aData += 2;
    }while( aData<aEnd );
    s1 = BYTESWAP32(s1);
    s2 = BYTESWAP32(s2);
  }
  memcpy(aOut, &s1, 4);
  memcpy(aOut+4, &s2, 4);
}

/*
** SQL function:    verify_checksum(BLOB)
**
** Return 0 or 1 if the checksum is invalid or valid.  Or return
** NULL if the input is not a BLOB that is the right size for a
** database page.
*/
static void cksmVerifyFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int nByte;
  u8 *data;
  u8 cksum[8];
  data = (u8*)sqlite3_value_blob(argv[0]);
  if( data==0 ) return;
  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 );
    p->pPartner->pPartner = 0;
    p->pPartner = 0;
  }
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xClose(pFile);
}

/*
** Set the computeCkSm and verifyCksm flags, if they need to be
** changed.
*/
static void cksmSetFlags(CksmFile *p, int hasCorrectReserveSize){
  if( hasCorrectReserveSize!=p->computeCksm ){
    p->computeCksm = p->verifyCksm = hasCorrectReserveSize;
    if( p->pPartner ){
      p->pPartner->verifyCksm = hasCorrectReserveSize;
      p->pPartner->computeCksm = hasCorrectReserveSize;
    }
  }
}

/*
** Read data from a cksm-file.
*/
static int cksmRead(
  sqlite3_file *pFile, 
  void *zBuf, 
  int iAmt, 
  sqlite_int64 iOfst
){
  int rc;
  CksmFile *p = (CksmFile *)pFile;
  pFile = ORIGFILE(pFile);
  rc = pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst);
  if( rc==SQLITE_OK ){
    if( iOfst==0 && iAmt>=100 && (
          memcmp(zBuf,"SQLite format 3",16)==0 || memcmp(zBuf,"ZV-",3)==0 
    )){
      u8 *d = (u8*)zBuf;
      char hasCorrectReserveSize = (d[20]==8);
      cksmSetFlags(p, hasCorrectReserveSize);
    }
    /* Verify the checksum if
    **    (1) the size indicates that we are dealing with a complete
    **        database page
    **    (2) checksum verification is enabled
    **    (3) we are not in the middle of checkpoint
    */
    if( iAmt>=512           /* (1) */
     && p->verifyCksm       /* (2) */
     && !p->inCkpt          /* (3) */
    ){
      u8 cksum[8];
      cksmCompute((u8*)zBuf, iAmt-8, cksum);
      if( memcmp((u8*)zBuf+iAmt-8, cksum, 8)!=0 ){
        sqlite3_log(SQLITE_IOERR_DATA,
           "checksum fault offset %lld of \"%s\"",
           iOfst, p->zFName);
        rc = SQLITE_IOERR_DATA;
      }
    }
  }
  return rc;
}

/*
** Write data to a cksm-file.
*/
static int cksmWrite(
  sqlite3_file *pFile,
  const void *zBuf,
  int iAmt,
  sqlite_int64 iOfst
){
  CksmFile *p = (CksmFile *)pFile;
  pFile = ORIGFILE(pFile);
  if( iOfst==0 && iAmt>=100 && (
        memcmp(zBuf,"SQLite format 3",16)==0 || memcmp(zBuf,"ZV-",3)==0 
  )){
    u8 *d = (u8*)zBuf;
    char hasCorrectReserveSize = (d[20]==8);
    cksmSetFlags(p, hasCorrectReserveSize);
  }
  /* If the write size is appropriate for a database page and if
  ** checksums where ever enabled, then it will be safe to compute
  ** the checksums.  The reserve byte size might have increased, but
  ** it will never decrease.  And because it cannot decrease, the
  ** checksum will not overwrite anything.
  */
  if( iAmt>=512
   && p->computeCksm
   && !p->inCkpt
  ){
    cksmCompute((u8*)zBuf, iAmt-8, ((u8*)zBuf)+iAmt-8);
  }
  return pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst);
}

/*
** Truncate a cksm-file.
*/
static int cksmTruncate(sqlite3_file *pFile, sqlite_int64 size){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xTruncate(pFile, size);
}

/*
** Sync a cksm-file.
*/
static int cksmSync(sqlite3_file *pFile, int flags){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xSync(pFile, flags);
}

/*
** Return the current file-size of a cksm-file.
*/
static int cksmFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
  CksmFile *p = (CksmFile *)pFile;
  pFile = ORIGFILE(p);
  return pFile->pMethods->xFileSize(pFile, pSize);
}

/*
** Lock a cksm-file.
*/
static int cksmLock(sqlite3_file *pFile, int eLock){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xLock(pFile, eLock);
}

/*
** Unlock a cksm-file.
*/
static int cksmUnlock(sqlite3_file *pFile, int eLock){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xUnlock(pFile, eLock);
}

/*
** Check if another file-handle holds a RESERVED lock on a cksm-file.
*/
static int cksmCheckReservedLock(sqlite3_file *pFile, int *pResOut){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
}

/*
** File control method. For custom operations on a cksm-file.
*/
static int cksmFileControl(sqlite3_file *pFile, int op, void *pArg){
  int rc;
  CksmFile *p = (CksmFile*)pFile;
  pFile = ORIGFILE(pFile);
  if( op==SQLITE_FCNTL_PRAGMA ){
    char **azArg = (char**)pArg;
    assert( azArg[1]!=0 );
    if( sqlite3_stricmp(azArg[1],"checksum_verification")==0 ){
      char *zArg = azArg[2];
      if( zArg!=0 ){
        if( (zArg[0]>='1' && zArg[0]<='9')
         || sqlite3_strlike("enable%",zArg,0)==0
         || sqlite3_stricmp("yes",zArg)==0
         || sqlite3_stricmp("on",zArg)==0
        ){
          p->verifyCksm = p->computeCksm;
        }else{
          p->verifyCksm = 0;
        }
        if( p->pPartner ) p->pPartner->verifyCksm = p->verifyCksm;
      }
      azArg[0] = sqlite3_mprintf("%d",p->verifyCksm);
      return SQLITE_OK;
    }else if( p->computeCksm && azArg[2]!=0
           && sqlite3_stricmp(azArg[1], "page_size")==0 ){
      /* Do not allow page size changes on a checksum database */
      return SQLITE_OK;
    }
  }else if( op==SQLITE_FCNTL_CKPT_START || op==SQLITE_FCNTL_CKPT_DONE ){
    p->inCkpt = op==SQLITE_FCNTL_CKPT_START;
    if( p->pPartner ) p->pPartner->inCkpt = p->inCkpt;
  }
  rc = pFile->pMethods->xFileControl(pFile, op, pArg);
  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
    *(char**)pArg = sqlite3_mprintf("cksm/%z", *(char**)pArg);
  }
  return rc;
}

/*
** Return the sector-size in bytes for a cksm-file.
*/
static int cksmSectorSize(sqlite3_file *pFile){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xSectorSize(pFile);
}

/*
** Return the device characteristic flags supported by a cksm-file.
*/
static int cksmDeviceCharacteristics(sqlite3_file *pFile){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xDeviceCharacteristics(pFile);
}

/* Create a shared memory file mapping */
static int cksmShmMap(
  sqlite3_file *pFile,
  int iPg,
  int pgsz,
  int bExtend,
  void volatile **pp
){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
}

/* Perform locking on a shared-memory segment */
static int cksmShmLock(sqlite3_file *pFile, int offset, int n, int flags){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xShmLock(pFile,offset,n,flags);
}

/* Memory barrier operation on shared memory */
static void cksmShmBarrier(sqlite3_file *pFile){
  pFile = ORIGFILE(pFile);
  pFile->pMethods->xShmBarrier(pFile);
}

/* Unmap a shared memory segment */
static int cksmShmUnmap(sqlite3_file *pFile, int deleteFlag){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
}

/* Fetch a page of a memory-mapped file */
static int cksmFetch(
  sqlite3_file *pFile,
  sqlite3_int64 iOfst,
  int iAmt,
  void **pp
){
  CksmFile *p = (CksmFile *)pFile;
  if( p->computeCksm ){
    *pp = 0;
    return SQLITE_OK;
  }
  pFile = ORIGFILE(pFile);
  if( pFile->pMethods->iVersion>2 && pFile->pMethods->xFetch ){
    return pFile->pMethods->xFetch(pFile, iOfst, iAmt, pp);
  }
  *pp = 0;
  return SQLITE_OK;
}

/* Release a memory-mapped page */
static int cksmUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
  pFile = ORIGFILE(pFile);
  if( pFile->pMethods->iVersion>2 && pFile->pMethods->xUnfetch ){
    return pFile->pMethods->xUnfetch(pFile, iOfst, pPage);
  }
  return SQLITE_OK;
}

/*
** Open a cksm file handle.
*/
static int cksmOpen(
  sqlite3_vfs *pVfs,
  const char *zName,
  sqlite3_file *pFile,
  int flags,
  int *pOutFlags
){
  CksmFile *p;
  sqlite3_file *pSubFile;
  sqlite3_vfs *pSubVfs;
  int rc;
  pSubVfs = ORIGVFS(pVfs);
  if( (flags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_WAL))==0 ){
    return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
  }
  p = (CksmFile*)pFile;
  memset(p, 0, sizeof(*p));
  pSubFile = ORIGFILE(pFile);
  pFile->pMethods = &cksm_io_methods;
  rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
  if( rc ) goto cksm_open_done;
  if( flags & SQLITE_OPEN_WAL ){
    sqlite3_file *pDb = sqlite3_database_file_object(zName);
    p->pPartner = (CksmFile*)pDb;
    assert( p->pPartner->pPartner==0 );
    p->pPartner->pPartner = p;
    p->isWal = 1;
    p->computeCksm = p->pPartner->computeCksm;
  }else{
    p->isWal = 0;
    p->computeCksm = 0;
  }
  p->zFName = zName;
cksm_open_done:
  if( rc ) pFile->pMethods = 0;
  return rc;
}

/*
** All other VFS methods are pass-thrus.
*/
static int cksmDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
}
static int cksmAccess(
  sqlite3_vfs *pVfs, 
  const char *zPath, 
  int flags, 
  int *pResOut
){
  return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
}
static int cksmFullPathname(
  sqlite3_vfs *pVfs, 
  const char *zPath, 
  int nOut, 
  char *zOut
){
  return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
}
static void *cksmDlOpen(sqlite3_vfs *pVfs, const char *zPath){
  return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
}
static void cksmDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
  ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
}
static void (*cksmDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
  return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
}
static void cksmDlClose(sqlite3_vfs *pVfs, void *pHandle){
  ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
}
static int cksmRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
  return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
}
static int cksmSleep(sqlite3_vfs *pVfs, int nMicro){
  return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
}
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);
}
static sqlite3_syscall_ptr cksmGetSystemCall(
  sqlite3_vfs *pVfs,
  const char *zName
){
  return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
}
static const char *cksmNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
  return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
}

/* Register the verify_checksum() SQL function.
*/
static int cksmRegisterFunc(
  sqlite3 *db, 
  char **pzErrMsg, 
  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.
*/
static int cksmRegisterVfs(void){
  int rc = SQLITE_OK;
  sqlite3_vfs *pOrig;
  if( sqlite3_vfs_find("cksmvfs")!=0 ) return SQLITE_OK;
  pOrig = sqlite3_vfs_find(0);
  cksm_vfs.iVersion = pOrig->iVersion;
  cksm_vfs.pAppData = pOrig;
  cksm_vfs.szOsFile = pOrig->szOsFile + sizeof(CksmFile);
  rc = sqlite3_vfs_register(&cksm_vfs, 1);
  if( rc==SQLITE_OK ){
    rc = sqlite3_auto_extension((void(*)(void))cksmRegisterFunc);
  }
  return rc;
}

#if defined(SQLITE_CKSUMVFS_STATIC)
/* This variant of the initializer runs when the extension is
** statically linked.
*/
int sqlite3_register_cksumvfs(const char *NotUsed){
  (void)NotUsed;
  return cksmRegisterVfs();
}
int sqlite3_unregister_cksumvfs(void){
  if( sqlite3_vfs_find("cksmvfs") ){
    sqlite3_vfs_unregister(&cksm_vfs);
    sqlite3_cancel_auto_extension((void(*)(void))cksmRegisterFunc);
  }
  return SQLITE_OK;
}
#endif /* defined(SQLITE_CKSUMVFS_STATIC */

#if !defined(SQLITE_CKSUMVFS_STATIC)
/* This variant of the initializer function is used when the
** extension is shared library to be loaded at run-time.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
/* 
** This routine is called by sqlite3_load_extension() when the
** extension is first loaded.
***/
int sqlite3_cksumvfs_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg; /* not used */
  rc = cksmRegisterFunc(db, 0, 0);
  if( rc==SQLITE_OK ){
    
  }
  if( rc==SQLITE_OK ){
    rc = cksmRegisterVfs();
  }
  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
  return rc;
}
#endif /* !defined(SQLITE_CKSUMVFS_STATIC) */

Changes to ext/misc/completion.c.

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
114
115
116
117
118
119
120

121
122
123
124
125
126
127







-








/* Column numbers */
#define COMPLETION_COLUMN_CANDIDATE 0  /* Suggested completion of the input */
#define COMPLETION_COLUMN_PREFIX    1  /* Prefix of the word to be completed */
#define COMPLETION_COLUMN_WHOLELINE 2  /* Entire line seen so far */
#define COMPLETION_COLUMN_PHASE     3  /* ePhase - used for debugging only */

  sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  rc = sqlite3_declare_vtab(db,
      "CREATE TABLE x("
      "  candidate TEXT,"
      "  prefix TEXT HIDDEN,"
      "  wholeline TEXT HIDDEN,"
      "  phase INT HIDDEN"        /* Used for debugging only */
      ")");
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235







-
+







          char *zSql = 0;
          const char *zSep = "";
          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
          while( sqlite3_step(pS2)==SQLITE_ROW ){
            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
            zSql = sqlite3_mprintf(
               "%z%s"
               "SELECT name FROM \"%w\".sqlite_schema",
               "SELECT name FROM \"%w\".sqlite_master",
               zSql, zSep, zDb
            );
            if( zSql==0 ) return SQLITE_NOMEM;
            zSep = " UNION ";
          }
          sqlite3_finalize(pS2);
          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259







-
+







          char *zSql = 0;
          const char *zSep = "";
          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
          while( sqlite3_step(pS2)==SQLITE_ROW ){
            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
            zSql = sqlite3_mprintf(
               "%z%s"
               "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
               "SELECT pti.name FROM \"%w\".sqlite_master AS sm"
                       " JOIN pragma_table_info(sm.name,%Q) AS pti"
               " WHERE sm.type='table'",
               zSql, zSep, zDb, zDb
            );
            if( zSql==0 ) return SQLITE_NOMEM;
            zSep = " UNION ";
          }

Changes to ext/misc/compress.c.

115
116
117
118
119
120
121
122

123
124

125
126

127
128

129
130
131
115
116
117
118
119
120
121

122


123
124

125


126
127
128
129







-
+
-
-
+

-
+
-
-
+



  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "compress", 1, 
  rc = sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0,
                    SQLITE_UTF8 | SQLITE_INNOCUOUS,
                    0, compressFunc, 0, 0);
                               compressFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "uncompress", 1,
    rc = sqlite3_create_function(db, "uncompress", 1, SQLITE_UTF8, 0,
                    SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
                    0, uncompressFunc, 0, 0);
                                 uncompressFunc, 0, 0);
  }
  return rc;
}

Changes to ext/misc/csv.c.

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
628
629
630
631
632
633
634









635
636
637
638
639
640
641







-
-
-
-
-
-
-
-
-







  if( rc ){
    csv_errmsg(&sRdr, "bad schema: '%s' - %s", CSV_SCHEMA, sqlite3_errmsg(db));
    goto csvtab_connect_error;
  }
  for(i=0; i<sizeof(azPValue)/sizeof(azPValue[0]); i++){
    sqlite3_free(azPValue[i]);
  }
  /* Rationale for DIRECTONLY:
  ** An attacker who controls a database schema could use this vtab
  ** to exfiltrate sensitive data from other files in the filesystem.
  ** And, recommended practice is to put all CSV virtual tables in the
  ** TEMP namespace, so they should still be usable from within TEMP
  ** views, so there shouldn't be a serious loss of functionality by
  ** prohibiting the use of this vtab from persistent triggers and views.
  */
  sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
  return SQLITE_OK;

csvtab_connect_oom:
  rc = SQLITE_NOMEM;
  csv_errmsg(&sRdr, "out of memory");

csvtab_connect_error:
772
773
774
775
776
777
778
779

780
781
782
783
784
785
786
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777







-
+







  sqlite3_vtab_cursor *cur,   /* The cursor */
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
  int i                       /* Which column to return */
){
  CsvCursor *pCur = (CsvCursor*)cur;
  CsvTable *pTab = (CsvTable*)cur->pVtab;
  if( i>=0 && i<pTab->nCol && pCur->azVal[i]!=0 ){
    sqlite3_result_text(ctx, pCur->azVal[i], -1, SQLITE_TRANSIENT);
    sqlite3_result_text(ctx, pCur->azVal[i], -1, SQLITE_STATIC);
  }
  return SQLITE_OK;
}

/*
** Return the rowid for the current row.
*/

Deleted ext/misc/dbdata.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851



















































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2019-04-17
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains an implementation of two eponymous virtual tables,
** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
** "sqlite_dbpage" eponymous virtual table be available.
**
** SQLITE_DBDATA:
**   sqlite_dbdata is used to extract data directly from a database b-tree
**   page and its associated overflow pages, bypassing the b-tree layer.
**   The table schema is equivalent to:
**
**     CREATE TABLE sqlite_dbdata(
**       pgno INTEGER,
**       cell INTEGER,
**       field INTEGER,
**       value ANY,
**       schema TEXT HIDDEN
**     );
**
**   IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
**   FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
**   "schema".
**
**   Each page of the database is inspected. If it cannot be interpreted as
**   a b-tree page, or if it is a b-tree page containing 0 entries, the
**   sqlite_dbdata table contains no rows for that page.  Otherwise, the
**   table contains one row for each field in the record associated with
**   each cell on the page. For intkey b-trees, the key value is stored in
**   field -1.
**
**   For example, for the database:
**
**     CREATE TABLE t1(a, b);     -- root page is page 2
**     INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
**     INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
**
**   the sqlite_dbdata table contains, as well as from entries related to 
**   page 1, content equivalent to:
**
**     INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
**         (2, 0, -1, 5     ),
**         (2, 0,  0, 'v'   ),
**         (2, 0,  1, 'five'),
**         (2, 1, -1, 10    ),
**         (2, 1,  0, 'x'   ),
**         (2, 1,  1, 'ten' );
**
**   If database corruption is encountered, this module does not report an
**   error. Instead, it attempts to extract as much data as possible and
**   ignores the corruption.
**
** SQLITE_DBPTR:
**   The sqlite_dbptr table has the following schema:
**
**     CREATE TABLE sqlite_dbptr(
**       pgno INTEGER,
**       child INTEGER,
**       schema TEXT HIDDEN
**     );
**
**   It contains one entry for each b-tree pointer between a parent and
**   child page in the database.
*/
#if !defined(SQLITEINT_H) 
#include "sqlite3ext.h"

typedef unsigned char u8;

#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>

#define DBDATA_PADDING_BYTES 100 

typedef struct DbdataTable DbdataTable;
typedef struct DbdataCursor DbdataCursor;

/* Cursor object */
struct DbdataCursor {
  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
  sqlite3_stmt *pStmt;            /* For fetching database pages */

  int iPgno;                      /* Current page number */
  u8 *aPage;                      /* Buffer containing page */
  int nPage;                      /* Size of aPage[] in bytes */
  int nCell;                      /* Number of cells on aPage[] */
  int iCell;                      /* Current cell number */
  int bOnePage;                   /* True to stop after one page */
  int szDb;
  sqlite3_int64 iRowid;

  /* Only for the sqlite_dbdata table */
  u8 *pRec;                       /* Buffer containing current record */
  int nRec;                       /* Size of pRec[] in bytes */
  int nHdr;                       /* Size of header in bytes */
  int iField;                     /* Current field number */
  u8 *pHdrPtr;
  u8 *pPtr;
  
  sqlite3_int64 iIntkey;          /* Integer key value */
};

/* Table object */
struct DbdataTable {
  sqlite3_vtab base;              /* Base class.  Must be first */
  sqlite3 *db;                    /* The database connection */
  sqlite3_stmt *pStmt;            /* For fetching database pages */
  int bPtr;                       /* True for sqlite3_dbptr table */
};

/* Column and schema definitions for sqlite_dbdata */
#define DBDATA_COLUMN_PGNO        0
#define DBDATA_COLUMN_CELL        1
#define DBDATA_COLUMN_FIELD       2
#define DBDATA_COLUMN_VALUE       3
#define DBDATA_COLUMN_SCHEMA      4
#define DBDATA_SCHEMA             \
      "CREATE TABLE x("           \
      "  pgno INTEGER,"           \
      "  cell INTEGER,"           \
      "  field INTEGER,"          \
      "  value ANY,"              \
      "  schema TEXT HIDDEN"      \
      ")"

/* Column and schema definitions for sqlite_dbptr */
#define DBPTR_COLUMN_PGNO         0
#define DBPTR_COLUMN_CHILD        1
#define DBPTR_COLUMN_SCHEMA       2
#define DBPTR_SCHEMA              \
      "CREATE TABLE x("           \
      "  pgno INTEGER,"           \
      "  child INTEGER,"          \
      "  schema TEXT HIDDEN"      \
      ")"

/*
** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual 
** table.
*/
static int dbdataConnect(
  sqlite3 *db,
  void *pAux,
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErr
){
  DbdataTable *pTab = 0;
  int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);

  if( rc==SQLITE_OK ){
    pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
    if( pTab==0 ){
      rc = SQLITE_NOMEM;
    }else{
      memset(pTab, 0, sizeof(DbdataTable));
      pTab->db = db;
      pTab->bPtr = (pAux!=0);
    }
  }

  *ppVtab = (sqlite3_vtab*)pTab;
  return rc;
}

/*
** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
*/
static int dbdataDisconnect(sqlite3_vtab *pVtab){
  DbdataTable *pTab = (DbdataTable*)pVtab;
  if( pTab ){
    sqlite3_finalize(pTab->pStmt);
    sqlite3_free(pVtab);
  }
  return SQLITE_OK;
}

/*
** This function interprets two types of constraints:
**
**       schema=?
**       pgno=?
**
** If neither are present, idxNum is set to 0. If schema=? is present,
** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
** in idxNum is set.
**
** If both parameters are present, schema is in position 0 and pgno in
** position 1.
*/
static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
  DbdataTable *pTab = (DbdataTable*)tab;
  int i;
  int iSchema = -1;
  int iPgno = -1;
  int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);

  for(i=0; i<pIdx->nConstraint; i++){
    struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
    if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
      if( p->iColumn==colSchema ){
        if( p->usable==0 ) return SQLITE_CONSTRAINT;
        iSchema = i;
      }
      if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
        iPgno = i;
      }
    }
  }

  if( iSchema>=0 ){
    pIdx->aConstraintUsage[iSchema].argvIndex = 1;
    pIdx->aConstraintUsage[iSchema].omit = 1;
  }
  if( iPgno>=0 ){
    pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
    pIdx->aConstraintUsage[iPgno].omit = 1;
    pIdx->estimatedCost = 100;
    pIdx->estimatedRows =  50;

    if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
      int iCol = pIdx->aOrderBy[0].iColumn;
      if( pIdx->nOrderBy==1 ){
        pIdx->orderByConsumed = (iCol==0 || iCol==1);
      }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
        pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
      }
    }

  }else{
    pIdx->estimatedCost = 100000000;
    pIdx->estimatedRows = 1000000000;
  }
  pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
  return SQLITE_OK;
}

/*
** Open a new sqlite_dbdata or sqlite_dbptr cursor.
*/
static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
  DbdataCursor *pCsr;

  pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
  if( pCsr==0 ){
    return SQLITE_NOMEM;
  }else{
    memset(pCsr, 0, sizeof(DbdataCursor));
    pCsr->base.pVtab = pVTab;
  }

  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
  return SQLITE_OK;
}

/*
** Restore a cursor object to the state it was in when first allocated 
** by dbdataOpen().
*/
static void dbdataResetCursor(DbdataCursor *pCsr){
  DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
  if( pTab->pStmt==0 ){
    pTab->pStmt = pCsr->pStmt;
  }else{
    sqlite3_finalize(pCsr->pStmt);
  }
  pCsr->pStmt = 0;
  pCsr->iPgno = 1;
  pCsr->iCell = 0;
  pCsr->iField = 0;
  pCsr->bOnePage = 0;
  sqlite3_free(pCsr->aPage);
  sqlite3_free(pCsr->pRec);
  pCsr->pRec = 0;
  pCsr->aPage = 0;
}

/*
** Close an sqlite_dbdata or sqlite_dbptr cursor.
*/
static int dbdataClose(sqlite3_vtab_cursor *pCursor){
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
  dbdataResetCursor(pCsr);
  sqlite3_free(pCsr);
  return SQLITE_OK;
}

/* 
** Utility methods to decode 16 and 32-bit big-endian unsigned integers. 
*/
static unsigned int get_uint16(unsigned char *a){
  return (a[0]<<8)|a[1];
}
static unsigned int get_uint32(unsigned char *a){
  return ((unsigned int)a[0]<<24)
       | ((unsigned int)a[1]<<16)
       | ((unsigned int)a[2]<<8)
       | ((unsigned int)a[3]);
}

/*
** Load page pgno from the database via the sqlite_dbpage virtual table.
** If successful, set (*ppPage) to point to a buffer containing the page
** data, (*pnPage) to the size of that buffer in bytes and return
** SQLITE_OK. In this case it is the responsibility of the caller to
** eventually free the buffer using sqlite3_free().
**
** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
** return an SQLite error code.
*/
static int dbdataLoadPage(
  DbdataCursor *pCsr,             /* Cursor object */
  unsigned int pgno,              /* Page number of page to load */
  u8 **ppPage,                    /* OUT: pointer to page buffer */
  int *pnPage                     /* OUT: Size of (*ppPage) in bytes */
){
  int rc2;
  int rc = SQLITE_OK;
  sqlite3_stmt *pStmt = pCsr->pStmt;

  *ppPage = 0;
  *pnPage = 0;
  sqlite3_bind_int64(pStmt, 2, pgno);
  if( SQLITE_ROW==sqlite3_step(pStmt) ){
    int nCopy = sqlite3_column_bytes(pStmt, 0);
    if( nCopy>0 ){
      u8 *pPage;
      pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
      if( pPage==0 ){
        rc = SQLITE_NOMEM;
      }else{
        const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
        memcpy(pPage, pCopy, nCopy);
        memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
      }
      *ppPage = pPage;
      *pnPage = nCopy;
    }
  }
  rc2 = sqlite3_reset(pStmt);
  if( rc==SQLITE_OK ) rc = rc2;

  return rc;
}

/*
** Read a varint.  Put the value in *pVal and return the number of bytes.
*/
static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
  sqlite3_int64 v = 0;
  int i;
  for(i=0; i<8; i++){
    v = (v<<7) + (z[i]&0x7f);
    if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
  }
  v = (v<<8) + (z[i]&0xff);
  *pVal = v;
  return 9;
}

/*
** Return the number of bytes of space used by an SQLite value of type
** eType.
*/
static int dbdataValueBytes(int eType){
  switch( eType ){
    case 0: case 8: case 9:
    case 10: case 11:
      return 0;
    case 1:
      return 1;
    case 2:
      return 2;
    case 3:
      return 3;
    case 4:
      return 4;
    case 5:
      return 6;
    case 6:
    case 7:
      return 8;
    default:
      if( eType>0 ){
        return ((eType-12) / 2);
      }
      return 0;
  }
}

/*
** Load a value of type eType from buffer pData and use it to set the
** result of context object pCtx.
*/
static void dbdataValue(
  sqlite3_context *pCtx, 
  int eType, 
  u8 *pData,
  int nData
){
  if( eType>=0 && dbdataValueBytes(eType)<=nData ){
    switch( eType ){
      case 0: 
      case 10: 
      case 11: 
        sqlite3_result_null(pCtx);
        break;
      
      case 8: 
        sqlite3_result_int(pCtx, 0);
        break;
      case 9:
        sqlite3_result_int(pCtx, 1);
        break;
  
      case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
        sqlite3_uint64 v = (signed char)pData[0];
        pData++;
        switch( eType ){
          case 7:
          case 6:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
          case 5:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
          case 4:  v = (v<<8) + pData[0];  pData++;
          case 3:  v = (v<<8) + pData[0];  pData++;
          case 2:  v = (v<<8) + pData[0];  pData++;
        }
  
        if( eType==7 ){
          double r;
          memcpy(&r, &v, sizeof(r));
          sqlite3_result_double(pCtx, r);
        }else{
          sqlite3_result_int64(pCtx, (sqlite3_int64)v);
        }
        break;
      }
  
      default: {
        int n = ((eType-12) / 2);
        if( eType % 2 ){
          sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
        }else{
          sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
        }
      }
    }
  }
}

/*
** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
*/
static int dbdataNext(sqlite3_vtab_cursor *pCursor){
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
  DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;

  pCsr->iRowid++;
  while( 1 ){
    int rc;
    int iOff = (pCsr->iPgno==1 ? 100 : 0);
    int bNextPage = 0;

    if( pCsr->aPage==0 ){
      while( 1 ){
        if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
        rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
        if( rc!=SQLITE_OK ) return rc;
        if( pCsr->aPage ) break;
        pCsr->iPgno++;
      }
      pCsr->iCell = pTab->bPtr ? -2 : 0;
      pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
    }

    if( pTab->bPtr ){
      if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
        pCsr->iCell = pCsr->nCell;
      }
      pCsr->iCell++;
      if( pCsr->iCell>=pCsr->nCell ){
        sqlite3_free(pCsr->aPage);
        pCsr->aPage = 0;
        if( pCsr->bOnePage ) return SQLITE_OK;
        pCsr->iPgno++;
      }else{
        return SQLITE_OK;
      }
    }else{
      /* If there is no record loaded, load it now. */
      if( pCsr->pRec==0 ){
        int bHasRowid = 0;
        int nPointer = 0;
        sqlite3_int64 nPayload = 0;
        sqlite3_int64 nHdr = 0;
        int iHdr;
        int U, X;
        int nLocal;
  
        switch( pCsr->aPage[iOff] ){
          case 0x02:
            nPointer = 4;
            break;
          case 0x0a:
            break;
          case 0x0d:
            bHasRowid = 1;
            break;
          default:
            /* This is not a b-tree page with records on it. Continue. */
            pCsr->iCell = pCsr->nCell;
            break;
        }

        if( pCsr->iCell>=pCsr->nCell ){
          bNextPage = 1;
        }else{
  
          iOff += 8 + nPointer + pCsr->iCell*2;
          if( iOff>pCsr->nPage ){
            bNextPage = 1;
          }else{
            iOff = get_uint16(&pCsr->aPage[iOff]);
          }
    
          /* For an interior node cell, skip past the child-page number */
          iOff += nPointer;
    
          /* Load the "byte of payload including overflow" field */
          if( bNextPage || iOff>pCsr->nPage ){
            bNextPage = 1;
          }else{
            iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
          }
    
          /* If this is a leaf intkey cell, load the rowid */
          if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
            iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
          }
    
          /* Figure out how much data to read from the local page */
          U = pCsr->nPage;
          if( bHasRowid ){
            X = U-35;
          }else{
            X = ((U-12)*64/255)-23;
          }
          if( nPayload<=X ){
            nLocal = nPayload;
          }else{
            int M, K;
            M = ((U-12)*32/255)-23;
            K = M+((nPayload-M)%(U-4));
            if( K<=X ){
              nLocal = K;
            }else{
              nLocal = M;
            }
          }

          if( bNextPage || nLocal+iOff>pCsr->nPage ){
            bNextPage = 1;
          }else{

            /* Allocate space for payload. And a bit more to catch small buffer
            ** overruns caused by attempting to read a varint or similar from 
            ** near the end of a corrupt record.  */
            pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
            if( pCsr->pRec==0 ) return SQLITE_NOMEM;
            memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
            pCsr->nRec = nPayload;

            /* Load the nLocal bytes of payload */
            memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
            iOff += nLocal;

            /* Load content from overflow pages */
            if( nPayload>nLocal ){
              sqlite3_int64 nRem = nPayload - nLocal;
              unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
              while( nRem>0 ){
                u8 *aOvfl = 0;
                int nOvfl = 0;
                int nCopy;
                rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
                assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
                if( rc!=SQLITE_OK ) return rc;
                if( aOvfl==0 ) break;

                nCopy = U-4;
                if( nCopy>nRem ) nCopy = nRem;
                memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
                nRem -= nCopy;

                pgnoOvfl = get_uint32(aOvfl);
                sqlite3_free(aOvfl);
              }
            }
    
            iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
            pCsr->nHdr = nHdr;
            pCsr->pHdrPtr = &pCsr->pRec[iHdr];
            pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
            pCsr->iField = (bHasRowid ? -1 : 0);
          }
        }
      }else{
        pCsr->iField++;
        if( pCsr->iField>0 ){
          sqlite3_int64 iType;
          if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
            bNextPage = 1;
          }else{
            pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
            pCsr->pPtr += dbdataValueBytes(iType);
          }
        }
      }

      if( bNextPage ){
        sqlite3_free(pCsr->aPage);
        sqlite3_free(pCsr->pRec);
        pCsr->aPage = 0;
        pCsr->pRec = 0;
        if( pCsr->bOnePage ) return SQLITE_OK;
        pCsr->iPgno++;
      }else{
        if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
          return SQLITE_OK;
        }

        /* Advance to the next cell. The next iteration of the loop will load
        ** the record and so on. */
        sqlite3_free(pCsr->pRec);
        pCsr->pRec = 0;
        pCsr->iCell++;
      }
    }
  }

  assert( !"can't get here" );
  return SQLITE_OK;
}

/* 
** Return true if the cursor is at EOF.
*/
static int dbdataEof(sqlite3_vtab_cursor *pCursor){
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
  return pCsr->aPage==0;
}

/* 
** Determine the size in pages of database zSchema (where zSchema is
** "main", "temp" or the name of an attached database) and set 
** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
** an SQLite error code.
*/
static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
  DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
  char *zSql = 0;
  int rc, rc2;
  sqlite3_stmt *pStmt = 0;

  zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
  if( zSql==0 ) return SQLITE_NOMEM;
  rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
  sqlite3_free(zSql);
  if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
    pCsr->szDb = sqlite3_column_int(pStmt, 0);
  }
  rc2 = sqlite3_finalize(pStmt);
  if( rc==SQLITE_OK ) rc = rc2;
  return rc;
}

/* 
** xFilter method for sqlite_dbdata and sqlite_dbptr.
*/
static int dbdataFilter(
  sqlite3_vtab_cursor *pCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
  DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
  int rc = SQLITE_OK;
  const char *zSchema = "main";

  dbdataResetCursor(pCsr);
  assert( pCsr->iPgno==1 );
  if( idxNum & 0x01 ){
    zSchema = (const char*)sqlite3_value_text(argv[0]);
  }
  if( idxNum & 0x02 ){
    pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
    pCsr->bOnePage = 1;
  }else{
    pCsr->nPage = dbdataDbsize(pCsr, zSchema);
    rc = dbdataDbsize(pCsr, zSchema);
  }

  if( rc==SQLITE_OK ){
    if( pTab->pStmt ){
      pCsr->pStmt = pTab->pStmt;
      pTab->pStmt = 0;
    }else{
      rc = sqlite3_prepare_v2(pTab->db, 
          "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
          &pCsr->pStmt, 0
      );
    }
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
  }else{
    pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
  }
  if( rc==SQLITE_OK ){
    rc = dbdataNext(pCursor);
  }
  return rc;
}

/* 
** Return a column for the sqlite_dbdata or sqlite_dbptr table.
*/
static int dbdataColumn(
  sqlite3_vtab_cursor *pCursor, 
  sqlite3_context *ctx, 
  int i
){
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
  DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
  if( pTab->bPtr ){
    switch( i ){
      case DBPTR_COLUMN_PGNO:
        sqlite3_result_int64(ctx, pCsr->iPgno);
        break;
      case DBPTR_COLUMN_CHILD: {
        int iOff = pCsr->iPgno==1 ? 100 : 0;
        if( pCsr->iCell<0 ){
          iOff += 8;
        }else{
          iOff += 12 + pCsr->iCell*2;
          if( iOff>pCsr->nPage ) return SQLITE_OK;
          iOff = get_uint16(&pCsr->aPage[iOff]);
        }
        if( iOff<=pCsr->nPage ){
          sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
        }
        break;
      }
    }
  }else{
    switch( i ){
      case DBDATA_COLUMN_PGNO:
        sqlite3_result_int64(ctx, pCsr->iPgno);
        break;
      case DBDATA_COLUMN_CELL:
        sqlite3_result_int(ctx, pCsr->iCell);
        break;
      case DBDATA_COLUMN_FIELD:
        sqlite3_result_int(ctx, pCsr->iField);
        break;
      case DBDATA_COLUMN_VALUE: {
        if( pCsr->iField<0 ){
          sqlite3_result_int64(ctx, pCsr->iIntkey);
        }else{
          sqlite3_int64 iType;
          dbdataGetVarint(pCsr->pHdrPtr, &iType);
          dbdataValue(
              ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
          );
        }
        break;
      }
    }
  }
  return SQLITE_OK;
}

/* 
** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
*/
static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
  *pRowid = pCsr->iRowid;
  return SQLITE_OK;
}


/*
** Invoke this routine to register the "sqlite_dbdata" virtual table module
*/
static int sqlite3DbdataRegister(sqlite3 *db){
  static sqlite3_module dbdata_module = {
    0,                            /* iVersion */
    0,                            /* xCreate */
    dbdataConnect,                /* xConnect */
    dbdataBestIndex,              /* xBestIndex */
    dbdataDisconnect,             /* xDisconnect */
    0,                            /* xDestroy */
    dbdataOpen,                   /* xOpen - open a cursor */
    dbdataClose,                  /* xClose - close a cursor */
    dbdataFilter,                 /* xFilter - configure scan constraints */
    dbdataNext,                   /* xNext - advance a cursor */
    dbdataEof,                    /* xEof - check for end of scan */
    dbdataColumn,                 /* xColumn - read data */
    dbdataRowid,                  /* xRowid - read data */
    0,                            /* xUpdate */
    0,                            /* xBegin */
    0,                            /* xSync */
    0,                            /* xCommit */
    0,                            /* xRollback */
    0,                            /* xFindMethod */
    0,                            /* xRename */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0,                            /* xRollbackTo */
    0                             /* xShadowName */
  };

  int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
  }
  return rc;
}

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_dbdata_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  SQLITE_EXTENSION_INIT2(pApi);
  return sqlite3DbdataRegister(db);
}

Changes to ext/misc/dbdump.c.

391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414







-
+








-
+







  zTable = azArg[0];
  zType = azArg[1];
  zSql = azArg[2];

  if( strcmp(zTable, "sqlite_sequence")==0 ){
    p->xCallback("DELETE FROM sqlite_sequence;\n", p->pArg);
  }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
    p->xCallback("ANALYZE sqlite_schema;\n", p->pArg);
    p->xCallback("ANALYZE sqlite_master;\n", p->pArg);
  }else if( strncmp(zTable, "sqlite_", 7)==0 ){
    return 0;
  }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
    if( !p->writableSchema ){
      p->xCallback("PRAGMA writable_schema=ON;\n", p->pArg);
      p->writableSchema = 1;
    }
    output_formatted(p,
       "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
       "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
       "VALUES('table','%q','%q',0,'%q');",
       zTable, zTable, zSql);
    return 0;
  }else{
    if( sqlite3_strglob("CREATE TABLE ['\"]*", zSql)==0 ){
      p->xCallback("CREATE TABLE IF NOT EXISTS ", p->pArg);
      p->xCallback(zSql+13, p->pArg);
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
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







-
+




-
+



-
+




-
+





-
+







  if( x.rc ) return x.rc;
  x.db = db;
  x.xCallback = xCallback;
  x.pArg = pArg;
  xCallback("PRAGMA foreign_keys=OFF;\nBEGIN TRANSACTION;\n", pArg);
  if( zTable==0 ){
    run_schema_dump_query(&x,
      "SELECT name, type, sql FROM \"%w\".sqlite_schema "
      "SELECT name, type, sql FROM \"%w\".sqlite_master "
      "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'",
      zSchema
    );
    run_schema_dump_query(&x,
      "SELECT name, type, sql FROM \"%w\".sqlite_schema "
      "SELECT name, type, sql FROM \"%w\".sqlite_master "
      "WHERE name=='sqlite_sequence'", zSchema
    );
    output_sql_from_query(&x,
      "SELECT sql FROM sqlite_schema "
      "SELECT sql FROM sqlite_master "
      "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
    );
  }else{
    run_schema_dump_query(&x,
      "SELECT name, type, sql FROM \"%w\".sqlite_schema "
      "SELECT name, type, sql FROM \"%w\".sqlite_master "
      "WHERE tbl_name=%Q COLLATE nocase AND type=='table'"
      "  AND sql NOT NULL",
      zSchema, zTable
    );
    output_sql_from_query(&x,
      "SELECT sql FROM \"%w\".sqlite_schema "
      "SELECT sql FROM \"%w\".sqlite_master "
      "WHERE sql NOT NULL"
      "  AND type IN ('index','trigger','view')"
      "  AND tbl_name=%Q COLLATE nocase",
      zSchema, zTable
    ); 
  }
  if( x.writableSchema ){

Deleted ext/misc/decimal.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634


























































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2020-06-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.
**
******************************************************************************
**
** Routines to implement arbitrary-precision decimal math.
**
** The focus here is on simplicity and correctness, not performance.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

/* Mark a function parameter as unused, to suppress nuisance compiler
** warnings. */
#ifndef UNUSED_PARAMETER
# define UNUSED_PARAMETER(X)  (void)(X)
#endif


/* A decimal object */
typedef struct Decimal Decimal;
struct Decimal {
  char sign;        /* 0 for positive, 1 for negative */
  char oom;         /* True if an OOM is encountered */
  char isNull;      /* True if holds a NULL rather than a number */
  char isInit;      /* True upon initialization */
  int nDigit;       /* Total number of digits */
  int nFrac;        /* Number of digits to the right of the decimal point */
  signed char *a;   /* Array of digits.  Most significant first. */
};

/*
** Release memory held by a Decimal, but do not free the object itself.
*/
static void decimal_clear(Decimal *p){
  sqlite3_free(p->a);
}

/*
** Destroy a Decimal object
*/
static void decimal_free(Decimal *p){
  if( p ){
    decimal_clear(p);
    sqlite3_free(p);
  }
}

/*
** Allocate a new Decimal object.  Initialize it to the number given
** by the input string.
*/
static Decimal *decimal_new(
  sqlite3_context *pCtx,
  sqlite3_value *pIn,
  int nAlt,
  const unsigned char *zAlt
){
  Decimal *p;
  int n, i;
  const unsigned char *zIn;
  int iExp = 0;
  p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ) goto new_no_mem;
  p->sign = 0;
  p->oom = 0;
  p->isInit = 1;
  p->isNull = 0;
  p->nDigit = 0;
  p->nFrac = 0;
  if( zAlt ){
    n = nAlt,
    zIn = zAlt;
  }else{
    if( sqlite3_value_type(pIn)==SQLITE_NULL ){
      p->a = 0;
      p->isNull = 1;
      return p;
    }
    n = sqlite3_value_bytes(pIn);
    zIn = sqlite3_value_text(pIn);
  }
  p->a = sqlite3_malloc64( n+1 );
  if( p->a==0 ) goto new_no_mem;
  for(i=0; isspace(zIn[i]); i++){}
  if( zIn[i]=='-' ){
    p->sign = 1;
    i++;
  }else if( zIn[i]=='+' ){
    i++;
  }
  while( i<n && zIn[i]=='0' ) i++;
  while( i<n ){
    char c = zIn[i];
    if( c>='0' && c<='9' ){
      p->a[p->nDigit++] = c - '0';
    }else if( c=='.' ){
      p->nFrac = p->nDigit + 1;
    }else if( c=='e' || c=='E' ){
      int j = i+1;
      int neg = 0;
      if( j>=n ) break;
      if( zIn[j]=='-' ){
        neg = 1;
        j++;
      }else if( zIn[j]=='+' ){
        j++;
      }
      while( j<n && iExp<1000000 ){
        if( zIn[j]>='0' && zIn[j]<='9' ){
          iExp = iExp*10 + zIn[j] - '0';
        }
        j++;
      }
      if( neg ) iExp = -iExp;
      break;
    }
    i++;
  }
  if( p->nFrac ){
    p->nFrac = p->nDigit - (p->nFrac - 1);
  }
  if( iExp>0 ){
    if( p->nFrac>0 ){
      if( iExp<=p->nFrac ){
        p->nFrac -= iExp;
        iExp = 0;
      }else{
        iExp -= p->nFrac;
        p->nFrac = 0;
      }
    }
    if( iExp>0 ){   
      p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
      if( p->a==0 ) goto new_no_mem;
      memset(p->a+p->nDigit, 0, iExp);
      p->nDigit += iExp;
    }
  }else if( iExp<0 ){
    int nExtra;
    iExp = -iExp;
    nExtra = p->nDigit - p->nFrac - 1;
    if( nExtra ){
      if( nExtra>=iExp ){
        p->nFrac += iExp;
        iExp  = 0;
      }else{
        iExp -= nExtra;
        p->nFrac = p->nDigit - 1;
      }
    }
    if( iExp>0 ){
      p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
      if( p->a==0 ) goto new_no_mem;
      memmove(p->a+iExp, p->a, p->nDigit);
      memset(p->a, 0, iExp);
      p->nDigit += iExp;
      p->nFrac += iExp;
    }
  }
  return p;

new_no_mem:
  if( pCtx ) sqlite3_result_error_nomem(pCtx);
  sqlite3_free(p);
  return 0;
}

/*
** Make the given Decimal the result.
*/
static void decimal_result(sqlite3_context *pCtx, Decimal *p){
  char *z;
  int i, j;
  int n;
  if( p==0 || p->oom ){
    sqlite3_result_error_nomem(pCtx);
    return;
  }
  if( p->isNull ){
    sqlite3_result_null(pCtx);
    return;
  }
  z = sqlite3_malloc( p->nDigit+4 );
  if( z==0 ){
    sqlite3_result_error_nomem(pCtx);
    return;
  }
  i = 0;
  if( p->nDigit==0 || (p->nDigit==1 && p->a[0]==0) ){
    p->sign = 0;
  }
  if( p->sign ){
    z[0] = '-';
    i = 1;
  }
  n = p->nDigit - p->nFrac;
  if( n<=0 ){
    z[i++] = '0';
  }
  j = 0;
  while( n>1 && p->a[j]==0 ){
    j++;
    n--;
  }
  while( n>0  ){
    z[i++] = p->a[j] + '0';
    j++;
    n--;
  }
  if( p->nFrac ){
    z[i++] = '.';
    do{
      z[i++] = p->a[j] + '0';
      j++;
    }while( j<p->nDigit );
  }
  z[i] = 0;
  sqlite3_result_text(pCtx, z, i, sqlite3_free);
}

/*
** SQL Function:   decimal(X)
**
** Convert input X into decimal and then back into text
*/
static void decimalFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Decimal *p = decimal_new(context, argv[0], 0, 0);
  UNUSED_PARAMETER(argc);
  decimal_result(context, p);
  decimal_free(p);
}

/*
** Compare to Decimal objects.  Return negative, 0, or positive if the
** first object is less than, equal to, or greater than the second.
**
** Preconditions for this routine:
**
**    pA!=0
**    pA->isNull==0
**    pB!=0
**    pB->isNull==0
*/
static int decimal_cmp(const Decimal *pA, const Decimal *pB){
  int nASig, nBSig, rc, n;
  if( pA->sign!=pB->sign ){
    return pA->sign ? -1 : +1;
  }
  if( pA->sign ){
    const Decimal *pTemp = pA;
    pA = pB;
    pB = pTemp;
  }
  nASig = pA->nDigit - pA->nFrac;
  nBSig = pB->nDigit - pB->nFrac;
  if( nASig!=nBSig ){
    return nASig - nBSig;
  }
  n = pA->nDigit;
  if( n>pB->nDigit ) n = pB->nDigit;
  rc = memcmp(pA->a, pB->a, n);
  if( rc==0 ){
    rc = pA->nDigit - pB->nDigit;
  }
  return rc;
}

/*
** SQL Function:   decimal_cmp(X, Y)
**
** Return negative, zero, or positive if X is less then, equal to, or
** greater than Y.
*/
static void decimalCmpFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Decimal *pA = 0, *pB = 0;
  int rc;

  UNUSED_PARAMETER(argc);
  pA = decimal_new(context, argv[0], 0, 0);
  if( pA==0 || pA->isNull ) goto cmp_done;
  pB = decimal_new(context, argv[1], 0, 0);
  if( pB==0 || pB->isNull ) goto cmp_done;
  rc = decimal_cmp(pA, pB);
  if( rc<0 ) rc = -1;
  else if( rc>0 ) rc = +1;
  sqlite3_result_int(context, rc);
cmp_done:
  decimal_free(pA);
  decimal_free(pB);
}

/*
** Expand the Decimal so that it has a least nDigit digits and nFrac
** digits to the right of the decimal point.
*/
static void decimal_expand(Decimal *p, int nDigit, int nFrac){
  int nAddSig;
  int nAddFrac;
  if( p==0 ) return;
  nAddFrac = nFrac - p->nFrac;
  nAddSig = (nDigit - p->nDigit) - nAddFrac;
  if( nAddFrac==0 && nAddSig==0 ) return;
  p->a = sqlite3_realloc64(p->a, nDigit+1);
  if( p->a==0 ){
    p->oom = 1;
    return;
  }
  if( nAddSig ){
    memmove(p->a+nAddSig, p->a, p->nDigit);
    memset(p->a, 0, nAddSig);
    p->nDigit += nAddSig;
  }
  if( nAddFrac ){
    memset(p->a+p->nDigit, 0, nAddFrac);
    p->nDigit += nAddFrac;
    p->nFrac += nAddFrac;
  }
}

/*
** Add the value pB into pA.
**
** Both pA and pB might become denormalized by this routine.
*/
static void decimal_add(Decimal *pA, Decimal *pB){
  int nSig, nFrac, nDigit;
  int i, rc;
  if( pA==0 ){
    return;
  }
  if( pA->oom || pB==0 || pB->oom ){
    pA->oom = 1;
    return;
  }
  if( pA->isNull || pB->isNull ){
    pA->isNull = 1;
    return;
  }
  nSig = pA->nDigit - pA->nFrac;
  if( nSig && pA->a[0]==0 ) nSig--;
  if( nSig<pB->nDigit-pB->nFrac ){
    nSig = pB->nDigit - pB->nFrac;
  }
  nFrac = pA->nFrac;
  if( nFrac<pB->nFrac ) nFrac = pB->nFrac;
  nDigit = nSig + nFrac + 1;
  decimal_expand(pA, nDigit, nFrac);
  decimal_expand(pB, nDigit, nFrac);
  if( pA->oom || pB->oom ){
    pA->oom = 1;
  }else{
    if( pA->sign==pB->sign ){
      int carry = 0;
      for(i=nDigit-1; i>=0; i--){
        int x = pA->a[i] + pB->a[i] + carry;
        if( x>=10 ){
          carry = 1;
          pA->a[i] = x - 10;
        }else{
          carry = 0;
          pA->a[i] = x;
        }
      }
    }else{
      signed char *aA, *aB;
      int borrow = 0;
      rc = memcmp(pA->a, pB->a, nDigit);
      if( rc<0 ){
        aA = pB->a;
        aB = pA->a;
        pA->sign = !pA->sign;
      }else{
        aA = pA->a;
        aB = pB->a;
      }
      for(i=nDigit-1; i>=0; i--){
        int x = aA[i] - aB[i] - borrow;
        if( x<0 ){
          pA->a[i] = x+10;
          borrow = 1;
        }else{
          pA->a[i] = x;
          borrow = 0;
        }
      }
    }
  }
}

/*
** Compare text in decimal order.
*/
static int decimalCollFunc(
  void *notUsed,
  int nKey1, const void *pKey1,
  int nKey2, const void *pKey2
){
  const unsigned char *zA = (const unsigned char*)pKey1;
  const unsigned char *zB = (const unsigned char*)pKey2;
  Decimal *pA = decimal_new(0, 0, nKey1, zA);
  Decimal *pB = decimal_new(0, 0, nKey2, zB);
  int rc;
  UNUSED_PARAMETER(notUsed);
  if( pA==0 || pB==0 ){
    rc = 0;
  }else{
    rc = decimal_cmp(pA, pB);
  }
  decimal_free(pA);
  decimal_free(pB);
  return rc;
}


/*
** SQL Function:   decimal_add(X, Y)
**                 decimal_sub(X, Y)
**
** Return the sum or difference of X and Y.
*/
static void decimalAddFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
  UNUSED_PARAMETER(argc);
  decimal_add(pA, pB);
  decimal_result(context, pA);
  decimal_free(pA);
  decimal_free(pB);
}
static void decimalSubFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
  UNUSED_PARAMETER(argc);
  if( pB==0 ) return;
  pB->sign = !pB->sign;
  decimal_add(pA, pB);
  decimal_result(context, pA);
  decimal_free(pA);
  decimal_free(pB);
}

/* Aggregate funcion:   decimal_sum(X)
**
** Works like sum() except that it uses decimal arithmetic for unlimited
** precision.
*/
static void decimalSumStep(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Decimal *p;
  Decimal *pArg;
  UNUSED_PARAMETER(argc);
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p==0 ) return;
  if( !p->isInit ){
    p->isInit = 1;
    p->a = sqlite3_malloc(2);
    if( p->a==0 ){
      p->oom = 1;
    }else{
      p->a[0] = 0;
    }
    p->nDigit = 1;
    p->nFrac = 0;
  }
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pArg = decimal_new(context, argv[0], 0, 0);
  decimal_add(p, pArg);
  decimal_free(pArg);
}
static void decimalSumInverse(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Decimal *p;
  Decimal *pArg;
  UNUSED_PARAMETER(argc);
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p==0 ) return;
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pArg = decimal_new(context, argv[0], 0, 0);
  if( pArg ) pArg->sign = !pArg->sign;
  decimal_add(p, pArg);
  decimal_free(pArg);
}
static void decimalSumValue(sqlite3_context *context){
  Decimal *p = sqlite3_aggregate_context(context, 0);
  if( p==0 ) return;
  decimal_result(context, p);
}
static void decimalSumFinalize(sqlite3_context *context){
  Decimal *p = sqlite3_aggregate_context(context, 0);
  if( p==0 ) return;
  decimal_result(context, p);
  decimal_clear(p);
}

/*
** SQL Function:   decimal_mul(X, Y)
**
** Return the product of X and Y.
**
** All significant digits after the decimal point are retained.
** Trailing zeros after the decimal point are omitted as long as
** the number of digits after the decimal point is no less than
** either the number of digits in either input.
*/
static void decimalMulFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
  signed char *acc = 0;
  int i, j, k;
  int minFrac;
  UNUSED_PARAMETER(argc);
  if( pA==0 || pA->oom || pA->isNull
   || pB==0 || pB->oom || pB->isNull 
  ){
    goto mul_end;
  }
  acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
  if( acc==0 ){
    sqlite3_result_error_nomem(context);
    goto mul_end;
  }
  memset(acc, 0, pA->nDigit + pB->nDigit + 2);
  minFrac = pA->nFrac;
  if( pB->nFrac<minFrac ) minFrac = pB->nFrac;
  for(i=pA->nDigit-1; i>=0; i--){
    signed char f = pA->a[i];
    int carry = 0, x;
    for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){
      x = acc[k] + f*pB->a[j] + carry;
      acc[k] = x%10;
      carry = x/10;
    }
    x = acc[k] + carry;
    acc[k] = x%10;
    acc[k-1] += x/10;
  }
  sqlite3_free(pA->a);
  pA->a = acc;
  acc = 0;
  pA->nDigit += pB->nDigit + 2;
  pA->nFrac += pB->nFrac;
  pA->sign ^= pB->sign;
  while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){
    pA->nFrac--;
    pA->nDigit--;
  }
  decimal_result(context, pA);

mul_end:
  sqlite3_free(acc);
  decimal_free(pA);
  decimal_free(pB);
}

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_decimal_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  static const struct {
    const char *zFuncName;
    int nArg;
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
  } aFunc[] = {
    { "decimal",       1,   decimalFunc        },
    { "decimal_cmp",   2,   decimalCmpFunc     },
    { "decimal_add",   2,   decimalAddFunc     },
    { "decimal_sub",   2,   decimalSubFunc     },
    { "decimal_mul",   2,   decimalMulFunc     },
  };
  unsigned int i;
  (void)pzErrMsg;  /* Unused parameter */

  SQLITE_EXTENSION_INIT2(pApi);

  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
    rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg,
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
                   0, aFunc[i].xFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_window_function(db, "decimal_sum", 1,
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0,
                   decimalSumStep, decimalSumFinalize,
                   decimalSumValue, decimalSumInverse, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_collation(db, "decimal", SQLITE_UTF8,
                                  0, decimalCollFunc);
  }
  return rc;
}

Changes to ext/misc/eval.c.

109
110
111
112
113
114
115
116

117
118
119
120

121
122
123
124
125
109
110
111
112
113
114
115

116

117
118

119

120
121
122
123







-
+
-


-
+
-




  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "eval", 1, 
  rc = sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0,
                               SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
                               sqlEvalFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "eval", 2,
    rc = sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0,
                                 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
                                 sqlEvalFunc, 0, 0);
  }
  return rc;
}

Changes to ext/misc/explain.c.

12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26







-
+







**
** This file demonstrates an eponymous virtual table that returns the
** EXPLAIN output from an SQL statement.
**
** Usage example:
**
**     .load ./explain
**     SELECT p2 FROM explain('SELECT * FROM sqlite_schema')
**     SELECT p2 FROM explain('SELECT * FROM sqlite_master')
**      WHERE opcode='OpenRead';
**
** This module was originally written to help simplify SQLite testing,
** by providing an easier means of verifying certain patterns in the
** generated bytecode.
*/
#if !defined(SQLITEINT_H)

Changes to ext/misc/fileio.c.

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

397
398
399
400
401
402
403







-







      if( rc ) return 2;
      sqlite3_result_int64(pCtx, nWrite);
    }
  }

  if( mtime>=0 ){
#if defined(_WIN32)
#if !SQLITE_OS_WINRT
    /* Windows */
    FILETIME lastAccess;
    FILETIME lastWrite;
    SYSTEMTIME currentTime;
    LONGLONG intervals;
    HANDLE hFile;
    LPWSTR zUnicodeName;
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
420
421
422
423
424
425
426

427
428
429
430
431
432
433







-







    if( hFile!=INVALID_HANDLE_VALUE ){
      BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
      CloseHandle(hFile);
      return !bResult;
    }else{
      return 1;
    }
#endif
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
    /* Recent unix */
    struct timespec times[2];
    times[0].tv_nsec = times[1].tv_nsec = 0;
    times[0].tv_sec = time(0);
    times[1].tv_sec = mtime;
    if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
581
582
583
584
585
586
587

588
589
590
591
592
593
594







-







  (void)argv;
  (void)pzErr;
  rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
  if( rc==SQLITE_OK ){
    pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
    if( pNew==0 ) return SQLITE_NOMEM;
    memset(pNew, 0, sizeof(*pNew));
    sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
  }
  *ppVtab = (sqlite3_vtab*)pNew;
  return rc;
}

/*
** This method is the destructor for fsdir vtab objects.
977
978
979
980
981
982
983
984

985
986
987
988

989
990
991
992
993
994
995
996
997
998
999
1000
974
975
976
977
978
979
980

981

982
983

984

985
986
987
988
989
990
991
992
993
994
995







-
+
-


-
+
-











  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "readfile", 1, 
  rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
                               SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
                               readfileFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "writefile", -1,
    rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0,
                                 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
                                 writefileFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
                                 lsModeFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = fsdirRegister(db);
  }
  return rc;
}

Changes to ext/misc/fossildelta.c.

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







-











-
-







*/
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1

#ifndef SQLITE_AMALGAMATION
/*
** The "u32" type must be an unsigned 32-bit integer.  Adjust this
*/
typedef unsigned int u32;

/*
** Must be a 16-bit value
*/
typedef short int s16;
typedef unsigned short int u16;

#endif /* SQLITE_AMALGAMATION */


/*
** The width of a hash window in bytes.  The algorithm only works if this
** is a power of 2.
*/
#define NHASH 16

818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
815
816
817
818
819
820
821

822
823
824
825
826
827
828







-







#define DELTAPARSEVTAB_A2     2
#define DELTAPARSEVTAB_DELTA  3
  if( rc==SQLITE_OK ){
    pNew = sqlite3_malloc64( sizeof(*pNew) );
    *ppVtab = (sqlite3_vtab*)pNew;
    if( pNew==0 ) return SQLITE_NOMEM;
    memset(pNew, 0, sizeof(*pNew));
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  }
  return rc;
}

/*
** This method is the destructor for deltaparsevtab_vtab objects.
*/
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
845
846
847
848
849
850
851

852
853
854
855
856
857
858







-







}

/*
** Destructor for a deltaparsevtab_cursor.
*/
static int deltaparsevtabClose(sqlite3_vtab_cursor *cur){
  deltaparsevtab_cursor *pCur = (deltaparsevtab_cursor*)cur;
  sqlite3_free(pCur->aDelta);
  sqlite3_free(pCur);
  return SQLITE_OK;
}


/*
** Advance a deltaparsevtab_cursor to its next row of output.
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
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







-



-
+


-
+



-
+







__declspec(dllexport)
#endif
int sqlite3_fossildelta_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  static const int enc = SQLITE_UTF8|SQLITE_INNOCUOUS;
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "delta_create", 2, enc, 0,
  rc = sqlite3_create_function(db, "delta_create", 2, SQLITE_UTF8, 0,
                               deltaCreateFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "delta_apply", 2, enc, 0,
    rc = sqlite3_create_function(db, "delta_apply", 2, SQLITE_UTF8, 0,
                                 deltaApplyFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "delta_output_size", 1, enc, 0,
    rc = sqlite3_create_function(db, "delta_output_size", 1, SQLITE_UTF8, 0,
                                 deltaOutputSizeFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_module(db, "delta_parse", &deltaparsevtabModule, 0);
  }
  return rc;
}

Changes to ext/misc/fuzzer.c.

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


543
544
545
546
547
548
549







-
-








      if( rc==SQLITE_OK ){
        rc = sqlite3_declare_vtab(db, "CREATE TABLE x(word,distance,ruleset)");
      }
      if( rc!=SQLITE_OK ){
        fuzzerDisconnect((sqlite3_vtab *)pNew);
        pNew = 0;
      }else{
        sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
      }
    }
  }

  *ppVtab = (sqlite3_vtab *)pNew;
  return rc;
}

Changes to ext/misc/ieee754.c.

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







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






-
-
-
-
-
-















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













-
-
-
-
+
-






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





-
-
-
-
-
-
-
-




-
+












-
+
-
-
-
-
+
-
-








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









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



+
+
-
-
+
+
-
-
-
+



**
** In the second form, Y and Z are integers which are the mantissa and
** base-2 exponent of a new floating point number.  The function returns
** a floating-point value equal to Y*pow(2,Z).
**
** Examples:
**
**     ieee754(2.0)             ->     'ieee754(2,0)'
**     ieee754(45.25)           ->     'ieee754(181,-2)'
**     ieee754(2, 0)            ->     2.0
**     ieee754(181, -2)         ->     45.25
**     ieee754(2.0)       ->     'ieee754(2,0)'
**     ieee754(45.25)     ->     'ieee754(181,-2)'
**     ieee754(2, 0)      ->     2.0
**     ieee754(181, -2)   ->     45.25
**
** Two additional functions break apart the one-argument ieee754()
** result into separate integer values:
**
**     ieee754_mantissa(45.25)  ->     181
**     ieee754_exponent(45.25)  ->     -2
**
** These functions convert binary64 numbers into blobs and back again.
**
**     ieee754_from_blob(x'3ff0000000000000')  ->  1.0
**     ieee754_to_blob(1.0)                    ->  x'3ff0000000000000'
**
** In all single-argument functions, if the argument is an 8-byte blob
** then that blob is interpreted as a big-endian binary64 value.
**
**
** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES
** -----------------------------------------------
**
** This extension in combination with the separate 'decimal' extension
** can be used to compute the exact decimal representation of binary64
** values.  To begin, first compute a table of exponent values:
**
**    CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
**    WITH RECURSIVE c(x,v) AS (
**      VALUES(0,'1')
**      UNION ALL
**      SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971
**    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
**    WITH RECURSIVE c(x,v) AS (
**      VALUES(-1,'0.5')
**      UNION ALL
**      SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075
**    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
**
** Then, to compute the exact decimal representation of a floating
** point value (the value 47.49 is used in the example) do:
**
**    WITH c(n) AS (VALUES(47.49))
**          ---------------^^^^^---- Replace with whatever you want
**    SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
**
** Here is a query to show various boundry values for the binary64
** number format:
**
**    WITH c(name,bin) AS (VALUES
**       ('minimum positive value',        x'0000000000000001'),
**       ('maximum subnormal value',       x'000fffffffffffff'),
**       ('mininum positive nornal value', x'0010000000000000'),
**       ('maximum value',                 x'7fefffffffffffff'))
**    SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
**
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>

/* Mark a function parameter as unused, to suppress nuisance compiler
** warnings. */
#ifndef UNUSED_PARAMETER
# define UNUSED_PARAMETER(X)  (void)(X)
#endif

/*
** Implementation of the ieee754() function
*/
static void ieee754func(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  if( argc==1 ){
    sqlite3_int64 m, a;
    double r;
    int e;
    int isNeg;
    char zResult[100];
    assert( sizeof(m)==sizeof(r) );
    if( sqlite3_value_type(argv[0])==SQLITE_BLOB
    if( sqlite3_value_type(argv[0])!=SQLITE_FLOAT ) return;
     && sqlite3_value_bytes(argv[0])==sizeof(r)
    ){
      const unsigned char *x = sqlite3_value_blob(argv[0]);
      unsigned int i;
      sqlite3_uint64 v = 0;
      for(i=0; i<sizeof(r); i++){
        v = (v<<8) | x[i];
      }
      memcpy(&r, &v, sizeof(r));
    }else{
      r = sqlite3_value_double(argv[0]);
    r = sqlite3_value_double(argv[0]);
    }
    if( r<0.0 ){
      isNeg = 1;
      r = -r;
    }else{
      isNeg = 0;
    }
    memcpy(&a,&r,sizeof(a));
    if( a==0 ){
      e = 0;
      m = 0;
    }else{
      e = a>>52;
      m = a & ((((sqlite3_int64)1)<<52)-1);
      if( e==0 ){
        m <<= 1;
      }else{
        m |= ((sqlite3_int64)1)<<52;
      m |= ((sqlite3_int64)1)<<52;
      }
      while( e<1075 && m>0 && (m&1)==0 ){
        m >>= 1;
        e++;
      }
      if( isNeg ) m = -m;
    }
    switch( *(int*)sqlite3_user_data(context) ){
      case 0:
        sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)",
                         m, e-1075);
        sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT);
    sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)",
                     m, e-1075);
    sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT);
        break;
      case 1:
        sqlite3_result_int64(context, m);
        break;
      case 2:
        sqlite3_result_int(context, e-1075);
        break;
    }
  }else{
  }else if( argc==2 ){
    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 ){
    }else if( m==0 && e>1000 && e<1000 ){
      sqlite3_result_double(context, 0.0);
      return;
    }
    while( (m>>32)&0xffe00000 ){
      m >>= 1;
      e++;
    }
    while( m!=0 && ((m>>32)&0xfff00000)==0 ){
      m <<= 1;
      e--;
    }
    e += 1075;
    if( e<=0 ){
    if( e<0 ) e = m = 0;
      /* Subnormal */
      m >>= 1-e;
      e = 0;
    }else if( e>0x7ff ){
    if( e>0x7ff ) e = 0x7ff;
      e = 0x7ff;
    }
    a = m & ((((sqlite3_int64)1)<<52)-1);
    a |= e<<52;
    if( isNeg ) a |= ((sqlite3_uint64)1)<<63;
    memcpy(&r, &a, sizeof(r));
    sqlite3_result_double(context, r);
  }
}

/*
** Functions to convert between blobs and floats.
*/
static void ieee754func_from_blob(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  UNUSED_PARAMETER(argc);
  if( sqlite3_value_type(argv[0])==SQLITE_BLOB
   && sqlite3_value_bytes(argv[0])==sizeof(double)
  ){
    double r;
    const unsigned char *x = sqlite3_value_blob(argv[0]);
    unsigned int i;
    sqlite3_uint64 v = 0;
    for(i=0; i<sizeof(r); i++){
      v = (v<<8) | x[i];
    }
    memcpy(&r, &v, sizeof(r));
    sqlite3_result_double(context, r);
  }
}
static void ieee754func_to_blob(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  UNUSED_PARAMETER(argc);
  if( sqlite3_value_type(argv[0])==SQLITE_FLOAT
   || sqlite3_value_type(argv[0])==SQLITE_INTEGER
  ){
    double r = sqlite3_value_double(argv[0]);
    sqlite3_uint64 v;
    unsigned char a[sizeof(r)];
    unsigned int i;
    memcpy(&v, &r, sizeof(r));
    for(i=1; i<=sizeof(r); i++){
      a[sizeof(r)-i] = v&0xff;
      v >>= 8;
    }
    sqlite3_result_blob(context, a, sizeof(r), SQLITE_TRANSIENT);
  }
}


#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_ieee_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  static const struct {
    char *zFName;
    int nArg;
    int iAux;
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
  } aFunc[] = {
    { "ieee754",           1,   0, ieee754func },
    { "ieee754",           2,   0, ieee754func },
    { "ieee754_mantissa",  1,   1, ieee754func },
    { "ieee754_exponent",  1,   2, ieee754func },
    { "ieee754_to_blob",   1,   0, ieee754func_to_blob },
    { "ieee754_from_blob", 1,   0, ieee754func_from_blob },

  };
  unsigned int i;
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "ieee754", 1, SQLITE_UTF8, 0,
                               ieee754func, 0, 0);
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
    rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,	
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "ieee754", 2, SQLITE_UTF8, 0,
                               SQLITE_UTF8|SQLITE_INNOCUOUS,
                               (void*)&aFunc[i].iAux,
                               aFunc[i].xFunc, 0, 0);
                                 ieee754func, 0, 0);
  }
  return rc;
}

Changes to ext/misc/json1.c.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
38
39
40
41
42
43
44




45
46
47
48
49
50
51







-
-
-
-







#endif

#ifndef LARGEST_INT64
# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
#endif

#ifndef deliberate_fall_through
# define deliberate_fall_through
#endif

/*
** Versions of isspace(), isalnum() and isdigit() to which it is safe
** to pass signed char values.
*/
#ifdef sqlite3Isdigit
   /* Use the SQLite core versions if this routine is part of the
   ** SQLite amalgamation */
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
250
251
252
253
254
255
256

257
258
259
260
261
262
263







-







  p->nAlloc = nTotal;
  return SQLITE_OK;
}

/* Append N bytes from zIn onto the end of the JsonString string.
*/
static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
  if( N==0 ) return;
  if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
  memcpy(p->zBuf+p->nUsed, zIn, N);
  p->nUsed += N;
}

/* Append formatted text (not to exceed N bytes) to the JsonString.
*/
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469







-
+







      break;
    }
    case JSON_STRING: {
      if( pNode->jnFlags & JNODE_RAW ){
        jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
        break;
      }
      /* no break */ deliberate_fall_through
      /* Fall through into the next case */
    }
    case JSON_REAL:
    case JSON_INT: {
      jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
      break;
    }
    case JSON_ARRAY: {
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
518
519
520
521
522
523
524































525
526
527
528
529
530
531







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







  JsonString s;
  jsonInit(&s, pCtx);
  jsonRenderNode(pNode, &s, aReplace);
  jsonResult(&s);
  sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
}

/*
** Translate a single byte of Hex into an integer.
** This routine only works if h really is a valid hexadecimal
** character:  0..9a..fA..F
*/
static u8 jsonHexToInt(int h){
  assert( (h>='0' && h<='9') ||  (h>='a' && h<='f') ||  (h>='A' && h<='F') );
#ifdef SQLITE_EBCDIC
  h += 9*(1&~(h>>4));
#else
  h += 9*(1&(h>>6));
#endif
  return (u8)(h & 0xf);
}

/*
** Convert a 4-byte hex string into an integer
*/
static u32 jsonHexToInt4(const char *z){
  u32 v;
  assert( safe_isxdigit(z[0]) );
  assert( safe_isxdigit(z[1]) );
  assert( safe_isxdigit(z[2]) );
  assert( safe_isxdigit(z[3]) );
  v = (jsonHexToInt(z[0])<<12)
    + (jsonHexToInt(z[1])<<8)
    + (jsonHexToInt(z[2])<<4)
    + jsonHexToInt(z[3]);
  return v;
}

/*
** Make the JsonNode the return value of the function.
*/
static void jsonReturn(
  JsonNode *pNode,            /* Node to return */
  sqlite3_context *pCtx,      /* Return value for this function */
  sqlite3_value **aReplace    /* Array of replacement values */
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
565
566
567
568
569
570
571

572
573
574
575
576
577
578
579







-
+







        }
        i = i*10 + v;
      }
      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
      sqlite3_result_int64(pCtx, i);
      int_done:
      break;
      int_as_real: i=0; /* no break */ deliberate_fall_through
      int_as_real: /* fall through to real */;
    }
    case JSON_REAL: {
      double r;
#ifdef SQLITE_AMALGAMATION
      const char *z = pNode->u.zJContent;
      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
#else
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
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







-
-
+
+
+
+
+
+
+
+
+







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







        for(i=1, j=0; i<n-1; i++){
          char c = z[i];
          if( c!='\\' ){
            zOut[j++] = c;
          }else{
            c = z[++i];
            if( c=='u' ){
              u32 v = jsonHexToInt4(z+i+1);
              i += 4;
              u32 v = 0, k;
              for(k=0; k<4; i++, k++){
                assert( i<n-2 );
                c = z[i+1];
                assert( safe_isxdigit(c) );
                if( c<='9' ) v = v*16 + c - '0';
                else if( c<='F' ) v = v*16 + c - 'A' + 10;
                else v = v*16 + c - 'a' + 10;
              }
              if( v==0 ) break;
              if( v<=0x7f ){
                zOut[j++] = (char)v;
              }else if( v<=0x7ff ){
                zOut[j++] = (char)(0xc0 | (v>>6));
                zOut[j++] = 0x80 | (v&0x3f);
              }else{
                u32 vlo;
                if( (v&0xfc00)==0xd800
                  && i<n-6
                  && z[i+1]=='\\'
                  && z[i+2]=='u'
                  && ((vlo = jsonHexToInt4(z+i+3))&0xfc00)==0xdc00
                ){
                  /* We have a surrogate pair */
                  v = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000;
                  i += 6;
                  zOut[j++] = 0xf0 | (v>>18);
                  zOut[j++] = 0x80 | ((v>>12)&0x3f);
                  zOut[j++] = 0x80 | ((v>>6)&0x3f);
                  zOut[j++] = 0x80 | (v&0x3f);
                }else{
                  zOut[j++] = 0xe0 | (v>>12);
                  zOut[j++] = 0x80 | ((v>>6)&0x3f);
                  zOut[j++] = 0x80 | (v&0x3f);
                zOut[j++] = (char)(0xe0 | (v>>12));
                zOut[j++] = 0x80 | ((v>>6)&0x3f);
                zOut[j++] = 0x80 | (v&0x3f);
                }
              }
            }else{
              if( c=='b' ){
                c = '\b';
              }else if( c=='f' ){
                c = '\f';
              }else if( c=='n' ){
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1079
1080
1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091
1092







-







  int *pApnd,             /* Append nodes to complete path if not NULL */
  const char **pzErr      /* Make *pzErr point to any syntax error in zPath */
){
  u32 i, j, nKey;
  const char *zKey;
  JsonNode *pRoot = &pParse->aNode[iRoot];
  if( zPath[0]==0 ) return pRoot;
  if( pRoot->jnFlags & JNODE_REPLACE ) return 0;
  if( zPath[0]=='.' ){
    if( pRoot->eType!=JSON_OBJECT ) return 0;
    zPath++;
    if( zPath[0]=='"' ){
      zKey = zPath + 1;
      for(i=1; zPath[i] && zPath[i]!='"'; i++){}
      nKey = i-1;
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
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







-
+











-
+
+






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







      pRoot = &pParse->aNode[iRoot];
      j = 1;
    }
    if( pApnd ){
      u32 iStart, iLabel;
      JsonNode *pNode;
      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
      iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
      iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
      zPath += i;
      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
      if( pParse->oom ) return 0;
      if( pNode ){
        pRoot = &pParse->aNode[iRoot];
        pRoot->u.iAppend = iStart - iRoot;
        pRoot->jnFlags |= JNODE_APPEND;
        pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
      }
      return pNode;
    }
  }else if( zPath[0]=='[' ){
  }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
    if( pRoot->eType!=JSON_ARRAY ) return 0;
    i = 0;
    j = 1;
    while( safe_isdigit(zPath[j]) ){
      i = i*10 + zPath[j] - '0';
      j++;
    }
    if( j<2 || zPath[j]!=']' ){
      if( zPath[1]=='#' ){
        JsonNode *pBase = pRoot;
        int iBase = iRoot;
        if( pRoot->eType!=JSON_ARRAY ) return 0;
        for(;;){
          while( j<=pBase->n ){
            if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
            j += jsonNodeSize(&pBase[j]);
          }
          if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
          iBase += pBase->u.iAppend;
          pBase = &pParse->aNode[iBase];
          j = 1;
        }
        j = 2;
        if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){
          unsigned int x = 0;
          j = 3;
          do{
            x = x*10 + zPath[j] - '0';
            j++;
          }while( safe_isdigit(zPath[j]) );
          if( x>i ) return 0;
          i -= x;
        }
        if( zPath[j]!=']' ){
          *pzErr = zPath;
          return 0;
        }
    if( zPath[j]!=']' ){
      *pzErr = zPath;
      return 0;
    }
      }else{
        *pzErr = zPath;
        return 0;
      }
    }
    if( pRoot->eType!=JSON_ARRAY ) return 0;
    zPath += j + 1;
    j = 1;
    for(;;){
      while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
        if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
        j += jsonNodeSize(&pRoot[j]);
      }
1892
1893
1894
1895
1896
1897
1898
1899

1900
1901
1902
1903
1904
1905
1906
1815
1816
1817
1818
1819
1820
1821

1822
1823
1824
1825
1826
1827
1828
1829







-
+







  JsonString *pStr;
  UNUSED_PARAM(argc);
  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
  if( pStr ){
    if( pStr->zBuf==0 ){
      jsonInit(pStr, ctx);
      jsonAppendChar(pStr, '[');
    }else if( pStr->nUsed>1 ){
    }else{
      jsonAppendChar(pStr, ',');
      pStr->pCtx = ctx;
    }
    jsonAppendValue(pStr, argv[0]);
  }
}
static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
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
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







-
+

-

-










-
-
+
+
-
-
-
-
+

-
+

-
-
-







** text through that comma.
*/
static void jsonGroupInverse(
  sqlite3_context *ctx,
  int argc,
  sqlite3_value **argv
){
  unsigned int i;
  int i;
  int inStr = 0;
  int nNest = 0;
  char *z;
  char c;
  JsonString *pStr;
  UNUSED_PARAM(argc);
  UNUSED_PARAM(argv);
  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
#ifdef NEVER
  /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
  ** always have been called to initalize it */
  if( NEVER(!pStr) ) return;
#endif
  z = pStr->zBuf;
  for(i=1; (c = z[i])!=',' || inStr || nNest; i++){
    if( i>=pStr->nUsed ){
  for(i=1; z[i]!=',' || inStr; i++){
    assert( i<pStr->nUsed );
      pStr->nUsed = 1;
      return;
    }
    if( c=='"' ){
    if( z[i]=='"' ){
      inStr = !inStr;
    }else if( c=='\\' ){
    }else if( z[i]=='\\' ){
      i++;
    }else if( !inStr ){
      if( c=='{' || c=='[' ) nNest++;
      if( c=='}' || c==']' ) nNest--;
    }
  }
  pStr->nUsed -= i;      
  memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1);
}
#else
# define jsonGroupInverse 0
1996
1997
1998
1999
2000
2001
2002
2003

2004
2005
2006
2007
2008
2009
2010
1911
1912
1913
1914
1915
1916
1917

1918
1919
1920
1921
1922
1923
1924
1925







-
+







  u32 n;
  UNUSED_PARAM(argc);
  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
  if( pStr ){
    if( pStr->zBuf==0 ){
      jsonInit(pStr, ctx);
      jsonAppendChar(pStr, '{');
    }else if( pStr->nUsed>1 ){
    }else{
      jsonAppendChar(pStr, ',');
      pStr->pCtx = ctx;
    }
    z = (const char*)sqlite3_value_text(argv[0]);
    n = (u32)sqlite3_value_bytes(argv[0]);
    jsonAppendString(pStr, z, n);
    jsonAppendChar(pStr, ':');
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2007
2008
2009
2010
2011
2012
2013

2014
2015
2016
2017
2018
2019
2020







-







  rc = sqlite3_declare_vtab(db, 
     "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
                    "json HIDDEN,root HIDDEN)");
  if( rc==SQLITE_OK ){
    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
    if( pNew==0 ) return SQLITE_NOMEM;
    memset(pNew, 0, sizeof(*pNew));
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  }
  return rc;
}

/* destructor for json_each virtual table */
static int jsonEachDisconnect(sqlite3_vtab *pVtab){
  sqlite3_free(pVtab);
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2218
2219
2220
2221
2222
2223
2224

2225
2226
2227
2228
2229
2230
2231







-







        jsonInit(&x, ctx);
        jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
        jsonResult(&x);
        break;
      }
      /* For json_each() path and root are the same so fall through
      ** into the root case */
      /* no break */ deliberate_fall_through
    }
    default: {
      const char *zRoot = p->zRoot;
      if( zRoot==0 ) zRoot = "$";
      sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
      break;
    }
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596


2597
2598
2599
2600
2601
2602
2603

2604
2605
2606
2607
2608
2609
2610
2497
2498
2499
2500
2501
2502
2503




2504

2505
2506
2507
2508
2509
2510
2511
2512

2513
2514
2515
2516
2517
2518
2519
2520







-
-
-
-

-
+
+






-
+







     const char *zName;
     sqlite3_module *pModule;
  } aMod[] = {
    { "json_each",            &jsonEachModule               },
    { "json_tree",            &jsonTreeModule               },
  };
#endif
  static const int enc = 
       SQLITE_UTF8 |
       SQLITE_DETERMINISTIC |
       SQLITE_INNOCUOUS;
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, enc,
    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 
                                 (void*)&aFunc[i].flag,
                                 aFunc[i].xFunc, 0, 0);
  }
#ifndef SQLITE_OMIT_WINDOWFUNC
  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
    rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
                                 SQLITE_SUBTYPE | enc, 0,
                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
                                 aAgg[i].xStep, aAgg[i].xFinal,
                                 aAgg[i].xValue, jsonGroupInverse, 0);
  }
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
    rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);

Changes to ext/misc/mmapwarm.c.

39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53







-
+







  char *zSql = 0;
  int pgsz = 0;
  int nTotal = 0;

  if( 0==sqlite3_get_autocommit(db) ) return SQLITE_MISUSE;

  /* Open a read-only transaction on the file in question */
  zSql = sqlite3_mprintf("BEGIN; SELECT * FROM %s%q%ssqlite_schema", 
  zSql = sqlite3_mprintf("BEGIN; SELECT * FROM %s%q%ssqlite_master", 
      (zDb ? "'" : ""), (zDb ? zDb : ""), (zDb ? "'." : "")
  );
  if( zSql==0 ) return SQLITE_NOMEM;
  rc = sqlite3_exec(db, zSql, 0, 0, 0);
  sqlite3_free(zSql);

  /* Find the SQLite page size of the file */

Changes to ext/misc/nextchar.c.

293
294
295
296
297
298
299
300

301
302
303
304

305
306
307
308
309

310
311
312
313
314
293
294
295
296
297
298
299

300

301
302

303

304
305
306

307

308
309
310
311







-
+
-


-
+
-



-
+
-




  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "next_char", 3,
  rc = sqlite3_create_function(db, "next_char", 3, SQLITE_UTF8, 0,
                               SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
                               nextCharFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "next_char", 4,
    rc = sqlite3_create_function(db, "next_char", 4, SQLITE_UTF8, 0,
                                 SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
                                 nextCharFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "next_char", 5,
    rc = sqlite3_create_function(db, "next_char", 5, SQLITE_UTF8, 0,
                                 SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
                                 nextCharFunc, 0, 0);
  }
  return rc;
}

Deleted ext/misc/noop.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




































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2020-01-08
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This SQLite extension implements a noop() function used for testing.
**
** Variants:
**
**    noop(X)           The default.  Deterministic.
**    noop_i(X)         Deterministic and innocuous.
**    noop_do(X)        Deterministic and direct-only.
**    noop_nd(X)        Non-deterministic.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>

/*
** Implementation of the noop() function.
**
** The function returns its argument, unchanged.
*/
static void noopfunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  assert( argc==1 );
  sqlite3_result_value(context, argv[0]);
}

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_noop_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "noop", 1,
                     SQLITE_UTF8 | SQLITE_DETERMINISTIC,
                     0, noopfunc, 0, 0);
  if( rc ) return rc;
  rc = sqlite3_create_function(db, "noop_i", 1,
                     SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS,
                     0, noopfunc, 0, 0);
  if( rc ) return rc;
  rc = sqlite3_create_function(db, "noop_do", 1,
                     SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY,
                     0, noopfunc, 0, 0);
  if( rc ) return rc;
  rc = sqlite3_create_function(db, "noop_nd", 1,
                     SQLITE_UTF8,
                     0, noopfunc, 0, 0);
  return rc;
}

Changes to ext/misc/normalize.c.

282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
282
283
284
285
286
287
288







289
290
291
292
293
294
295







-
-
-
-
-
-
-







#define TK_ILLEGAL  TK_ERROR
#define TK_DOT      TK_PUNCT
#define TK_INTEGER  TK_LITERAL
#define TK_FLOAT    TK_LITERAL
#define TK_VARIABLE TK_LITERAL
#define TK_BLOB     TK_LITERAL

/* Disable nuisence warnings about case fall-through */
#if !defined(deliberate_fall_through) && defined(__GCC__) && __GCC__>=7
# define deliberate_fall_through __attribute__((fallthrough));
#else
# define deliberate_fall_through
#endif

/*
** Return the length (in bytes) of the token that begins at z[0]. 
** Store the token type in *tokenType before returning.
*/
static int sqlite3GetToken(const unsigned char *z, int *tokenType){
  int i, c;
  switch( aiClass[*z] ){  /* Switch on the character-class of the first byte
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
432
433
434
435
436
437
438

439
440
441
442
443
444
445







-







    case CC_DOT: {
      if( !sqlite3Isdigit(z[1]) ){
        *tokenType = TK_DOT;
        return 1;
      }
      /* If the next character is a digit, this is a floating point
      ** number that begins with ".".  Fall thru into the next case */
      /* no break */ deliberate_fall_through
    }
    case CC_DIGIT: {
      *tokenType = TK_INTEGER;
      if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){
        for(i=3; sqlite3Isxdigit(z[i]); i++){}
        return i;
      }
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
524
525
526
527
528
529
530

531
532
533
534
535
536
537







-







          while( z[i] && z[i]!='\'' ){ i++; }
        }
        if( z[i] ) i++;
        return i;
      }
      /* 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;
    }
    default: {
      *tokenType = TK_ILLEGAL;

Changes to ext/misc/percentile.c.

209
210
211
212
213
214
215
216

217
218
219
220
209
210
211
212
213
214
215

216

217
218
219







-
+
-



  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "percentile", 2, 
  rc = sqlite3_create_function(db, "percentile", 2, SQLITE_UTF8, 0,
                               SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
                               0, percentStep, percentFinal);
  return rc;
}

Changes to ext/misc/prefixes.c.

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
75
76
77
78
79
80
81

82
83
84
85
86
87
88







-







           "CREATE TABLE prefixes(prefix TEXT, original_string TEXT HIDDEN)"
       );
  if( rc==SQLITE_OK ){
    pNew = sqlite3_malloc( sizeof(*pNew) );
    *ppVtab = (sqlite3_vtab*)pNew;
    if( pNew==0 ) return SQLITE_NOMEM;
    memset(pNew, 0, sizeof(*pNew));
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  }
  return rc;
}

/*
** This method is the destructor for prefixes_vtab objects.
*/

Changes to ext/misc/regexp.c.

152
153
154
155
156
157
158
159

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

159
160
161
162
163
164
165
166







-
+







    if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){
      c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
      if( c<0x80 ) c = 0xfffd;
    }else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80
           && (p->z[p->i+1]&0xc0)==0x80 ){
      c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
      p->i += 2;
      if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
      if( c<=0x3ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
    }else if( (c&0xf8)==0xf0 && p->i+3<p->mx && (p->z[p->i]&0xc0)==0x80
           && (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
      c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
                       | (p->z[p->i+2]&0x3f);
      p->i += 3;
      if( c<=0xffff || c>0x10ffff ) c = 0xfffd;
    }else{
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
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







-
+













-
+







  return 0;
}

/* Free and reclaim all the memory used by a previously compiled
** regular expression.  Applications should invoke this routine once
** for every call to re_compile() to avoid memory leaks.
*/
static void re_free(ReCompiled *pRe){
void re_free(ReCompiled *pRe){
  if( pRe ){
    sqlite3_free(pRe->aOp);
    sqlite3_free(pRe->aArg);
    sqlite3_free(pRe);
  }
}

/*
** Compile a textual regular expression in zIn[] into a compiled regular
** expression suitable for us by re_match() and return a pointer to the
** compiled regular expression in *ppRe.  Return NULL on success or an
** error message if something goes wrong.
*/
static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
  ReCompiled *pRe;
  const char *zErr;
  int i, j;

  *ppRe = 0;
  pRe = sqlite3_malloc( sizeof(*pRe) );
  if( pRe==0 ){
750
751
752
753
754
755
756
757
758


759
760
750
751
752
753
754
755
756


757
758
759
760







-
-
+
+


int sqlite3_regexp_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8|SQLITE_INNOCUOUS,
                               0, re_sql_func, 0, 0);
  rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, 0,
                                 re_sql_func, 0, 0);
  return rc;
}

Changes to ext/misc/rot13.c.

101
102
103
104
105
106
107
108

109
110

111
112
113
114
115
101
102
103
104
105
106
107

108


109
110
111
112
113
114







-
+
-
-
+





  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "rot13", 1,
  rc = sqlite3_create_function(db, "rot13", 1, SQLITE_UTF8, 0,
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
                   0, rot13func, 0, 0);
                               rot13func, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_collation(db, "rot13", SQLITE_UTF8, 0, rot13CollFunc);
  }
  return rc;
}

Changes to ext/misc/scrub.c.

162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176







-
+







                 SQLITE_OPEN_READWRITE |
                 SQLITE_OPEN_URI | SQLITE_OPEN_PRIVATECACHE, 0);
  if( p->rcErr ){
    scrubBackupErr(p, "cannot open source database: %s",
                      sqlite3_errmsg(p->dbSrc));
    return;
  }
  p->rcErr = sqlite3_exec(p->dbSrc, "SELECT 1 FROM sqlite_schema; BEGIN;",
  p->rcErr = sqlite3_exec(p->dbSrc, "SELECT 1 FROM sqlite_master; BEGIN;",
                          0, 0, 0);
  if( p->rcErr ){
    scrubBackupErr(p,
       "cannot start a read transaction on the source database: %s",
       sqlite3_errmsg(p->dbSrc));
    return;
  }
531
532
533
534
535
536
537
538

539
540
541
542
543
544
545
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545







-
+







  /* Copy ptrmap pages */
  n = scrubBackupInt32(&s.page1[52]);
  if( n ) scrubBackupPtrmap(&s);

  /* Copy all of the btrees */
  scrubBackupBtree(&s, 1, 0);
  pStmt = scrubBackupPrepare(&s, s.dbSrc,
       "SELECT rootpage FROM sqlite_schema WHERE coalesce(rootpage,0)>0");
       "SELECT rootpage FROM sqlite_master WHERE coalesce(rootpage,0)>0");
  if( pStmt==0 ) goto scrub_abort;
  while( sqlite3_step(pStmt)==SQLITE_ROW ){
    i = (u32)sqlite3_column_int(pStmt, 0);
    scrubBackupBtree(&s, i, 0);
  }
  sqlite3_finalize(pStmt);

Changes to ext/misc/series.c.

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







-
-
+
+

-
+










-
-
-
-






-















-
+

-







**    (1) Allocate the series_vtab object and initialize all fields.
**
**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
**        result set of queries against generate_series will look like.
*/
static int seriesConnect(
  sqlite3 *db,
  void *pUnused,
  int argcUnused, const char *const*argvUnused,
  void *pAux,
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErrUnused
  char **pzErr
){
  sqlite3_vtab *pNew;
  int rc;

/* Column numbers */
#define SERIES_COLUMN_VALUE 0
#define SERIES_COLUMN_START 1
#define SERIES_COLUMN_STOP  2
#define SERIES_COLUMN_STEP  3

  (void)pUnused;
  (void)argcUnused;
  (void)argvUnused;
  (void)pzErrUnused;
  rc = sqlite3_declare_vtab(db,
     "CREATE TABLE x(value,start hidden,stop hidden,step hidden)");
  if( rc==SQLITE_OK ){
    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
    if( pNew==0 ) return SQLITE_NOMEM;
    memset(pNew, 0, sizeof(*pNew));
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  }
  return rc;
}

/*
** This method is the destructor for series_cursor objects.
*/
static int seriesDisconnect(sqlite3_vtab *pVtab){
  sqlite3_free(pVtab);
  return SQLITE_OK;
}

/*
** Constructor for a new series_cursor object.
*/
static int seriesOpen(sqlite3_vtab *pUnused, sqlite3_vtab_cursor **ppCursor){
static int seriesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
  series_cursor *pCur;
  (void)pUnused;
  pCur = sqlite3_malloc( sizeof(*pCur) );
  if( pCur==0 ) return SQLITE_NOMEM;
  memset(pCur, 0, sizeof(*pCur));
  *ppCursor = &pCur->base;
  return SQLITE_OK;
}

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







-
+
-







-
+




-












-
+
-
-
-
-
-







** 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
** in descending order rather than in ascending order.
** 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, 
  int idxNum, const char *idxStrUnused,
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  series_cursor *pCur = (series_cursor *)pVtabCursor;
  int i = 0;
  (void)idxStrUnused;
  if( idxNum & 1 ){
    pCur->mnValue = sqlite3_value_int64(argv[i++]);
  }else{
    pCur->mnValue = 0;
  }
  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 ){
    if( pCur->iStep<1 ) pCur->iStep = 1;
      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 */
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
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







-
+













-







**
**  (1)  start = $value  -- constraint exists
**  (2)  stop = $value   -- constraint exists
**  (4)  step = $value   -- constraint exists
**  (8)  output in descending order
*/
static int seriesBestIndex(
  sqlite3_vtab *tabUnused,
  sqlite3_vtab *tab,
  sqlite3_index_info *pIdxInfo
){
  int i, j;              /* Loop over constraints */
  int idxNum = 0;        /* The query plan bitmask */
  int unusableMask = 0;  /* Mask of unusable constraints */
  int nArg = 0;          /* Number of arguments that seriesFilter() expects */
  int aIdx[3];           /* Constraints on start, stop, and step */
  const struct sqlite3_index_constraint *pConstraint;

  /* This implementation assumes that the start, stop, and step columns
  ** are the last three columns in the virtual table. */
  assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
  assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
  (void)tabUnused;
  aIdx[0] = aIdx[1] = aIdx[2] = -1;
  pConstraint = pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
    int iCol;    /* 0 for start, 1 for stop, 2 for step */
    int iMask;   /* bitmask for those column */
    if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
    iCol = pConstraint->iColumn - SERIES_COLUMN_START;
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386
387
355
356
357
358
359
360
361

362




363
364
365
366
367
368
369







-
+
-
-
-
-







  }
  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 ){
      if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8;
        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;
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
393
394
395
396
397
398
399




400
401
402
403
404
405
406







-
-
-
-







  0,                         /* xUpdate */
  0,                         /* xBegin */
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0                          /* xShadowName */
};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef _WIN32
__declspec(dllexport)
#endif

Changes to ext/misc/sha1.c.

35
36
37
38
39
40
41














42
43
44


45
46
47
48
49
50
51
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







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



+
+







typedef struct SHA1Context SHA1Context;
struct SHA1Context {
  unsigned int state[5];
  unsigned int count[2];
  unsigned char buffer[64];
};


#if __GNUC__ && (defined(__i386__) || defined(__x86_64__))
/*
 * GCC by itself only generates left rotates.  Use right rotates if
 * possible to be kinder to dinky implementations with iterative rotate
 * instructions.
 */
#define SHA_ROT(op, x, k) \
        ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; })
#define rol(x,k) SHA_ROT("roll", x, k)
#define ror(x,k) SHA_ROT("rorl", x, k)

#else
/* Generic C equivalent */
#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
#define rol(x,k) SHA_ROT(x,k,32-(k))
#define ror(x,k) SHA_ROT(x,32-(k),k)
#endif


#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
    |(rol(block[i],8)&0x00FF00FF))
#define blk0be(i) block[i]
#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
    ^block[(i+2)&15]^block[i&15],1))

377
378
379
380
381
382
383
384

385
386

387
388

389
390
391
392
393
393
394
395
396
397
398
399

400


401
402

403

404
405
406
407







-
+
-
-
+

-
+
-




  sqlite3 *db,
  char **pzErrMsg,
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "sha1", 1, 
  rc = sqlite3_create_function(db, "sha1", 1, SQLITE_UTF8, 0,
                       SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
                               0, sha1Func, 0, 0);
                               sha1Func, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "sha1_query", 1, 
    rc = sqlite3_create_function(db, "sha1_query", 1, SQLITE_UTF8, 0,
                                 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
                                 sha1QueryFunc, 0, 0);
  }
  return rc;
}

Changes to ext/misc/shathree.c.

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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>

#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.
620
621
622
623
624
625
626
627
628
629
630



631
632
633
634
635
636
637
638
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);
    if( z ){
      n = (int)strlen(z);
      hash_step_vformat(&cx,"S%d:",n);
      SHA3Update(&cx,(unsigned char*)z,n);
    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: {
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
692
693
694
695
696
697
698

699


700
701

702


703
704
705

706


707
708
709

710


711
712
713
714







-
+
-
-
+

-
+
-
-
+


-
+
-
-
+


-
+
-
-
+



  sqlite3 *db,
  char **pzErrMsg,
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "sha3", 1,
  rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0,
                      SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
                      0, sha3Func, 0, 0);
                               sha3Func, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "sha3", 2,
    rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0,
                      SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
                      0, sha3Func, 0, 0);
                                 sha3Func, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "sha3_query", 1,
    rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0,
                      SQLITE_UTF8 | SQLITE_DIRECTONLY,
                      0, sha3QueryFunc, 0, 0);
                                 sha3QueryFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "sha3_query", 2,
    rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0,
                      SQLITE_UTF8 | SQLITE_DIRECTONLY,
                      0, sha3QueryFunc, 0, 0);
                                 sha3QueryFunc, 0, 0);
  }
  return rc;
}

Changes to ext/misc/spellfix.c.

2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2065
2066
2067
2068
2069
2070
2071

2072
2073
2074
2075
2076
2077
2078







-







    pNew->zDbName = (char*)&pNew[1];
    memcpy(pNew->zDbName, zDbName, nDbName+1);
    pNew->zTableName = sqlite3_mprintf("%s", zTableName);
    pNew->db = db;
    if( pNew->zTableName==0 ){
      rc = SQLITE_NOMEM;
    }else{
      sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
      rc = sqlite3_declare_vtab(db, 
           "CREATE TABLE x(word,rank,distance,langid, "
           "score, matchlen, phonehash HIDDEN, "
           "top HIDDEN, scope HIDDEN, srchcnt HIDDEN, "
           "soundslike HIDDEN, command HIDDEN)"
      );
#define SPELLFIX_COL_WORD            0

Changes to ext/misc/sqlar.c.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26







-







** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
** for working with sqlar archives and used by the shell tool's built-in
** sqlar support.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <zlib.h>
#include <assert.h>

/*
** Implementation of the "sqlar_compress(X)" SQL function.
**
** If the type of X is SQLITE_BLOB, and compressing that blob using
** zlib utility function compress() yields a smaller blob, return the
** compressed blob. Otherwise, return a copy of X.
108
109
110
111
112
113
114
115

116
117
118
119

120
121
122
123
124
107
108
109
110
111
112
113

114

115
116

117

118
119
120
121







-
+
-


-
+
-




  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "sqlar_compress", 1, 
  rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0,
                               SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
                               sqlarCompressFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "sqlar_uncompress", 2,
    rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0,
                                 SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
                                 sqlarUncompressFunc, 0, 0);
  }
  return rc;
}

Changes to ext/misc/stmt.c.

164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
164
165
166
167
168
169
170


171
172
173
174
175
176
177
178







-
-
+







      sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
      break;
    }
    case STMT_COLUMN_BUSY: {
      sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
      break;
    }
    default: {
      assert( i==STMT_COLUMN_MEM );
    case STMT_COLUMN_MEM: {
      i = SQLITE_STMTSTATUS_MEMUSED + 
            STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
      /* Fall thru */
    }
    case STMT_COLUMN_NSCAN:
    case STMT_COLUMN_NSORT:
    case STMT_COLUMN_NAIDX:

Changes to ext/misc/totype.c.

498
499
500
501
502
503
504
505

506
507

508
509

510
511

512
513
514
498
499
500
501
502
503
504

505


506
507

508


509
510
511
512







-
+
-
-
+

-
+
-
-
+



  sqlite3 *db,
  char **pzErrMsg,
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "tointeger", 1,
  rc = sqlite3_create_function(db, "tointeger", 1, SQLITE_UTF8, 0,
        SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0,
        tointegerFunc, 0, 0);
                               tointegerFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "toreal", 1,
    rc = sqlite3_create_function(db, "toreal", 1, SQLITE_UTF8, 0,
        SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0,
        torealFunc, 0, 0);
                                 torealFunc, 0, 0);
  }
  return rc;
}

Deleted ext/misc/uint.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




























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2020-04-14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This SQLite extension implements the UINT collating sequence.
**
** UINT works like BINARY for text, except that embedded strings
** of digits compare in numeric order.
**
**     *   Leading zeros are handled properly, in the sense that
**         they do not mess of the maginitude comparison of embedded
**         strings of digits.  "x00123y" is equal to "x123y".
**
**     *   Only unsigned integers are recognized.  Plus and minus
**         signs are ignored.  Decimal points and exponential notation
**         are ignored.
**
**     *   Embedded integers can be of arbitrary length.  Comparison
**         is *not* limited integers that can be expressed as a
**         64-bit machine integer.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <ctype.h>

/*
** Compare text in lexicographic order, except strings of digits
** compare in numeric order.
*/
static int uintCollFunc(
  void *notUsed,
  int nKey1, const void *pKey1,
  int nKey2, const void *pKey2
){
  const unsigned char *zA = (const unsigned char*)pKey1;
  const unsigned char *zB = (const unsigned char*)pKey2;
  int i=0, j=0, x;
  (void)notUsed;
  while( i<nKey1 && j<nKey2 ){
    x = zA[i] - zB[j];
    if( isdigit(zA[i]) ){
      int k;
      if( !isdigit(zB[j]) ) return x;
      while( i<nKey1 && zA[i]=='0' ){ i++; }
      while( j<nKey2 && zB[j]=='0' ){ j++; }
      k = 0;
      while( i+k<nKey1 && isdigit(zA[i+k])
             && j+k<nKey2 && isdigit(zB[j+k]) ){
        k++;
      }
      if( i+k<nKey1 && isdigit(zA[i+k]) ){
        return +1;
      }else if( j+k<nKey2 && isdigit(zB[j+k]) ){
        return -1;
      }else{
        x = memcmp(zA+i, zB+j, k);
        if( x ) return x;
        i += k;
        j += k;
      }
    }else if( x ){
      return x;
    }else{
      i++;
      j++;
    }
  }
  return (nKey1 - i) - (nKey2 - j);
}

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_uint_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
}

Deleted ext/misc/urifuncs.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

















































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2020-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.
**
******************************************************************************
**
** This SQLite extension implements various SQL functions used to access
** the following SQLite C-language APIs:
**
**         sqlite3_uri_parameter()
**         sqlite3_uri_boolean()
**         sqlite3_uri_int64()
**         sqlite3_uri_key()
**         sqlite3_filename_database()
**         sqlite3_filename_journal()
**         sqlite3_filename_wal()
**         sqlite3_db_filename()
**
** These SQL functions are for testing and demonstration purposes only.
**
**
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>

/*
** SQL function:    sqlite3_db_filename(SCHEMA) 
**
** Return the filename corresponding to SCHEMA.
*/
static void func_db_filename(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  const char *zFile = sqlite3_db_filename(db, zSchema);
  sqlite3_result_text(context, zFile, -1, SQLITE_TRANSIENT);
}

/*
** SQL function:    sqlite3_uri_parameter(SCHEMA,NAME) 
**
** Return the value of the NAME query parameter to the database for SCHEMA
*/
static void func_uri_parameter(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  const char *zName = (const char*)sqlite3_value_text(argv[1]);
  const char *zFile = sqlite3_db_filename(db, zSchema);
  const char *zRes = sqlite3_uri_parameter(zFile, zName);
  sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
}

/*
** SQL function:    sqlite3_uri_boolean(SCHEMA,NAME,DEFAULT) 
**
** Return the boolean value of the NAME query parameter to
** the database for SCHEMA
*/
static void func_uri_boolean(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  const char *zName = (const char*)sqlite3_value_text(argv[1]);
  const char *zFile = sqlite3_db_filename(db, zSchema);
  int iDflt = sqlite3_value_int(argv[2]);
  int iRes = sqlite3_uri_boolean(zFile, zName, iDflt);
  sqlite3_result_int(context, iRes);
}

/*
** SQL function:    sqlite3_uri_key(SCHEMA,N)
**
** Return the name of the Nth query parameter
*/
static void func_uri_key(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  int N = sqlite3_value_int(argv[1]);
  const char *zFile = sqlite3_db_filename(db, zSchema);
  const char *zRes = sqlite3_uri_key(zFile, N);
  sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
}

/*
** SQL function:    sqlite3_uri_int64(SCHEMA,NAME,DEFAULT) 
**
** Return the int64 value of the NAME query parameter to
** the database for SCHEMA
*/
static void func_uri_int64(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  const char *zName = (const char*)sqlite3_value_text(argv[1]);
  const char *zFile = sqlite3_db_filename(db, zSchema);
  sqlite3_int64 iDflt = sqlite3_value_int64(argv[2]);
  sqlite3_int64 iRes = sqlite3_uri_int64(zFile, zName, iDflt);
  sqlite3_result_int64(context, iRes);
}

/*
** SQL function:    sqlite3_filename_database(SCHEMA)
**
** Return the database filename for SCHEMA
*/
static void func_filename_database(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  const char *zFile = sqlite3_db_filename(db, zSchema);
  const char *zRes = zFile ? sqlite3_filename_database(zFile) : 0;
  sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
}

/*
** SQL function:    sqlite3_filename_journal(SCHEMA)
**
** Return the rollback journal filename for SCHEMA
*/
static void func_filename_journal(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  const char *zFile = sqlite3_db_filename(db, zSchema);
  const char *zRes = zFile ? sqlite3_filename_journal(zFile) : 0;
  sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
}

/*
** SQL function:    sqlite3_filename_wal(SCHEMA)
**
** Return the WAL filename for SCHEMA
*/
static void func_filename_wal(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  const char *zFile = sqlite3_db_filename(db, zSchema);
  const char *zRes = zFile ? sqlite3_filename_wal(zFile) : 0;
  sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
}

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_urifuncs_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  static const struct {
    const char *zFuncName;
    int nArg;
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
  } aFunc[] = {
    { "sqlite3_db_filename",       1, func_db_filename       },
    { "sqlite3_uri_parameter",     2, func_uri_parameter     },
    { "sqlite3_uri_boolean",       3, func_uri_boolean       },
    { "sqlite3_uri_int64",         3, func_uri_int64         },
    { "sqlite3_uri_key",           2, func_uri_key           },
    { "sqlite3_filename_database", 1, func_filename_database },
    { "sqlite3_filename_journal",  1, func_filename_journal  },
    { "sqlite3_filename_wal",      1, func_filename_wal      },
  };
  int rc = SQLITE_OK;
  int i;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  for(i=0; rc==SQLITE_OK && i<sizeof(aFunc)/sizeof(aFunc[0]); i++){
    rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg,
                     SQLITE_UTF8, 0,
                     aFunc[i].xFunc, 0, 0);
  }
  return rc;
}

Deleted ext/misc/uuid.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









































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2019-10-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 SQLite extension implements functions that handling RFC-4122 UUIDs
** Three SQL functions are implemented:
**
**     uuid()        - generate a version 4 UUID as a string
**     uuid_str(X)   - convert a UUID X into a well-formed UUID string
**     uuid_blob(X)  - convert a UUID X into a 16-byte blob
**
** The output from uuid() and uuid_str(X) are always well-formed RFC-4122
** UUID strings in this format:
**
**        xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
**
** All of the 'x', 'M', and 'N' values are lower-case hexadecimal digits.
** The M digit indicates the "version".  For uuid()-generated UUIDs, the
** version is always "4" (a random UUID).  The upper three bits of N digit
** are the "variant".  This library only supports variant 1 (indicated
** by values of N between '8' and 'b') as those are overwhelming the most
** common.  Other variants are for legacy compatibility only.
**
** The output of uuid_blob(X) is always a 16-byte blob.  The UUID input
** string is converted in network byte order (big-endian) in accordance
** with RFC-4122 specifications for variant-1 UUIDs.  Note that network
** byte order is *always* used, even if the input self-identifies as a
** variant-2 UUID.
**
** The input X to the uuid_str() and uuid_blob() functions can be either
** a string or a BLOB.  If it is a BLOB it must be exactly 16 bytes in
** length or else a NULL is returned.  If the input is a string it must
** consist of 32 hexadecimal digits, upper or lower case, optionally
** surrounded by {...} and with optional "-" characters interposed in the
** middle.  The flexibility of input is inspired by the PostgreSQL
** implementation of UUID functions that accept in all of the following
** formats:
**
**     A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
**     {a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
**     a0eebc999c0b4ef8bb6d6bb9bd380a11
**     a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
**     {a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}
**
** If any of the above inputs are passed into uuid_str(), the output will
** always be in the canonical RFC-4122 format:
**
**     a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
**
** If the X input string has too few or too many digits or contains
** stray characters other than {, }, or -, then NULL is returned.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <ctype.h>

#if !defined(SQLITE_ASCII) && !defined(SQLITE_EBCDIC)
# define SQLITE_ASCII 1
#endif

/*
** Translate a single byte of Hex into an integer.
** This routine only works if h really is a valid hexadecimal
** character:  0..9a..fA..F
*/
static unsigned char sqlite3UuidHexToInt(int h){
  assert( (h>='0' && h<='9') ||  (h>='a' && h<='f') ||  (h>='A' && h<='F') );
#ifdef SQLITE_ASCII
  h += 9*(1&(h>>6));
#endif
#ifdef SQLITE_EBCDIC
  h += 9*(1&~(h>>4));
#endif
  return (unsigned char)(h & 0xf);
}

/*
** Convert a 16-byte BLOB into a well-formed RFC-4122 UUID.  The output
** buffer zStr should be at least 37 bytes in length.   The output will
** be zero-terminated.
*/
static void sqlite3UuidBlobToStr(
  const unsigned char *aBlob,  /* Input blob */
  unsigned char *zStr          /* Write the answer here */
){
  static const char zDigits[] = "0123456789abcdef";
  int i, k;
  unsigned char x;
  k = 0;
  for(i=0, k=0x550; i<16; i++, k=k>>1){
    if( k&1 ){
      zStr[0] = '-';
      zStr++;
    }
    x = aBlob[i];
    zStr[0] = zDigits[x>>4];
    zStr[1] = zDigits[x&0xf];
    zStr += 2;
  }
  *zStr = 0;
}

/*
** Attempt to parse a zero-terminated input string zStr into a binary
** UUID.  Return 0 on success, or non-zero if the input string is not
** parsable.
*/
static int sqlite3UuidStrToBlob(
  const unsigned char *zStr,   /* Input string */
  unsigned char *aBlob         /* Write results here */
){
  int i;
  if( zStr[0]=='{' ) zStr++;
  for(i=0; i<16; i++){
    if( zStr[0]=='-' ) zStr++;
    if( isxdigit(zStr[0]) && isxdigit(zStr[1]) ){
      aBlob[i] = (sqlite3UuidHexToInt(zStr[0])<<4)
                      + sqlite3UuidHexToInt(zStr[1]);
      zStr += 2;
    }else{
      return 1;
    }
  }
  if( zStr[0]=='}' ) zStr++;
  return zStr[0]!=0;
}

/*
** Render sqlite3_value pIn as a 16-byte UUID blob.  Return a pointer
** to the blob, or NULL if the input is not well-formed.
*/
static const unsigned char *sqlite3UuidInputToBlob(
  sqlite3_value *pIn,     /* Input text */
  unsigned char *pBuf     /* output buffer */
){
  switch( sqlite3_value_type(pIn) ){
    case SQLITE_TEXT: {
      const unsigned char *z = sqlite3_value_text(pIn);
      if( sqlite3UuidStrToBlob(z, pBuf) ) return 0;
      return pBuf;
    }
    case SQLITE_BLOB: {
      int n = sqlite3_value_bytes(pIn);
      return n==16 ? sqlite3_value_blob(pIn) : 0;
    }
    default: {
      return 0;
    }
  }
}

/* Implementation of uuid() */
static void sqlite3UuidFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  unsigned char aBlob[16];
  unsigned char zStr[37];
  (void)argc;
  (void)argv;
  sqlite3_randomness(16, aBlob);
  aBlob[6] = (aBlob[6]&0x0f) + 0x40;
  aBlob[8] = (aBlob[8]&0x3f) + 0x80;
  sqlite3UuidBlobToStr(aBlob, zStr);
  sqlite3_result_text(context, (char*)zStr, 36, SQLITE_TRANSIENT);
}

/* Implementation of uuid_str() */
static void sqlite3UuidStrFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  unsigned char aBlob[16];
  unsigned char zStr[37];
  const unsigned char *pBlob;
  (void)argc;
  pBlob = sqlite3UuidInputToBlob(argv[0], aBlob);
  if( pBlob==0 ) return;
  sqlite3UuidBlobToStr(pBlob, zStr);
  sqlite3_result_text(context, (char*)zStr, 36, SQLITE_TRANSIENT);
}

/* Implementation of uuid_blob() */
static void sqlite3UuidBlobFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  unsigned char aBlob[16];
  const unsigned char *pBlob;
  (void)argc;
  pBlob = sqlite3UuidInputToBlob(argv[0], aBlob);
  if( pBlob==0 ) return;
  sqlite3_result_blob(context, pBlob, 16, SQLITE_TRANSIENT);
}

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_uuid_init(
  sqlite3 *db,
  char **pzErrMsg,
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
                               sqlite3UuidFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "uuid_str", 1, 
                       SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
                       0, sqlite3UuidStrFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "uuid_blob", 1,
                       SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
                       0, sqlite3UuidBlobFunc, 0, 0);
  }
  return rc;
}

Changes to ext/misc/vfsstat.c.

807
808
809
810
811
812
813
814

815
816
817
818
819
807
808
809
810
811
812
813

814
815
816
817
818
819







-
+





  SQLITE_EXTENSION_INIT2(pApi);
  vstat_vfs.pVfs = sqlite3_vfs_find(0);
  vstat_vfs.base.szOsFile = sizeof(VStatFile) + vstat_vfs.pVfs->szOsFile;
  rc = sqlite3_vfs_register(&vstat_vfs.base, 1);
  if( rc==SQLITE_OK ){
    rc = vstatRegister(db, pzErrMsg, pApi);
    if( rc==SQLITE_OK ){
      rc = sqlite3_auto_extension((void(*)(void))vstatRegister);
      rc = sqlite3_auto_extension(vstatRegister);
    }
  }
  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
  return rc;
}

Changes to ext/misc/wholenumber.c.

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
46
47
48
49
50
51
52

53
54
55
56
57
58
59







-







  sqlite3_vtab **ppVtab,
  char **pzErr
){
  sqlite3_vtab *pNew;
  pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
  if( pNew==0 ) return SQLITE_NOMEM;
  sqlite3_declare_vtab(db, "CREATE TABLE x(value)");
  sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  memset(pNew, 0, sizeof(*pNew));
  return SQLITE_OK;
}
/* Note that for this virtual table, the xCreate and xConnect
** methods are identical. */

static int wholenumberDisconnect(sqlite3_vtab *pVtab){
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229







-
+







  }
  if( pIdxInfo->nOrderBy==1
   && pIdxInfo->aOrderBy[0].desc==0
  ){
    pIdxInfo->orderByConsumed = 1;
  }
  if( (idxNum & 12)==0 ){
    pIdxInfo->estimatedCost = 1e99;
    pIdxInfo->estimatedCost = (double)100000000;
  }else if( (idxNum & 3)==0 ){
    pIdxInfo->estimatedCost = (double)5;
  }else{
    pIdxInfo->estimatedCost = (double)1;
  }
  return SQLITE_OK;
}

Changes to ext/misc/zipfile.c.

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

372
373
374
375
376
377
378







-







    pNew->aBuffer = (u8*)&pNew[1];
    if( zFile ){
      pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
      memcpy(pNew->zFile, zFile, nFile);
      zipfileDequote(pNew->zFile);
    }
  }
  sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
  *ppVtab = (sqlite3_vtab*)pNew;
  return rc;
}

/*
** Free the ZipfileEntry structure indicated by the only argument.
*/
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534








535
536
537
538
539
540
541
542
518
519
520
521
522
523
524









525
526
527
528
529
530
531
532

533
534
535
536
537
538
539







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







}

static int zipfileAppendData(
  ZipfileTab *pTab,
  const u8 *aWrite,
  int nWrite
){
  if( nWrite>0 ){
    size_t n = nWrite;
    fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
    n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
    if( (int)n!=nWrite ){
      pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
      return SQLITE_ERROR;
    }
    pTab->szCurrent += nWrite;
  size_t n;
  fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
  n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
  if( (int)n!=nWrite ){
    pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
    return SQLITE_ERROR;
  }
  pTab->szCurrent += nWrite;
  }
  return SQLITE_OK;
}

/*
** Read and return a 16-bit little-endian unsigned integer from buffer aBuf.
*/
static u16 zipfileGetU16(const u8 *aBuf){
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
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







-
-
+
-

-
+
-
-
-
-

-





+
+
+
+


+
+

+







** case.
*/
static int zipfileDeflate(
  const u8 *aIn, int nIn,         /* Input */
  u8 **ppOut, int *pnOut,         /* Output */
  char **pzErr                    /* OUT: Error message */
){
  int rc = SQLITE_OK;
  sqlite3_int64 nAlloc;
  sqlite3_int64 nAlloc = compressBound(nIn);
  z_stream str;
  u8 *aOut;

  int rc = SQLITE_OK;
  memset(&str, 0, sizeof(str));
  str.next_in = (Bytef*)aIn;
  str.avail_in = nIn;
  deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);

  nAlloc = deflateBound(&str, nIn);
  aOut = (u8*)sqlite3_malloc64(nAlloc);
  if( aOut==0 ){
    rc = SQLITE_NOMEM;
  }else{
    int res;
    z_stream str;
    memset(&str, 0, sizeof(str));
    str.next_in = (Bytef*)aIn;
    str.avail_in = nIn;
    str.next_out = aOut;
    str.avail_out = nAlloc;

    deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
    res = deflate(&str, Z_FINISH);

    if( res==Z_STREAM_END ){
      *ppOut = aOut;
      *pnOut = (int)str.total_out;
    }else{
      sqlite3_free(aOut);
      *pzErr = sqlite3_mprintf("zipfile: deflate() error");
      rc = SQLITE_ERROR;
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317

1318
1319
1320
1321
1322
1323
1324
1304
1305
1306
1307
1308
1309
1310

1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321







-



+







    if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
    if( pCons->usable==0 ){
      unusable = 1;
    }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
      idx = i;
    }
  }
  pIdxInfo->estimatedCost = 1000.0;
  if( idx>=0 ){
    pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
    pIdxInfo->aConstraintUsage[idx].omit = 1;
    pIdxInfo->estimatedCost = 1000.0;
    pIdxInfo->idxNum = 1;
  }else if( unusable ){
    return SQLITE_CONSTRAINT;
  }
  return SQLITE_OK;
}

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







-
-
+
+









-
-
-
-








/*
** Both (const char*) arguments point to nul-terminated strings. Argument
** nB is the value of strlen(zB). This function returns 0 if the strings are
** identical, ignoring any trailing '/' character in either path.  */
static int zipfileComparePath(const char *zA, const char *zB, int nB){
  int nA = (int)strlen(zA);
  if( nA>0 && zA[nA-1]=='/' ) nA--;
  if( nB>0 && zB[nB-1]=='/' ) nB--;
  if( zA[nA-1]=='/' ) nA--;
  if( zB[nB-1]=='/' ) nB--;
  if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
  return 1;
}

static int zipfileBegin(sqlite3_vtab *pVtab){
  ZipfileTab *pTab = (ZipfileTab*)pVtab;
  int rc = SQLITE_OK;

  assert( pTab->pWriteFd==0 );
  if( pTab->zFile==0 || pTab->zFile[0]==0 ){
    pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
    return SQLITE_ERROR;
  }

  /* Open a write fd on the file. Also load the entire central directory
  ** structure into memory. During the transaction any new file data is 
  ** appended to the archive file, but the central directory is accumulated
  ** in main-memory until the transaction is committed.  */
  pTab->pWriteFd = fopen(pTab->zFile, "ab+");
  if( pTab->pWriteFd==0 ){
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
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







-









-
+

+

-
-
-
+
-
-
-








    if( rc==SQLITE_OK ){
      rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
    }

    if( rc==SQLITE_OK ){
      zPath = (const char*)sqlite3_value_text(apVal[2]);
      if( zPath==0 ) zPath = "";
      nPath = (int)strlen(zPath);
      mTime = zipfileGetTime(apVal[4]);
    }

    if( rc==SQLITE_OK && bIsDir ){
      /* For a directory, check that the last character in the path is a
      ** '/'. This appears to be required for compatibility with info-zip
      ** (the unzip command on unix). It does not create directories
      ** otherwise.  */
      if( nPath<=0 || zPath[nPath-1]!='/' ){
      if( zPath[nPath-1]!='/' ){
        zFree = sqlite3_mprintf("%s/", zPath);
        if( zFree==0 ){ rc = SQLITE_NOMEM; }
        zPath = (const char*)zFree;
        if( zFree==0 ){
          rc = SQLITE_NOMEM;
          nPath = 0;
        nPath++;
        }else{
          nPath = (int)strlen(zPath);
        }
      }
    }

    /* Check that we're not inserting a duplicate entry -OR- updating an
    ** entry with a path, thereby making it into a duplicate. */
    if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
      ZipfileEntry *p;
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
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







-
+





-
+

+




-







  /* Decode the "mtime" argument. */
  e.mUnixTime = zipfileGetTime(pMtime);

  /* If this is a directory entry, ensure that there is exactly one '/'
  ** at the end of the path. Or, if this is not a directory and the path
  ** ends in '/' it is an error. */
  if( bIsDir==0 ){
    if( nName>0 && zName[nName-1]=='/' ){
    if( zName[nName-1]=='/' ){
      zErr = sqlite3_mprintf("non-directory name must not end with /");
      rc = SQLITE_ERROR;
      goto zipfile_step_out;
    }
  }else{
    if( nName==0 || zName[nName-1]!='/' ){
    if( zName[nName-1]!='/' ){
      zName = zFree = sqlite3_mprintf("%s/", zName);
      nName++;
      if( zName==0 ){
        rc = SQLITE_NOMEM;
        goto zipfile_step_out;
      }
      nName = (int)strlen(zName);
    }else{
      while( nName>1 && zName[nName-2]=='/' ) nName--;
    }
  }

  /* Assemble the ZipfileEntry object for the new zip archive entry */
  e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;

Changes to ext/rbu/rbu.c.

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







186
187
188







-
-
-
-
-
-
-



      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/rbu_common.tcl.

85
86
87
88
89
90
91
92
93


94
95

96
97
98
99
100
101

102
103
104
105
106
107
108
85
86
87
88
89
90
91


92
93
94

95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
-
+
+

-
+





-
+







  }
  set rc
}

proc do_rbu_vacuum_test {tn step {statedb state.db}} {
  forcedelete $statedb
  if {$statedb=="" && $step==1} breakpoint
  uplevel [list do_test $tn.1 [string map [list %state% $statedb %step% $step] {
    if {%step%==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
  uplevel [list do_test $tn.1 [string map [list %state% $statedb] {
    if {$step==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
    while 1 {
      if {%step%==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
      if {$step==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
      set state [rbu state]
      check_prestep_state test.db $state
      set rc [rbu step]
      check_poststep_state $rc test.db $state
      if {$rc!="SQLITE_OK"} break
      if {%step%==1} { rbu close }
      if {$step==1} { rbu close }
    }
    rbu close
  }] {SQLITE_DONE}]

  uplevel [list do_execsql_test $tn.2 {
    PRAGMA integrity_check
  } ok]

Changes to ext/rbu/rbudiff.test.

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








266
267
268
269
270
271
272







-
-
-
-
-
-
-
-







      INSERT INTO t1 VALUES('a b c');
    }

    3 {
      creAte    virTUal
tablE t1 USING FTs5(c);
      INSERT INTO t1 VALUES('a b c');
      INSERT INTO t1 VALUES('a b c');
    } {
      DELETE FROM t1 WHERE rowid = 1;
      INSERT INTO t1 VALUES('a b c');
    }
    4 {
      creAte virTUal tablE	t1	USING FTs5(c);
      INSERT INTO t1 VALUES('a b c');
      INSERT INTO t1 VALUES('a b c');
    } {
      DELETE FROM t1 WHERE rowid = 1;
      INSERT INTO t1 VALUES('a b c');
    }

  } {

Deleted ext/rbu/rbuexpr.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





























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2014 August 30
#
# 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.
#
#***********************************************************************
#

source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbuexpr

db close
sqlite3_shutdown
sqlite3_config_uri 1

sqlite3 db test.db

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c PRIMARY KEY);
  CREATE INDEX i1 ON t1(a, null, b+1);
  CREATE INDEX i2 ON t1(a+1, b+1, c+1);

  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
  INSERT INTO t1 VALUES(7, 8, 9);
  INSERT INTO t1 VALUES(10, 11, 12);

  PRAGMA integrity_check;
} {ok}

forcedelete rbu.db
sqlite3 db2 rbu.db
do_execsql_test -db db2 1.1 {
  CREATE TABLE data_t1(a, b, c, rbu_control);
  INSERT INTO data_t1 VALUES(13, 14, 15, 0);
  INSERT INTO data_t1 VALUES(NULL, NULL, 6, 1);
  INSERT INTO data_t1 VALUES(NULL, 'three', 3, '.x.');
}
db2 close
db close

do_test 1.2 {
  run_rbu test.db rbu.db
} {SQLITE_DONE}

sqlite3 db test.db

do_execsql_test 1.3 {
  SELECT * FROM t1 WHERE a=4;
}

integrity_check 1.4

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t1(c1, c2, c3, i INTEGER PRIMARY KEY);
  INSERT INTO t1 VALUES('one', 'one', 'one', 1);
  INSERT INTO t1 VALUES('two', 'two', 'two', 2);
  INSERT INTO t1 VALUES('three', 'three', 'three', 3);
  INSERT INTO t1 VALUES('four', 'four', 'four', 4);

  CREATE INDEX i1 ON t1( substr(c1, 1, 2) );
  CREATE INDEX i2 ON t1( c1 || c2 || c3 );
  CREATE INDEX i3 ON t1( length(c1) + length(c2) - 1, c3||i );
}

forcedelete rbu.db
sqlite3 db2 rbu.db
do_execsql_test -db db2 2.1 {
  CREATE TABLE data_t1(c1, c2, c3, i, rbu_control);
  INSERT INTO data_t1 VALUES(NULL, NULL, NULL, 2, 1);
  INSERT INTO data_t1 VALUES('thirty', NULL, NULL, 3, 'xx..');
  INSERT INTO data_t1 VALUES('five', 'five', 'five', 5, 0);
}
db2 close

db close

do_test 2.2 {
  run_rbu test.db rbu.db
} {SQLITE_DONE}

sqlite3 db test.db
integrity_check 2.3

finish_test

Changes to ext/rbu/rbufault2.test.

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
48
49
50
51
52
53
54









55
56
57







-
-
-
-
-
-
-
-
-



      {1 SQLITE_CONSTRAINT} \
      {1 SQLITE_NOMEM} \
      {1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}} \
      {1 {SQLITE_NOMEM - out of memory}} 
}


sqlite3rbu_create_vfs -default rbu ""
sqlite3 db test.db
set ::vfsname [file_control_vfsname db]
do_faultsim_test 2 -faults oom* -prep {
} -body {
  file_control_vfsname db
} 
db close
sqlite3rbu_destroy_vfs rbu


finish_test

Changes to ext/rbu/rbufault3.test.

79
80
81
82
83
84
85

86
87
88
89
90
91
92

93
94
95
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97







+







+



  sqlite3rbu_vacuum rbu test.db test.db2
  rbu step
  rbu close
  faultsim_save_and_close

  do_faultsim_test 3 -faults $fault -prep {
    faultsim_restore_and_reopen
    forcedelete test.db2
  } -body {
    sqlite3rbu_vacuum rbu test.db test.db2
    rbu step
    rbu close
  } -test {
    eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
  }

}

finish_test

Deleted ext/rbu/rbumisc.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




















































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2014 August 30
#
# 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.
#
#***********************************************************************
#

source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbumisc

db close
sqlite3_shutdown
sqlite3_config_uri 1
reset_db

proc populate_rbu_db {} {
  forcedelete rbu.db
  sqlite3 rbu rbu.db
  rbu eval {
    CREATE TABLE data_x1(a, b, c, rbu_control);
    INSERT INTO data_x1 VALUES(1, 1, 1, 0);
    INSERT INTO data_x1 VALUES(2, 2, 2, 0);

    CREATE TABLE dat(a, b, c, rbu_control);
    CREATE TABLE "data x1"(a, b, c, rbu_control);
    CREATE TABLE datax1(a, b, c, rbu_control);
    CREATE TABLE data_(a, b, c, rbu_control);

    INSERT INTO "data x1" VALUES(3, 3, 3, 0);
    INSERT INTO datax1 VALUES(3, 3, 3, 0);
    INSERT INTO data_ VALUES(3, 3, 3, 0);
    INSERT INTO dat VALUES(3, 3, 3, 0);
  }
  rbu close
}

#-------------------------------------------------------------------------
# Ensure that RBU is not confused by oddly named tables in an RBU 
# database.
#
do_execsql_test 1.0 {
  CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
do_test 1.1 {
  populate_rbu_db
} {}

do_test 1.2 {
  step_rbu test.db rbu.db
  db eval { SELECT * FROM x1 }
} {1 1 1 2 2 2}

do_test 1.3 {
  db eval { DELETE FROM x1 }
  sqlite3 rbu rbu.db
  rbu eval { DELETE FROM rbu_state }
  rbu close
  step_rbu test.db rbu.db
  db eval { SELECT * FROM x1 }
} {1 1 1 2 2 2}

do_test 1.4 {
  db eval { DELETE FROM x1 }
  populate_rbu_db

  sqlite3rbu rbu test.db rbu.db
  rbu step
  rbu step
  rbu close

  forcecopy test.db-oal test.db-wal
  sqlite3rbu rbu test.db rbu.db
  rbu step
  list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}

#-------------------------------------------------------------------------
# Test the effect of a wal file appearing after the target database has
# been opened, but before it has been locked.
#
catch { db close }
testvfs tvfs -default 1

for {set N 1} {$N < 10} {incr N} {
  reset_db
  populate_rbu_db
  do_execsql_test 2.$N.0 {
    CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
  }
  
  set nAccessCnt 0
  do_test 2.$N.1 {
    sqlite3rbu rbu test.db rbu.db
    rbu step
    rbu step
    rbu close
  } {SQLITE_OK}
  
  tvfs script xAccess
  tvfs filter xAccess
  set nAccessCnt 0
  proc xAccess {method file args} {
    global nAccessCnt
    if {[file tail $file]=="test.db-wal"} {
      incr nAccessCnt -1
      if {$nAccessCnt==0} {
        set fd [open test.db-wal w]
        puts -nonewline $fd [string repeat 0 2000]
        close $fd
      }
    }
    return SQLITE_OK
  }

  foreach r {
     {1 {SQLITE_ERROR - cannot update wal mode database}}
     {0 SQLITE_OK}
     {1 {SQLITE_CANTOPEN - unable to open database file}}
  } {
    set RES($r) 1
  }
  do_test 2.$N.2 {
    set ::nAccessCnt $N
    set res [list [catch {
      sqlite3rbu rbu test.db rbu.db
      rbu step
      rbu close
    } msg ] $msg]
    set RES($res)
  } {1}
  catch {rbu close}
}
catch {db close}
catch {tvfs delete}

#-------------------------------------------------------------------------
testvfs tvfs -default 1
reset_db
populate_rbu_db
do_execsql_test 3.0 {
  CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
  
tvfs script xFileControl
tvfs filter xFileControl

proc xFileControl {method file verb args} {
  if {$verb=="ZIPVFS" && [info exists ::zipvfs_filecontrol]} {
    return $::zipvfs_filecontrol 
  }
  return "SQLITE_NOTFOUND"
}

breakpoint
foreach {tn ret err} {
  1 SQLITE_OK           0
  2 SQLITE_ERROR        1
  3 SQLITE_NOTFOUND     0
  4 SQLITE_OMIT         1
} {
  set ::zipvfs_filecontrol $ret
  do_test 3.$tn.1 {
    catch {
      sqlite3rbu rbu test.db rbu.db
      rbu step
      rbu close
    }
  } $err
}
catch {db close}
catch {tvfs delete}

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

finish_test

Changes to ext/rbu/rbupartial.test.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
36
37
38
39
40
41
42









43
44
45
46
47
48
49







-
-
-
-
-
-
-
-
-







    CREATE INDEX i1b3 ON t1(%B%) WHERE %C%>=5;

    CREATE INDEX i1c  ON t1(%C%);
    CREATE INDEX i1c2 ON t1(%C%) WHERE %C% IS NULL;
    CREATE INDEX i1c3 ON t1(%C%) WHERE %C% IS NOT NULL;

    CREATE INDEX i1c4 ON t1(%C%) WHERE %D% < 'd';
    CREATE INDEX i1c5 ON t1(
        %C%                   -- for (c = ... expressions
    ) WHERE %D% < 'd';
    CREATE INDEX i1c6 ON t1(
        %C% /* Again, for (c=... expr */, %D%
    ) WHERE %D% < 'd';

    CREATE INDEX i1c7 ON t1(
        %C% /* As before, for (c=... "expr */) WHERE %D% < 'd';
  }

  do_execsql_test $tn.1.1 {
    INSERT INTO t1 VALUES(0, NULL, NULL, 'a');
    INSERT INTO t1 VALUES(1, 2, 3, 'b');
    INSERT INTO t1 VALUES(4, 5, 6, 'c');
    INSERT INTO t1 VALUES(7, 8, 9, 'd');
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
76
77
78
79
80
81
82




83
84
85
86







-
-
-
-




    SELECT * FROM t1 ORDER BY %A%;
  } {
    1 10 {} b   7 8 4 d   10 11 12 e   13 14 {} f
  }

  set step 0
  do_rbu_vacuum_test $tn.1.5 0

  do_test $tn.1.6 {
    execsql { PRAGMA integrity_check }
  } {ok}
  }]
}

finish_test

Changes to ext/rbu/rbuprogress.test.

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
410
411
412
413
414
415
416
































417
418







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


      set R(nopk) $r1
      set R(vtab) $r2
      do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn)
    }
  }
}

#-------------------------------------------------------------------------
# Test that sqlite3_bp_progress() works with an RBU vacuum if there
# is an rbu_count table in the db being vacuumed.
#
reset_db
do_execsql_test 6.0 {
  CREATE TABLE t1(a, b, c);
  CREATE INDEX i1 ON t1(a);
  CREATE INDEX i2 ON t1(b);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
  )
  INSERT INTO t1 SELECT i, i, i FROM s;
  CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
  INSERT INTO rbu_count VALUES('t1', (SELECT count(*) FROM t1));
  INSERT INTO rbu_count VALUES('rbu_count', 2);
}

forcedelete state.db
do_test 6.1 {
  set maxA 0
  set maxB 0
  sqlite3rbu_vacuum rbu test.db state.db
  while {[rbu step]=="SQLITE_OK"} {
    foreach {a b} [rbu bp_progress] {
      if {$a > $maxA} { set maxA $a }
      if {$b > $maxB} { set maxB $b }
    }
  }
  list [rbu close] $maxA $maxB
} {SQLITE_DONE 10000 10000}


finish_test

Changes to ext/rbu/rbutemplimit.test.

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
61
62
63
64
65
66
67

68
69
70
71
72
73
74







-







}

proc step_rbu_cachesize {target rbu stepsize cachesize temp_limit} {
  set res ""
  while 1 {
    sqlite3rbu rbu $target $rbu
    rbu temp_size_limit $temp_limit
    if { [rbu temp_size_limit -1]!=$temp_limit } { error "round trip problem!" }
    sqlite3_exec_nr [rbu db 1] "PRAGMA cache_size = $cachesize"
    for {set i 0} {$i < $stepsize} {incr i} {
      set rc [rbu step]
      set ::A([rbu temp_size]) 1
      if {$rc!="SQLITE_OK"} break
    }
    set res [list [catch {rbu close} msg] $msg]

Deleted ext/rbu/rbuvacuum4.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




















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 Jan 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 for the RBU module. More specifically, it
# contains tests to ensure that the sqlite3rbu_vacuum() API works as
# expected.
#

source [file join [file dirname [info script]] rbu_common.tcl]
set testprefix rbuvacuum4

set step 1

do_execsql_test 1.0 {
  CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID;
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
  INSERT INTO t1 VALUES(7, 8, 9);
}
do_rbu_vacuum_test 1.1 1

#-------------------------------------------------------------------------
reset_db

do_execsql_test 2.0 {
  CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
  INSERT INTO t1 VALUES(7, 8, 9);
}
do_rbu_vacuum_test 2.1 1
do_execsql_test 2.2 {
  SELECT * FROM t1;
} {1 2 3 4 5 6 7 8 9}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 3.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  CREATE INDEX i1 oN t1(b, c);
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
  INSERT INTO t1 VALUES(7, 8, 9);

  CREATE TABLE t2(a, b, c INTEGER, PRIMARY KEY(c));
  CREATE INDEX i2 oN t2(b, a);
  INSERT INTO t2 VALUES('a', 'b', -1);
  INSERT INTO t2 VALUES('c', 'd', -2);
  INSERT INTO t2 VALUES('e', 'f', -3);
}

do_rbu_vacuum_test 3.1 1

do_execsql_test 3.2 {
  SELECT * FROM t1;
  SELECT * FROM t2;
} {1 2 3 4 5 6 7 8 9 e f -3 c d -2 a b -1}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE TABLE x1(a, b, c, d, PRIMARY KEY(c, b)) WITHOUT ROWID;
  INSERT INTO x1 VALUES(1, 1, 1, 1);
  INSERT INTO x1 VALUES(1, 1, 2, 1);
  INSERT INTO x1 VALUES(1, 2, 2, 1);

  INSERT INTO x1 VALUES(NULL, 2, 3, NULL);
  INSERT INTO x1 VALUES(NULL, 2, 4, NULL);
  INSERT INTO x1 VALUES(NULL, 2, 5, NULL);

  CREATE INDEX x1ad ON x1(d, a);
  CREATE INDEX x1null ON x1(d, a) WHERE d>15;
}

do_rbu_vacuum_test 4.1.1 1

do_execsql_test 4.2 {
  SELECT count(*) fROM x1
} 6

do_rbu_vacuum_test 4.1.2 0

#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  CREATE TABLE "a b c"(a, "b b" PRIMARY KEY, "c c");
  CREATE INDEX abc1 ON "a b c"(a, "c c");

  INSERT INTO "a b c" VALUES(NULL, 'a', NULL);
  INSERT INTO "a b c" VALUES(NULL, 'b', NULL);
  INSERT INTO "a b c" VALUES(NULL, 'c', NULL);

  INSERT INTO "a b c" VALUES(1, 2, 3);
  INSERT INTO "a b c" VALUES(3, 9, 1);
  INSERT INTO "a b c" VALUES('aaa', 'bbb', 'ccc');

  CREATE INDEX abc2 ON "a b c"("c c" DESC, a);

  CREATE TABLE x(a);
  INSERT INTO x VALUES('a'), ('b'), ('d');
  CREATE UNIQUE INDEX y ON x(a);
}

do_rbu_vacuum_test 5.1 1

finish_test

Changes to ext/rbu/sqlite3rbu.c.

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
178
179
180
181
182
183
184

185
186
187
188
189
190
191







-








#define RBU_CREATE_STATE \
  "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)"

typedef struct RbuFrame RbuFrame;
typedef struct RbuObjIter RbuObjIter;
typedef struct RbuState RbuState;
typedef struct RbuSpan RbuSpan;
typedef struct rbu_vfs rbu_vfs;
typedef struct rbu_file rbu_file;
typedef struct RbuUpdateStmt RbuUpdateStmt;

#if !defined(SQLITE_AMALGAMATION)
typedef unsigned int u32;
typedef unsigned short u16;
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
222
223
224
225
226
227
228





229
230
231
232
233
234
235







-
-
-
-
-








struct RbuUpdateStmt {
  char *zMask;                    /* Copy of update mask used with pUpdate */
  sqlite3_stmt *pUpdate;          /* Last update statement (or NULL) */
  RbuUpdateStmt *pNext;
};

struct RbuSpan {
  const char *zSpan;
  int nSpan;
};

/*
** An iterator of this type is used to iterate through all objects in
** the target database that require updating. For each such table, the
** iterator visits, in order:
**
**     * the table itself, 
**     * each index of the table (zero or more points to visit), and
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
271
272
273
274
275
276
277



278
279
280
281
282
283
284







-
-
-








  /* Statements created by rbuObjIterPrepareAll() */
  int nCol;                       /* Number of columns in current object */
  sqlite3_stmt *pSelect;          /* Source data */
  sqlite3_stmt *pInsert;          /* Statement for INSERT operations */
  sqlite3_stmt *pDelete;          /* Statement for DELETE ops */
  sqlite3_stmt *pTmpInsert;       /* Insert into rbu_tmp_$zDataTbl */
  int nIdxCol;
  RbuSpan *aIdxCol;
  char *zIdxSql;

  /* Last UPDATE used (for PK b-tree updates only), or NULL. */
  RbuUpdateStmt *pRbuUpdate;
};

/*
** Values for RbuObjIter.eType
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
805
806
807
808
809
810
811


812
813
814
815
816
817
818



819
820
821
822
823
824
825







-
-







-
-
-







  pUp = pIter->pRbuUpdate;
  while( pUp ){
    RbuUpdateStmt *pTmp = pUp->pNext;
    sqlite3_finalize(pUp->pUpdate);
    sqlite3_free(pUp);
    pUp = pTmp;
  }
  sqlite3_free(pIter->aIdxCol);
  sqlite3_free(pIter->zIdxSql);
  
  pIter->pSelect = 0;
  pIter->pInsert = 0;
  pIter->pDelete = 0;
  pIter->pRbuUpdate = 0;
  pIter->pTmpInsert = 0;
  pIter->nCol = 0;
  pIter->nIdxCol = 0;
  pIter->aIdxCol = 0;
  pIter->zIdxSql = 0;
}

/*
** Clean up any resources allocated as part of the iterator object passed
** as the only argument.
*/
static void rbuObjIterFinalize(RbuObjIter *pIter){
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
926
927
928
929
930
931
932

933
934
935
936
937
938
939







-







  sqlite3rbu *p = sqlite3_user_data(pCtx);
  const char *zIn;
  assert( argc==1 || argc==2 );

  zIn = (const char*)sqlite3_value_text(argv[0]);
  if( zIn ){
    if( rbuIsVacuum(p) ){
      assert( argc==2 || argc==1 );
      if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
        sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
      }
    }else{
      if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
        int i;
        for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
971
972
973
974
975
976
977
978

979
980
981
982
983
984
985
986
987

988
989
990
991
992
993
994
956
957
958
959
960
961
962

963
964
965
966
967
968
969
970
971

972
973
974
975
976
977
978
979







-
+








-
+







static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){
  int rc;
  memset(pIter, 0, sizeof(RbuObjIter));

  rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, 
    sqlite3_mprintf(
      "SELECT rbu_target_name(name, type='view') AS target, name "
      "FROM sqlite_schema "
      "FROM sqlite_master "
      "WHERE type IN ('table', 'view') AND target IS NOT NULL "
      " %s "
      "ORDER BY name"
  , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : ""));

  if( rc==SQLITE_OK ){
    rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
        "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
        "  FROM main.sqlite_schema "
        "  FROM main.sqlite_master "
        "  WHERE type='index' AND tbl_name = ?"
    );
  }

  pIter->bCleanup = 1;
  p->rc = rc;
  return rbuObjIterNext(p, pIter);
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113








1114
1115
1116
1117
1118
1119
1120
1121
1084
1085
1086
1087
1088
1089
1090








1091
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
1103
1104
1105







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







** If an OOM condition is encountered when attempting to allocate memory,
** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise,
** if the allocation succeeds, (*pRc) is left unchanged.
*/
static char *rbuStrndup(const char *zStr, int *pRc){
  char *zRet = 0;

  if( *pRc==SQLITE_OK ){
    if( zStr ){
      size_t nCopy = strlen(zStr) + 1;
      zRet = (char*)sqlite3_malloc64(nCopy);
      if( zRet ){
        memcpy(zRet, zStr, nCopy);
      }else{
        *pRc = SQLITE_NOMEM;
  assert( *pRc==SQLITE_OK );
  if( zStr ){
    size_t nCopy = strlen(zStr) + 1;
    zRet = (char*)sqlite3_malloc64(nCopy);
    if( zRet ){
      memcpy(zRet, zStr, nCopy);
    }else{
      *pRc = SQLITE_NOMEM;
      }
    }
  }

  return zRet;
}

/*
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
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







-
+




-
+



















-
+

-
+











-
+







**   (i.e. unless *peType is set to 3), then *piPk is set to zero. Or,
**   if the table does have an external primary key index, then *piPk
**   is set to the root page number of the primary key index before
**   returning.
**
** ALGORITHM:
**
**   if( no entry exists in sqlite_schema ){
**   if( no entry exists in sqlite_master ){
**     return RBU_PK_NOTABLE
**   }else if( sql for the entry starts with "CREATE VIRTUAL" ){
**     return RBU_PK_VTAB
**   }else if( "PRAGMA index_list()" for the table contains a "pk" index ){
**     if( the index that is the pk exists in sqlite_schema ){
**     if( the index that is the pk exists in sqlite_master ){
**       *piPK = rootpage of that index.
**       return RBU_PK_EXTERNAL
**     }else{
**       return RBU_PK_WITHOUT_ROWID
**     }
**   }else if( "PRAGMA table_info()" lists one or more "pk" columns ){
**     return RBU_PK_IPK
**   }else{
**     return RBU_PK_NONE
**   }
*/
static void rbuTableType(
  sqlite3rbu *p,
  const char *zTab,
  int *peType,
  int *piTnum,
  int *piPk
){
  /*
  ** 0) SELECT count(*) FROM sqlite_schema where name=%Q AND IsVirtual(%Q)
  ** 0) SELECT count(*) FROM sqlite_master where name=%Q AND IsVirtual(%Q)
  ** 1) PRAGMA index_list = ?
  ** 2) SELECT count(*) FROM sqlite_schema where name=%Q 
  ** 2) SELECT count(*) FROM sqlite_master where name=%Q 
  ** 3) PRAGMA table_info = ?
  */
  sqlite3_stmt *aStmt[4] = {0, 0, 0, 0};

  *peType = RBU_PK_NOTABLE;
  *piPk = 0;

  assert( p->rc==SQLITE_OK );
  p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, 
    sqlite3_mprintf(
          "SELECT (sql LIKE 'create virtual%%'), rootpage"
          "  FROM sqlite_schema"
          "  FROM sqlite_master"
          " WHERE name=%Q", zTab
  ));
  if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){
    /* Either an error, or no such table. */
    goto rbuTableType_end;
  }
  if( sqlite3_column_int(aStmt[0], 0) ){
1214
1215
1216
1217
1218
1219
1220
1221

1222
1223
1224
1225
1226
1227
1228
1198
1199
1200
1201
1202
1203
1204

1205
1206
1207
1208
1209
1210
1211
1212







-
+







  if( p->rc ) goto rbuTableType_end;
  while( sqlite3_step(aStmt[1])==SQLITE_ROW ){
    const u8 *zOrig = sqlite3_column_text(aStmt[1], 3);
    const u8 *zIdx = sqlite3_column_text(aStmt[1], 1);
    if( zOrig && zIdx && zOrig[0]=='p' ){
      p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg, 
          sqlite3_mprintf(
            "SELECT rootpage FROM sqlite_schema WHERE name = %Q", zIdx
            "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx
      ));
      if( p->rc==SQLITE_OK ){
        if( sqlite3_step(aStmt[2])==SQLITE_ROW ){
          *piPk = sqlite3_column_int(aStmt[2], 0);
          *peType = RBU_PK_EXTERNAL;
        }else{
          *peType = RBU_PK_WITHOUT_ROWID;
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1263
1264
1265
1266
1267
1268
1269



1270
1271
1272
1273
1274
1275
1276







-
-
-







    }
    p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
        sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
    );
    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
      int iCid = sqlite3_column_int(pXInfo, 1);
      if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
      if( iCid==-2 ){
        memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol);
      }
    }
    rbuFinalize(p, pXInfo);
    bIndex = 1;
    pIter->nIndex++;
  }

  if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
1396
1397
1398
1399
1400
1401
1402
1403
1404

1405
1406
1407
1408
1409
1410
1411
1377
1378
1379
1380
1381
1382
1383


1384
1385
1386
1387
1388
1389
1390
1391







-
-
+








        if( i!=iOrder ){
          SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
          SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
        }

        pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
        assert( iPk>=0 );
        pIter->abTblPk[iOrder] = (u8)iPk;
        pIter->abTblPk[iOrder] = (iPk!=0);
        pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
        iOrder++;
      }
    }

    rbuFinalize(p, pStmt);
    rbuObjIterCacheIndexedCols(p, pIter);
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1412
1413
1414
1415
1416
1417
1418















































































































































































































1419
1420
1421
1422
1423
1424
1425







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







    const char *z = pIter->azTblCol[i];
    zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
    zSep = ", ";
  }
  return zList;
}

/*
** Return a comma separated list of the quoted PRIMARY KEY column names,
** in order, for the current table. Before each column name, add the text
** zPre. After each column name, add the zPost text. Use zSeparator as
** the separator text (usually ", ").
*/
static char *rbuObjIterGetPkList(
  sqlite3rbu *p,                  /* RBU object */
  RbuObjIter *pIter,              /* Object iterator for column names */
  const char *zPre,               /* Before each quoted column name */
  const char *zSeparator,         /* Separator to use between columns */
  const char *zPost               /* After each quoted column name */
){
  int iPk = 1;
  char *zRet = 0;
  const char *zSep = "";
  while( 1 ){
    int i;
    for(i=0; i<pIter->nTblCol; i++){
      if( (int)pIter->abTblPk[i]==iPk ){
        const char *zCol = pIter->azTblCol[i];
        zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
        zSep = zSeparator;
        break;
      }
    }
    if( i==pIter->nTblCol ) break;
    iPk++;
  }
  return zRet;
}

/*
** This function is called as part of restarting an RBU vacuum within 
** stage 1 of the process (while the *-oal file is being built) while
** updating a table (not an index). The table may be a rowid table or
** a WITHOUT ROWID table. It queries the target database to find the 
** largest key that has already been written to the target table and
** constructs a WHERE clause that can be used to extract the remaining
** rows from the source table. For a rowid table, the WHERE clause
** is of the form:
**
**     "WHERE _rowid_ > ?"
**
** and for WITHOUT ROWID tables:
**
**     "WHERE (key1, key2) > (?, ?)"
**
** Instead of "?" placeholders, the actual WHERE clauses created by
** this function contain literal SQL values.
*/
static char *rbuVacuumTableStart(
  sqlite3rbu *p,                  /* RBU handle */
  RbuObjIter *pIter,              /* RBU iterator object */
  int bRowid,                     /* True for a rowid table */
  const char *zWrite              /* Target table name prefix */
){
  sqlite3_stmt *pMax = 0;
  char *zRet = 0;
  if( bRowid ){
    p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, 
        sqlite3_mprintf(
          "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
        )
    );
    if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
      sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
      zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
    }
    rbuFinalize(p, pMax);
  }else{
    char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
    char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
    char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");

    if( p->rc==SQLITE_OK ){
      p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, 
          sqlite3_mprintf(
            "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1", 
                zSelect, zWrite, pIter->zTbl, zOrder
          )
      );
      if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
        const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
        zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
      }
      rbuFinalize(p, pMax);
    }

    sqlite3_free(zOrder);
    sqlite3_free(zSelect);
    sqlite3_free(zList);
  }
  return zRet;
}

/*
** This function is called as part of restating an RBU vacuum when the
** current operation is writing content to an index. If possible, it
** queries the target index b-tree for the largest key already written to
** it, then composes and returns an expression that can be used in a WHERE 
** clause to select the remaining required rows from the source table. 
** It is only possible to return such an expression if:
**
**   * The index contains no DESC columns, and
**   * The last key written to the index before the operation was 
**     suspended does not contain any NULL values.
**
** The expression is of the form:
**
**   (index-field1, index-field2, ...) > (?, ?, ...)
**
** except that the "?" placeholders are replaced with literal values.
**
** If the expression cannot be created, NULL is returned. In this case,
** the caller has to use an OFFSET clause to extract only the required 
** rows from the sourct table, just as it does for an RBU update operation.
*/
char *rbuVacuumIndexStart(
  sqlite3rbu *p,                  /* RBU handle */
  RbuObjIter *pIter               /* RBU iterator object */
){
  char *zOrder = 0;
  char *zLhs = 0;
  char *zSelect = 0;
  char *zVector = 0;
  char *zRet = 0;
  int bFailed = 0;
  const char *zSep = "";
  int iCol = 0;
  sqlite3_stmt *pXInfo = 0;

  p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
      sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
  );
  while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
    int iCid = sqlite3_column_int(pXInfo, 1);
    const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
    const char *zCol;
    if( sqlite3_column_int(pXInfo, 3) ){
      bFailed = 1;
      break;
    }

    if( iCid<0 ){
      if( pIter->eType==RBU_PK_IPK ){
        int i;
        for(i=0; pIter->abTblPk[i]==0; i++);
        assert( i<pIter->nTblCol );
        zCol = pIter->azTblCol[i];
      }else{
        zCol = "_rowid_";
      }
    }else{
      zCol = pIter->azTblCol[iCid];
    }

    zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q",
        zLhs, zSep, zCol, zCollate
        );
    zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC",
        zOrder, zSep, iCol, zCol, zCollate
        );
    zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")",
        zSelect, zSep, iCol, zCol
        );
    zSep = ", ";
    iCol++;
  }
  rbuFinalize(p, pXInfo);
  if( bFailed ) goto index_start_out;

  if( p->rc==SQLITE_OK ){
    sqlite3_stmt *pSel = 0;

    p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg,
        sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1",
          zSelect, pIter->zTbl, zOrder
        )
    );
    if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){
      zSep = "";
      for(iCol=0; iCol<pIter->nCol; iCol++){
        const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
        if( zQuoted[0]=='N' ){
          bFailed = 1;
          break;
        }
        zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted);
        zSep = ", ";
      }

      if( !bFailed ){
        zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector);
      }
    }
    rbuFinalize(p, pSel);
  }

 index_start_out:
  sqlite3_free(zOrder);
  sqlite3_free(zSelect);
  sqlite3_free(zVector);
  sqlite3_free(zLhs);
  return zRet;
}

/*
** This function is used to create a SELECT list (the list of SQL 
** expressions that follows a SELECT keyword) for a SELECT statement 
** used to read from an data_xxx or rbu_tmp_xxx table while updating the 
** index object currently indicated by the iterator object passed as the 
** second argument. A "PRAGMA index_xinfo = <idxname>" statement is used 
** to obtain the required information.
1693
1694
1695
1696
1697
1698
1699
1700

1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727


















1728
1729
1730


1731
1732
1733
1734
1735
1736
1737
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







-
+


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







    );
  }

  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
    int iCid = sqlite3_column_int(pXInfo, 1);
    int bDesc = sqlite3_column_int(pXInfo, 3);
    const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
    const char *zCol = 0;
    const char *zCol;
    const char *zType;

    if( iCid==-2 ){
      int iSeq = sqlite3_column_int(pXInfo, 0);
      zRet = sqlite3_mprintf("%z%s(%.*s) COLLATE %Q", zRet, zCom,
          pIter->aIdxCol[iSeq].nSpan, pIter->aIdxCol[iSeq].zSpan, zCollate
      );
      zType = "";
    }else {
      if( iCid<0 ){
        /* An integer primary key. If the table has an explicit IPK, use
        ** its name. Otherwise, use "rbu_rowid".  */
        if( pIter->eType==RBU_PK_IPK ){
          int i;
          for(i=0; pIter->abTblPk[i]==0; i++);
          assert( i<pIter->nTblCol );
          zCol = pIter->azTblCol[i];
        }else if( rbuIsVacuum(p) ){
          zCol = "_rowid_";
        }else{
          zCol = "rbu_rowid";
        }
        zType = "INTEGER";
      }else{
        zCol = pIter->azTblCol[iCid];
        zType = pIter->azTblType[iCid];
      }
    if( iCid<0 ){
      /* An integer primary key. If the table has an explicit IPK, use
      ** its name. Otherwise, use "rbu_rowid".  */
      if( pIter->eType==RBU_PK_IPK ){
        int i;
        for(i=0; pIter->abTblPk[i]==0; i++);
        assert( i<pIter->nTblCol );
        zCol = pIter->azTblCol[i];
      }else if( rbuIsVacuum(p) ){
        zCol = "_rowid_";
      }else{
        zCol = "rbu_rowid";
      }
      zType = "INTEGER";
    }else{
      zCol = pIter->azTblCol[iCid];
      zType = pIter->azTblType[iCid];
    }
      zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom,zCol,zCollate);
    }


    zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
    if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
      const char *zOrder = (bDesc ? " DESC" : "");
      zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", 
          zImpPK, zCom, nBind, zCol, zOrder
      );
    }
    zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", 
2034
2035
2036
2037
2038
2039
2040
2041

2042
2043
2044
2045
2046
2047
2048
1799
1800
1801
1802
1803
1804
1805

1806
1807
1808
1809
1810
1811
1812
1813







-
+







    char *zCols = 0;              /* Used to build up list of table cols */
    char *zPk = 0;                /* Used to build up table PK declaration */

    /* Figure out the name of the primary key index for the current table.
    ** This is needed for the argument to "PRAGMA index_xinfo". Set
    ** zIdx to point to a nul-terminated string containing this name. */
    p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg, 
        "SELECT name FROM sqlite_schema WHERE rootpage = ?"
        "SELECT name FROM sqlite_master WHERE rootpage = ?"
    );
    if( p->rc==SQLITE_OK ){
      sqlite3_bind_int(pQuery, 1, tnum);
      if( SQLITE_ROW==sqlite3_step(pQuery) ){
        zIdx = (const char*)sqlite3_column_text(pQuery, 0);
      }
    }
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214

2215
2216
2217
2218
2219
2220
2221

2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
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







-
-


-
+






-
+
-
-
-



-
-


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

-
-
-
-





-
-



-
-
-
-











-
-
-
-
-
-
-





-







}

static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
  sqlite3_stmt *pStmt = 0;
  int rc = p->rc;
  char *zRet = 0;

  assert( pIter->zIdxSql==0 && pIter->nIdxCol==0 && pIter->aIdxCol==0 );

  if( rc==SQLITE_OK ){
    rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
        "SELECT trim(sql) FROM sqlite_schema WHERE type='index' AND name=?"
        "SELECT trim(sql) FROM sqlite_master WHERE type='index' AND name=?"
    );
  }
  if( rc==SQLITE_OK ){
    int rc2;
    rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC);
    if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
      char *zSql = (char*)sqlite3_column_text(pStmt, 0);
      const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
      if( zSql ){
        pIter->zIdxSql = zSql = rbuStrndup(zSql, &rc);
      }
      if( zSql ){
        int nParen = 0;           /* Number of open parenthesis */
        int i;
        int iIdxCol = 0;
        int nIdxAlloc = 0;
        for(i=0; zSql[i]; i++){
          char c = zSql[i];

          /* If necessary, grow the pIter->aIdxCol[] array */
          if( iIdxCol==nIdxAlloc ){
            RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc(
                pIter->aIdxCol, (nIdxAlloc+16)*sizeof(RbuSpan)
            );
            if( aIdxCol==0 ){
              rc = SQLITE_NOMEM;
              break;
            }
            pIter->aIdxCol = aIdxCol;
            nIdxAlloc += 16;
          }

          if( c=='(' ){
            if( nParen==0 ){
              assert( iIdxCol==0 );
              pIter->aIdxCol[0].zSpan = &zSql[i+1];
            }
            nParen++;
          }
          else if( c==')' ){
            nParen--;
            if( nParen==0 ){
              int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
              pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
              i++;
              break;
            }
          }else if( c==',' && nParen==1 ){
            int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
            pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
            pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
          }else if( c=='"' || c=='\'' || c=='`' ){
            for(i++; 1; i++){
              if( zSql[i]==c ){
                if( zSql[i+1]!=c ) break;
                i++;
              }
            }
          }else if( c=='[' ){
            for(i++; 1; i++){
              if( zSql[i]==']' ) break;
            }
          }else if( c=='-' && zSql[i+1]=='-' ){
            for(i=i+2; zSql[i] && zSql[i]!='\n'; i++);
            if( zSql[i]=='\0' ) break;
          }else if( c=='/' && zSql[i+1]=='*' ){
            for(i=i+2; zSql[i] && (zSql[i]!='*' || zSql[i+1]!='/'); i++);
            if( zSql[i]=='\0' ) break;
            i++;
          }
        }
        if( zSql[i] ){
          zRet = rbuStrndup(&zSql[i], &rc);
        }
        pIter->nIdxCol = iIdxCol;
      }
    }

    rc2 = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ) rc = rc2;
  }

2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337

2338
2339
2340
2341
2342
2343
2344
2052
2053
2054
2055
2056
2057
2058

2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070







-




+







      char *zImposterPK = 0;      /* Primary key declaration for imposter */
      char *zWhere = 0;           /* WHERE clause on PK columns */
      char *zBind = 0;
      char *zPart = 0;
      int nBind = 0;

      assert( pIter->eType!=RBU_PK_VTAB );
      zPart = rbuObjIterGetIndexWhere(p, pIter);
      zCollist = rbuObjIterGetIndexCols(
          p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
      );
      zBind = rbuObjIterGetBindlist(p, nBind);
      zPart = rbuObjIterGetIndexWhere(p, pIter);

      /* Create the imposter table used to write to this index. */
      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
      rbuMPrintfExec(p, p->dbMain,
          "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID",
          zTbl, zImposterCols, zImposterPK
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379

2380
2381
2382
2383
2384

2385
2386
2387
2388
2389
2390
2391
2392
2393
2088
2089
2090
2091
2092
2093
2094









2095

2096
2097
2098



2099
2100

2101
2102
2103
2104
2105
2106
2107







-
-
-
-
-
-
-
-
-

-
+


-
-
-
+

-







        );
      }

      /* Create the SELECT statement to read keys in sorted order */
      if( p->rc==SQLITE_OK ){
        char *zSql;
        if( rbuIsVacuum(p) ){
          char *zStart = 0;
          if( nOffset ){
            zStart = rbuVacuumIndexStart(p, pIter);
            if( zStart ){
              sqlite3_free(zLimit);
              zLimit = 0;
            }
          }

          zSql = sqlite3_mprintf(
              "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
              "SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
              zCollist, 
              pIter->zDataTbl,
              zPart, 
              (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
              zCollist, zLimit
              zPart, zCollist, zLimit
          );
          sqlite3_free(zStart);
        }else

        if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
          zSql = sqlite3_mprintf(
              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
              zCollist, p->zStateDb, pIter->zDataTbl,
              zPart, zCollist, zLimit
2402
2403
2404
2405
2406
2407
2408
2409
2410

2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2116
2117
2118
2119
2120
2121
2122


2123



2124
2125
2126
2127
2128
2129
2130







-
-
+
-
-
-







              zCollist, p->zStateDb, pIter->zDataTbl, zPart,
              zCollist, pIter->zDataTbl, 
              zPart,
              (zPart ? "AND" : "WHERE"),
              zCollist, zLimit
          );
        }
        if( p->rc==SQLITE_OK ){
          p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql);
        p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
        }else{
          sqlite3_free(zSql);
        }
      }

      sqlite3_free(zImposterCols);
      sqlite3_free(zImposterPK);
      sqlite3_free(zWhere);
      sqlite3_free(zBind);
      sqlite3_free(zPart);
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541







2542
2543
2544
2545


2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
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







-
-



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








        rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid);
      }

      /* Create the SELECT statement to read keys from data_xxx */
      if( p->rc==SQLITE_OK ){
        const char *zRbuRowid = "";
        char *zStart = 0;
        char *zOrder = 0;
        if( bRbuRowid ){
          zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
        }

        if( rbuIsVacuum(p) ){
          if( nOffset ){
            zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite);
            if( zStart ){
              sqlite3_free(zLimit);
              zLimit = 0;
            }
          }
          if( bRbuRowid ){
            zOrder = rbuMPrintf(p, "_rowid_");
          }else{
            zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", "");
          }
        }

        if( p->rc==SQLITE_OK ){
          p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
              sqlite3_mprintf(
                "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s",
                zCollist, 
                (rbuIsVacuum(p) ? "0 AS " : ""),
                zRbuRowid,
                pIter->zDataTbl, (zStart ? zStart : ""), 
        p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
            sqlite3_mprintf(
              "SELECT %s,%s rbu_control%s FROM '%q'%s", 
              zCollist, 
              (rbuIsVacuum(p) ? "0 AS " : ""),
              zRbuRowid,
              pIter->zDataTbl, zLimit
                (zOrder ? "ORDER BY" : ""), zOrder,
                zLimit
              )
          );
            )
        );
        }
        sqlite3_free(zStart);
        sqlite3_free(zOrder);
      }

      sqlite3_free(zWhere);
      sqlite3_free(zOldlist);
      sqlite3_free(zNewlist);
      sqlite3_free(zBindings);
    }
2789
2790
2791
2792
2793
2794
2795
2796

2797
2798
2799
2800
2801
2802
2803
2475
2476
2477
2478
2479
2480
2481

2482
2483
2484
2485
2486
2487
2488
2489







-
+







#if 0
  if( rbuIsVacuum(p) ){
    if( p->rc==SQLITE_OK ){
      int rc2;
      int bOk = 0;
      sqlite3_stmt *pCnt = 0;
      p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg,
          "SELECT count(*) FROM stat.sqlite_schema"
          "SELECT count(*) FROM stat.sqlite_master"
      );
      if( p->rc==SQLITE_OK 
       && sqlite3_step(pCnt)==SQLITE_ROW
       && 1==sqlite3_column_int(pCnt, 0)
      ){
        bOk = 1;
      }
2893
2894
2895
2896
2897
2898
2899
2900

2901
2902
2903
2904
2905
2906
2907
2579
2580
2581
2582
2583
2584
2585

2586
2587
2588
2589
2590
2591
2592
2593







-
+







        "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
    );
  }

  if( p->rc==SQLITE_OK ){
    p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
  }
  rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_schema");
  rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master");

  /* Mark the database file just opened as an RBU target database. If 
  ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use.
  ** This is an error.  */
  if( p->rc==SQLITE_OK ){
    p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
  }
2986
2987
2988
2989
2990
2991
2992
2993

2994
2995
2996
2997
2998
2999
3000
2672
2673
2674
2675
2676
2677
2678

2679
2680
2681
2682
2683
2684
2685
2686







-
+








  /* If pState is NULL, then the wal file may not have been opened and
  ** recovered. Running a read-statement here to ensure that doing so
  ** does not interfere with the "capture" process below.  */
  if( pState==0 ){
    p->eStage = 0;
    if( p->rc==SQLITE_OK ){
      p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_schema", 0, 0, 0);
      p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0);
    }
  }

  /* Assuming no error has occurred, run a "restart" checkpoint with the
  ** sqlite3rbu.eStage variable set to CAPTURE. This turns on the following
  ** special behaviour in the rbu VFS:
  **
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
3263
3264
3265
3266
3267
3268
3269

3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284

3285
3286
3287
3288
3289
3290

3291
3292
3293
3294
3295
3296
3297
3298







-
+














-
+





-
+







  sqlite3_stmt *pSql = 0;
  sqlite3_stmt *pInsert = 0;

  assert( rbuIsVacuum(p) );
  p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg);
  if( p->rc==SQLITE_OK ){
    p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, 
      "SELECT sql FROM sqlite_schema WHERE sql!='' AND rootpage!=0"
      "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0"
      " AND name!='sqlite_sequence' "
      " ORDER BY type DESC"
    );
  }

  while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
    const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
    p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
  }
  rbuFinalize(p, pSql);
  if( p->rc!=SQLITE_OK ) return;

  if( p->rc==SQLITE_OK ){
    p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, 
        "SELECT * FROM sqlite_schema WHERE rootpage=0 OR rootpage IS NULL" 
        "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL" 
    );
  }

  if( p->rc==SQLITE_OK ){
    p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg, 
        "INSERT INTO sqlite_schema VALUES(?,?,?,?,?)"
        "INSERT INTO sqlite_master VALUES(?,?,?,?,?)"
    );
  }

  while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
    int i;
    for(i=0; i<5; i++){
      sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i));
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868


3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882

3883
3884
3885
3886
3887
3888
3889
3542
3543
3544
3545
3546
3547
3548

3549
3550
3551


3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566

3567
3568
3569
3570
3571
3572
3573
3574







-



-
-
+
+













-
+







  int nVal,
  sqlite3_value **apVal
){
  sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx);
  sqlite3_stmt *pStmt = 0;
  char *zErrmsg = 0;
  int rc;
  sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);

  assert( nVal==1 );
  
  rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, 
      sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
  rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, 
      sqlite3_mprintf("SELECT count(*) FROM sqlite_master "
        "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
  );
  if( rc!=SQLITE_OK ){
    sqlite3_result_error(pCtx, zErrmsg, -1);
  }else{
    int nIndex = 0;
    if( SQLITE_ROW==sqlite3_step(pStmt) ){
      nIndex = sqlite3_column_int(pStmt, 0);
    }
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ){
      sqlite3_result_int(pCtx, nIndex);
    }else{
      sqlite3_result_error(pCtx, sqlite3_errmsg(db), -1);
      sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
    }
  }

  sqlite3_free(zErrmsg);
}

/*
3912
3913
3914
3915
3916
3917
3918
3919

3920
3921
3922
3923
3924
3925
3926
3597
3598
3599
3600
3601
3602
3603

3604
3605
3606
3607
3608
3609
3610
3611







-
+







        "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0
    );
  
    /* Check for the rbu_count table. If it does not exist, or if an error
    ** occurs, nPhaseOneStep will be left set to -1. */
    if( p->rc==SQLITE_OK ){
      p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
          "SELECT 1 FROM sqlite_schema WHERE tbl_name = 'rbu_count'"
          "SELECT 1 FROM sqlite_master WHERE tbl_name = 'rbu_count'"
      );
    }
    if( p->rc==SQLITE_OK ){
      if( SQLITE_ROW==sqlite3_step(pStmt) ){
        bExists = 1;
      }
      p->rc = sqlite3_finalize(pStmt);
4769
4770
4771
4772
4773
4774
4775

4776


4777
4778
4779
4780
4781
4782
4783
4454
4455
4456
4457
4458
4459
4460
4461

4462
4463
4464
4465
4466
4467
4468
4469
4470







+
-
+
+







      rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy);
      if( rc==SQLITE_OK ){
        rc = SQLITE_ERROR;
        pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
      }else if( rc==SQLITE_NOTFOUND ){
        pRbu->pTargetFd = p;
        p->pRbu = pRbu;
        if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
        rbuMainlistAdd(p);
          rbuMainlistAdd(p);
        }
        if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
        rc = SQLITE_OK;
      }
    }
    return rc;
  }
  else if( op==SQLITE_FCNTL_RBUCNT ){
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
4511
4512
4513
4514
4515
4516
4517



4518



4519


4520
4521
4522
4523
4524
4525
4526

4527
4528
4529
4530
4531
4532
4533
4534
4535

4536
4537
4538
4539
4540
4541
4542
4543







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



+
-
+
+
+


+



-
+







  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 
  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 
    /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from
    ** is supplying heap memory to the upper layer in place of *-shm 
    ** segments. */
    ** 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( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
    if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
     && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
     && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
    ){
      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;
        pRbu->mLock |= (1 << ofst);
      }
    }
  }

  return rc;
}

4867
4868
4869
4870
4871
4872
4873
4874
4875
4876




4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891










4892
4893
4894
4895
4896
4897
4898
4555
4556
4557
4558
4559
4560
4561



4562
4563
4564
4565















4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582







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







  int rc = SQLITE_OK;
  int eStage = (p->pRbu ? p->pRbu->eStage : 0);

  /* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this
  ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space 
  ** instead of a file on disk.  */
  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
  if( eStage==RBU_STAGE_OAL ){
    sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
    char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
  if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
    if( iRegion<=p->nShm ){
      sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
      char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);

    /* This is an RBU connection that uses its own heap memory for the
    ** pages of the *-shm file. Since no other process can have run
    ** recovery, the connection must request *-shm pages in order
    ** from start to finish.  */
    assert( iRegion==p->nShm );
    if( apNew==0 ){
      rc = SQLITE_NOMEM;
    }else{
      memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
      p->apShm = apNew;
      p->nShm = iRegion+1;
    }

    if( rc==SQLITE_OK ){
      if( apNew==0 ){
        rc = SQLITE_NOMEM;
      }else{
        memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
        p->apShm = apNew;
        p->nShm = iRegion+1;
      }
    }

    if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
      char *pNew = (char*)sqlite3_malloc64(szRegion);
      if( pNew==0 ){
        rc = SQLITE_NOMEM;
      }else{
        memset(pNew, 0, szRegion);
        p->apShm[iRegion] = pNew;
      }
4933
4934
4935
4936
4937
4938
4939



























4940
4941
4942
4943
4944
4945
4946
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
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657







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







  }else{
    /* Release the checkpointer and writer locks */
    rbuUnlockShm(p);
    rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
  }
  return rc;
}

/* 
** A main database named zName has just been opened. The following 
** function returns a pointer to a buffer owned by SQLite that contains
** the name of the *-wal file this db connection will use. SQLite
** happens to pass a pointer to this buffer when using xAccess()
** or xOpen() to operate on the *-wal file.  
*/
static const char *rbuMainToWal(const char *zName, int flags){
  int n = (int)strlen(zName);
  const char *z = &zName[n];
  if( flags & SQLITE_OPEN_URI ){
    int odd = 0;
    while( 1 ){
      if( z[0]==0 ){
        odd = 1 - odd;
        if( odd && z[1]==0 ) break;
      }
      z++;
    }
    z += 2;
  }else{
    while( *z==0 ) z++;
  }
  z += (n + 8 + 1);
  return z;
}

/*
** Open an rbu file handle.
*/
static int rbuVfsOpen(
  sqlite3_vfs *pVfs,
  const char *zName,
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
4693
4694
4695
4696
4697
4698
4699

4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714

4715
4716
4717
4718
4719
4720
4721
4722







-
+














-
+







  if( zName ){
    if( flags & SQLITE_OPEN_MAIN_DB ){
      /* A main database has just been opened. The following block sets
      ** (pFd->zWal) to point to a buffer owned by SQLite that contains
      ** the name of the *-wal file this db connection will use. SQLite
      ** happens to pass a pointer to this buffer when using xAccess()
      ** or xOpen() to operate on the *-wal file.  */
      pFd->zWal = sqlite3_filename_wal(zName);
      pFd->zWal = rbuMainToWal(zName, flags);
    }
    else if( flags & SQLITE_OPEN_WAL ){
      rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
      if( pDb ){
        if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
          /* This call is to open a *-wal file. Intead, open the *-oal. This
          ** code ensures that the string passed to xOpen() is terminated by a
          ** pair of '\0' bytes in case the VFS attempts to extract a URI 
          ** parameter from it.  */
          const char *zBase = zName;
          size_t nCopy;
          char *zCopy;
          if( rbuIsVacuum(pDb->pRbu) ){
            zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
            zBase = sqlite3_filename_wal(zBase);
            zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI);
          }
          nCopy = strlen(zBase);
          zCopy = sqlite3_malloc64(nCopy+2);
          if( zCopy ){
            memcpy(zCopy, zBase, nCopy);
            zCopy[nCopy-3] = 'o';
            zCopy[nCopy] = '\0';
5086
5087
5088
5089
5090
5091
5092
5093

5094
5095
5096
5097
5098
5099
5100
5101
4797
4798
4799
4800
4801
4802
4803

4804

4805
4806
4807
4808
4809
4810
4811







-
+
-







  **   b) if the *-wal file does not exist, claim that it does anyway,
  **      causing SQLite to call xOpen() to open it. This call will also
  **      be intercepted (see the rbuVfsOpen() function) and the *-oal
  **      file opened instead.
  */
  if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
    rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
    if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){
    if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
      assert( pDb->pRbu );
      if( *pResOut ){
        rc = SQLITE_CANTOPEN;
      }else{
        sqlite3_int64 sz = 0;
        rc = rbuVfsFileSize(&pDb->base, &sz);
        *pResOut = (sz>0);
      }

Changes to ext/repair/checkindex.c.

469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483







-
+







  CidxIndex *pIdx = 0;

  sqlite3_stmt *pFindTab = 0;
  sqlite3_stmt *pInfo = 0;
    
  /* Find the table for this index. */
  pFindTab = cidxPrepare(&rc, pCsr, 
      "SELECT tbl_name, sql FROM sqlite_schema WHERE name=%Q AND type='index'",
      "SELECT tbl_name, sql FROM sqlite_master WHERE name=%Q AND type='index'",
      zIdx
  );
  if( rc==SQLITE_OK && sqlite3_step(pFindTab)==SQLITE_ROW ){
    const char *zSql = (const char*)sqlite3_column_text(pFindTab, 1);
    zTab = cidxStrdup(&rc, (const char*)sqlite3_column_text(pFindTab, 0));

    pInfo = cidxPrepare(&rc, pCsr, "PRAGMA index_xinfo(%Q)", zIdx);

Changes to ext/rtree/geopoly.c.

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
679
680
681
682
683
684
685


686
687
688
689
690
691
692







-
-







    }else{
      sqlite3_free(p);
      aCoord[0].f = mnX;
      aCoord[1].f = mxX;
      aCoord[2].f = mnY;
      aCoord[3].f = mxY;
    }
  }else{
    memset(aCoord, 0, sizeof(RtreeCoord)*4);
  }
  return pOut;
}

/*
** Implementation of the geopoly_bbox(X) SQL function.
*/
1071
1072
1073
1074
1075
1076
1077
1078

1079
1080
1081
1082
1083
1084
1085
1069
1070
1071
1072
1073
1074
1075

1076
1077
1078
1079
1080
1081
1082
1083







-
+







  if( p==0 ) return -1;
  p->aEvent = (GeoEvent*)&p[1];
  p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2];
  p->nEvent = p->nSegment = 0;
  geopolyAddSegments(p, p1, 1);
  geopolyAddSegments(p, p2, 2);
  pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent);
  rX = pThisEvent && pThisEvent->x==0.0 ? -1.0 : 0.0;
  rX = pThisEvent->x==0.0 ? -1.0 : 0.0;
  memset(aOverlap, 0, sizeof(aOverlap));
  while( pThisEvent ){
    if( pThisEvent->x!=rX ){
      GeoSegment *pPrev = 0;
      int iMask = 0;
      GEODEBUG(("Distinct X: %g\n", pThisEvent->x));
      rX = pThisEvent->x;
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354






1355
1356
1357
1358
1359
1360
1361
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







+




-
+
+
+
+
+
+







  int argc, sqlite3_value **argv        /* Parameters to the query plan */
){
  Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
  RtreeNode *pRoot = 0;
  int rc = SQLITE_OK;
  int iCell = 0;
  sqlite3_stmt *pStmt;

  rtreeReference(pRtree);

  /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
  resetCursor(pCsr);
  freeCursorConstraints(pCsr);
  sqlite3_free(pCsr->aPoint);
  pStmt = pCsr->pReadAux;
  memset(pCsr, 0, sizeof(RtreeCursor));
  pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
  pCsr->pReadAux = pStmt;

  pCsr->iStrategy = idxNum;
  if( idxNum==1 ){
    /* Special case - lookup by rowid. */
    RtreeNode *pLeaf;        /* Leaf on which the required cell resides */
    RtreeSearchPoint *p;     /* Search point for the leaf */
    i64 iRowid = sqlite3_value_int64(argv[0]);
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
1788
1789
1790
1791
1792
1793
1794



1795



1796
1797
1798
1799
1800

1801


1802
1803
1804
1805
1806
1807
1808







-
-
-
+
-
-
-





-
+
-
-
+






    void (*xFinal)(sqlite3_context*);
    const char *zName;
  } aAgg[] = {
     { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox"    },
  };
  int i;
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
    int enc;
    if( aFunc[i].bPure ){
      enc = SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS;
    int enc = aFunc[i].bPure ? SQLITE_UTF8|SQLITE_DETERMINISTIC : SQLITE_UTF8;
    }else{
      enc = SQLITE_UTF8|SQLITE_DIRECTONLY;
    }
    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
                                 enc, 0,
                                 aFunc[i].xFunc, 0, 0);
  }
  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
    rc = sqlite3_create_function(db, aAgg[i].zName, 1, 
    rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0,
              SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS, 0,
              0, aAgg[i].xStep, aAgg[i].xFinal);
                                 0, aAgg[i].xStep, aAgg[i].xFinal);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_module_v2(db, "geopoly", &geopolyModule, 0, 0);
  }
  return rc;
}

Changes to ext/rtree/rtree.c.

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







-
+
+
+
+








-
-

-
-
-
-
-
-
-
-
-








#ifndef SQLITE_CORE
  #include "sqlite3ext.h"
  SQLITE_EXTENSION_INIT1
#else
  #include "sqlite3.h"
#endif
int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */

#include <string.h>
#include <assert.h>
#include <stdio.h>

#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
# undef NDEBUG
#endif
#endif

#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

/*  The following macro is used to suppress compiler warnings.
*/
#ifndef UNUSED_PARAMETER
# define UNUSED_PARAMETER(x) (void)(x)
#endif

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
315
316
317
318
319
320
321






322
323
324
325
326
327
328







-
-
-
-
-
-







#define RTREE_LE    0x42  /* B */
#define RTREE_LT    0x43  /* C */
#define RTREE_GE    0x44  /* D */
#define RTREE_GT    0x45  /* E */
#define RTREE_MATCH 0x46  /* F: Old-style sqlite3_rtree_geometry_callback() */
#define RTREE_QUERY 0x47  /* G: New-style sqlite3_rtree_query_callback() */

/* Special operators available only on cursors.  Needs to be consecutive
** with the normal values above, but must be less than RTREE_MATCH.  These
** are used in the cursor for contraints such as x=NULL (RTREE_FALSE) or
** x<'xyz' (RTREE_TRUE) */
#define RTREE_TRUE  0x3f  /* ? */
#define RTREE_FALSE 0x40  /* @ */

/* 
** An rtree structure node.
*/
struct RtreeNode {
  RtreeNode *pParent;         /* Parent node */
  i64 iNode;                  /* The node number */
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
402
403
404
405
406
407
408

















409
410
411
412
413
414
415







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







/* The testcase() macro should already be defined in the amalgamation.  If
** it is not, make it a no-op.
*/
#ifndef SQLITE_AMALGAMATION
# define testcase(X)
#endif

/*
** Make sure that the compiler intrinsics we desire are enabled when
** compiling with an appropriate version of MSVC unless prevented by
** the SQLITE_DISABLE_INTRINSIC define.
*/
#if !defined(SQLITE_DISABLE_INTRINSIC)
#  if defined(_MSC_VER) && _MSC_VER>=1400
#    if !defined(_WIN32_WCE)
#      include <intrin.h>
#      pragma intrinsic(_byteswap_ulong)
#      pragma intrinsic(_byteswap_uint64)
#    else
#      include <cmnintrin.h>
#    endif
#  endif
#endif

/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.
**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros.  If that is unsuccessful, or if
** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
690
691
692
693
694
695
696

697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673



674
675
676
677
678
679
680







+







-
-
-







  int rc = SQLITE_OK;
  RtreeNode *pNode = 0;

  /* Check if the requested node is already in the hash table. If so,
  ** increase its reference count and return it.
  */
  if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
    assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
    if( pParent && !pNode->pParent ){
      if( nodeInParentChain(pNode, pParent) ){
        RTREE_IS_CORRUPT(pRtree);
        return SQLITE_CORRUPT_VTAB;
      }
      pParent->nRef++;
      pNode->pParent = pParent;
    }else if( pParent && pNode->pParent && pParent!=pNode->pParent ){
      RTREE_IS_CORRUPT(pRtree);
      return SQLITE_CORRUPT_VTAB;
    }
    pNode->nRef++;
    *ppNode = pNode;
    return SQLITE_OK;
  }

  if( pRtree->pNodeBlob ){
755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736







-
+








  /* If the root node was just loaded, set pRtree->iDepth to the height
  ** of the r-tree structure. A height of zero means all data is stored on
  ** the root node. A height of one means the children of the root node
  ** are the leaves, and so on. If the depth as specified on the root node
  ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
  */
  if( pNode && rc==SQLITE_OK && iNode==1 ){
  if( pNode && iNode==1 ){
    pRtree->iDepth = readInt16(pNode->zData);
    if( pRtree->iDepth>RTREE_MAX_DEPTH ){
      rc = SQLITE_CORRUPT_VTAB;
      RTREE_IS_CORRUPT(pRtree);
    }
  }

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







-
+

-
+
-
-
-












-
-
-
-
-
-
-







+


-
+

+
+







  *ppCursor = (sqlite3_vtab_cursor *)pCsr;

  return rc;
}


/*
** Reset a cursor back to its initial state.
** Free the RtreeCursor.aConstraint[] array and its contents.
*/
static void resetCursor(RtreeCursor *pCsr){
static void freeCursorConstraints(RtreeCursor *pCsr){
  Rtree *pRtree = (Rtree *)(pCsr->base.pVtab);
  int ii;
  sqlite3_stmt *pStmt;
  if( pCsr->aConstraint ){
    int i;                        /* Used to iterate through constraint array */
    for(i=0; i<pCsr->nConstraint; i++){
      sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo;
      if( pInfo ){
        if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser);
        sqlite3_free(pInfo);
      }
    }
    sqlite3_free(pCsr->aConstraint);
    pCsr->aConstraint = 0;
  }
  for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
  sqlite3_free(pCsr->aPoint);
  pStmt = pCsr->pReadAux;
  memset(pCsr, 0, sizeof(RtreeCursor));
  pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
  pCsr->pReadAux = pStmt;

}

/* 
** Rtree virtual table module xClose method.
*/
static int rtreeClose(sqlite3_vtab_cursor *cur){
  Rtree *pRtree = (Rtree *)(cur->pVtab);
  int ii;
  RtreeCursor *pCsr = (RtreeCursor *)cur;
  assert( pRtree->nCursor>0 );
  resetCursor(pCsr);
  freeCursorConstraints(pCsr);
  sqlite3_finalize(pCsr->pReadAux);
  sqlite3_free(pCsr->aPoint);
  for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
  sqlite3_free(pCsr);
  pRtree->nCursor--;
  nodeBlobReset(pRtree);
  return SQLITE_OK;
}

/*
1272
1273
1274
1275
1276
1277
1278
1279

1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1232
1233
1234
1235
1236
1237
1238

1239

1240
1241


1242
1243
1244
1245
1246
1247
1248







-
+
-


-
-








  /* p->iCoord might point to either a lower or upper bound coordinate
  ** in a coordinate pair.  But make pCellData point to the lower bound.
  */
  pCellData += 8 + 4*(p->iCoord&0xfe);

  assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
      || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
      || p->op==RTREE_GT || p->op==RTREE_EQ );
      || p->op==RTREE_FALSE );
  assert( ((((char*)pCellData) - (char*)0)&3)==0 );  /* 4-byte aligned */
  switch( p->op ){
    case RTREE_TRUE:  return;   /* Always satisfied */
    case RTREE_FALSE: break;    /* Never satisfied */
    case RTREE_LE:
    case RTREE_LT:
    case RTREE_EQ:
      RTREE_DECODE_COORD(eInt, pCellData, val);
      /* val now holds the lower bound of the coordinate pair */
      if( p->u.rValue>=val ) return;
      if( p->op!=RTREE_EQ ) break;  /* RTREE_LE and RTREE_LT end here */
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
1272
1273
1274
1275
1276
1277
1278

1279

1280
1281
1282
1283







1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295







-
+
-




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







  int eInt,                  /* True if RTree holds integer coordinates */
  u8 *pCellData,             /* Raw cell content as appears on disk */
  int *peWithin              /* Adjust downward, as appropriate */
){
  RtreeDValue xN;      /* Coordinate value converted to a double */

  assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
      || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
      || p->op==RTREE_GT || p->op==RTREE_EQ );
      || p->op==RTREE_FALSE );
  pCellData += 8 + p->iCoord*4;
  assert( ((((char*)pCellData) - (char*)0)&3)==0 );  /* 4-byte aligned */
  RTREE_DECODE_COORD(eInt, pCellData, xN);
  switch( p->op ){
    case RTREE_TRUE:  return;   /* Always satisfied */
    case RTREE_FALSE: break;    /* Never satisfied */
    case RTREE_LE:    if( xN <= p->u.rValue ) return;  break;
    case RTREE_LT:    if( xN <  p->u.rValue ) return;  break;
    case RTREE_GE:    if( xN >= p->u.rValue ) return;  break;
    case RTREE_GT:    if( xN >  p->u.rValue ) return;  break;
    default:          if( xN == p->u.rValue ) return;  break;
    case RTREE_LE: if( xN <= p->u.rValue ) return;  break;
    case RTREE_LT: if( xN <  p->u.rValue ) return;  break;
    case RTREE_GE: if( xN >= p->u.rValue ) return;  break;
    case RTREE_GT: if( xN >  p->u.rValue ) return;  break;
    default:       if( xN == p->u.rValue ) return;  break;
  }
  *peWithin = NOT_WITHIN;
}

/*
** One of the cells in node pNode is guaranteed to have a 64-bit 
** integer value equal to iRowid. Return the index of this cell.
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
1554
1555
1556
1557
1558
1559
1560

1561
1562
1563
1564

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

1580




1581


1582
1583
1584
1585
1586






1587
1588
1589
1590
1591
1592
1593







-




-


+












-
+
-
-
-
-
+
-
-

+



-
-
-
-
-
-







  int nConstraint = pCur->nConstraint;
  int ii;
  int eInt;
  RtreeSearchPoint x;

  eInt = pRtree->eCoordType==RTREE_COORD_INT32;
  while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){
    u8 *pCellData;
    pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc);
    if( rc ) return rc;
    nCell = NCELL(pNode);
    assert( nCell<200 );
    pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell);
    while( p->iCell<nCell ){
      sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1;
      u8 *pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell);
      eWithin = FULLY_WITHIN;
      for(ii=0; ii<nConstraint; ii++){
        RtreeConstraint *pConstraint = pCur->aConstraint + ii;
        if( pConstraint->op>=RTREE_MATCH ){
          rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p,
                                       &rScore, &eWithin);
          if( rc ) return rc;
        }else if( p->iLevel==1 ){
          rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin);
        }else{
          rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin);
        }
        if( eWithin==NOT_WITHIN ){
        if( eWithin==NOT_WITHIN ) break;
          p->iCell++;
          pCellData += pRtree->nBytesPerCell;
          break;
        }
      }
      }
      if( eWithin==NOT_WITHIN ) continue;
      p->iCell++;
      if( eWithin==NOT_WITHIN ) continue;
      x.iLevel = p->iLevel - 1;
      if( x.iLevel ){
        x.id = readInt64(pCellData);
        for(ii=0; ii<pCur->nPoint; ii++){
          if( pCur->aPoint[ii].id==x.id ){
            RTREE_IS_CORRUPT(pRtree);
            return SQLITE_CORRUPT_VTAB;
          }
        }
        x.iCell = 0;
      }else{
        x.id = p->id;
        x.iCell = p->iCell - 1;
      }
      if( p->iCell>=nCell ){
        RTREE_QUEUE_TRACE(pCur, "POP-S:");
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
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







+




-
+
+
+
+
+
+








-
-
-
-
-
+
-
-
-
-







){
  Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
  RtreeNode *pRoot = 0;
  int ii;
  int rc = SQLITE_OK;
  int iCell = 0;
  sqlite3_stmt *pStmt;

  rtreeReference(pRtree);

  /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
  resetCursor(pCsr);
  freeCursorConstraints(pCsr);
  sqlite3_free(pCsr->aPoint);
  pStmt = pCsr->pReadAux;
  memset(pCsr, 0, sizeof(RtreeCursor));
  pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
  pCsr->pReadAux = pStmt;

  pCsr->iStrategy = idxNum;
  if( idxNum==1 ){
    /* Special case - lookup by rowid. */
    RtreeNode *pLeaf;        /* Leaf on which the required cell resides */
    RtreeSearchPoint *p;     /* Search point for the leaf */
    i64 iRowid = sqlite3_value_int64(argv[0]);
    i64 iNode = 0;
    int eType = sqlite3_value_numeric_type(argv[0]);
    if( eType==SQLITE_INTEGER
     || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid)
    ){
      rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
    rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
    }else{
      rc = SQLITE_OK;
      pLeaf = 0;
    }
    if( rc==SQLITE_OK && pLeaf!=0 ){
      p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0);
      assert( p!=0 );  /* Always returns pCsr->sPoint */
      pCsr->aNode[0] = pLeaf;
      p->id = iNode;
      p->eWithin = PARTLY_WITHIN;
      rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
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
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







-














-
+





-
-
-
-
-
-
-
-
-







      }else{
        memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
        memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1));
        assert( (idxStr==0 && argc==0)
                || (idxStr && (int)strlen(idxStr)==argc*2) );
        for(ii=0; ii<argc; ii++){
          RtreeConstraint *p = &pCsr->aConstraint[ii];
          int eType = sqlite3_value_numeric_type(argv[ii]);
          p->op = idxStr[ii*2];
          p->iCoord = idxStr[ii*2+1]-'0';
          if( p->op>=RTREE_MATCH ){
            /* A MATCH operator. The right-hand-side must be a blob that
            ** can be cast into an RtreeMatchArg object. One created using
            ** an sqlite3_rtree_geometry_callback() SQL user function.
            */
            rc = deserializeGeometry(argv[ii], p);
            if( rc!=SQLITE_OK ){
              break;
            }
            p->pInfo->nCoord = pRtree->nDim2;
            p->pInfo->anQueue = pCsr->anQueue;
            p->pInfo->mxLevel = pRtree->iDepth + 1;
          }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
          }else{
#ifdef SQLITE_RTREE_INT_ONLY
            p->u.rValue = sqlite3_value_int64(argv[ii]);
#else
            p->u.rValue = sqlite3_value_double(argv[ii]);
#endif
          }else{
            p->u.rValue = RTREE_ZERO;
            if( eType==SQLITE_NULL ){
              p->op = RTREE_FALSE;
            }else if( p->op==RTREE_LT || p->op==RTREE_LE ){
              p->op = RTREE_TRUE;
            }else{
              p->op = RTREE_FALSE;
            }
          }
        }
      }
    }
    if( rc==SQLITE_OK ){
      RtreeSearchPoint *pNew;
      pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3608
3609
3610
3611
3612
3613
3614








3615
3616
3617
3618
3619
3620
3621







-
-
-
-
-
-
-
-







    }
  }

  sqlite3_free(zSql);
  return rc;
}

/*
** Return the length of a token
*/
static int rtreeTokenLength(const char *z){
  int dummy = 0;
  return sqlite3GetToken((const unsigned char*)z,&dummy);
}

/* 
** This function is the implementation of both the xConnect and xCreate
** methods of the r-tree virtual table.
**
**   argv[0]   -> module name
**   argv[1]   -> database name
**   argv[2]   -> table name
3721
3722
3723
3724
3725
3726
3727
3728
3729


3730
3731
3732
3733
3734
3735
3736
3644
3645
3646
3647
3648
3649
3650


3651
3652
3653
3654
3655
3656
3657
3658
3659







-
-
+
+







    "Wrong number of columns for an rtree table",         /* 1 */
    "Too few columns for an rtree table",                 /* 2 */
    "Too many columns for an rtree table",                /* 3 */
    "Auxiliary rtree columns must be last"                /* 4 */
  };

  assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */
  if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){
    *pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]);
  if( argc>RTREE_MAX_AUX_COLUMN+3 ){
    *pzErr = sqlite3_mprintf("%s", aErrMsg[3]);
    return SQLITE_ERROR;
  }

  sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);

  /* Allocate the sqlite3_vtab structure */
  nDb = (int)strlen(argv[1]);
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
3673
3674
3675
3676
3677
3678
3679

3680

3681


3682
3683

3684
3685
3686
3687

3688

3689

3690
3691
3692
3693
3694
3695
3696







-
+
-

-
-
+

-
+



-

-
+
-









  /* Create/Connect to the underlying relational database schema. If
  ** that is successful, call sqlite3_declare_vtab() to configure
  ** the r-tree table schema.
  */
  pSql = sqlite3_str_new(db);
  sqlite3_str_appendf(pSql, "CREATE TABLE x(%.*s INT", 
  sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]);
                      rtreeTokenLength(argv[3]), argv[3]);
  for(ii=4; ii<argc; ii++){
    const char *zArg = argv[ii];
    if( zArg[0]=='+' ){
    if( argv[ii][0]=='+' ){
      pRtree->nAux++;
      sqlite3_str_appendf(pSql, ",%.*s", rtreeTokenLength(zArg+1), zArg+1);
      sqlite3_str_appendf(pSql, ",%s", argv[ii]+1);
    }else if( pRtree->nAux>0 ){
      break;
    }else{
      static const char *azFormat[] = {",%.*s REAL", ",%.*s INT"};
      pRtree->nDim2++;
      sqlite3_str_appendf(pSql, azFormat[eCoordType],
      sqlite3_str_appendf(pSql, ",%s", argv[ii]);
                          rtreeTokenLength(zArg), zArg);
    }
  }
  sqlite3_str_appendf(pSql, ");");
  zSql = sqlite3_str_finish(pSql);
  if( !zSql ){
    rc = SQLITE_NOMEM;
  }else if( ii<argc ){

Changes to ext/rtree/rtree1.test.

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
108
109
110
111
112
113
114



115
116
117
118
119
120
121







-
-
-







    catchsql " 
      CREATE VIRTUAL TABLE t1 USING rtree($columns);
    "
  } $X

  catchsql { DROP TABLE t1 }
}
do_catchsql_test rtree-1.3.1000 {
  CREATE VIRTUAL TABLE t1000 USING rtree;
} {1 {Too few columns for an rtree table}}

# Like execsql except display output as integer where that can be
# done without loss of information.
#
proc execsql_intout {sql} {
  set out {}
  foreach term [execsql $sql] {
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
370
371
372
373
374
375
376







377
378
379
380
381
382
383






























384
385
386
387
388
389
390







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







do_test rtree-8.1.1 {
  execsql {
    CREATE VIRTUAL TABLE t6 USING rtree(ii, x1, x2);
    INSERT INTO t6 VALUES(1, 3, 7);
    INSERT INTO t6 VALUES(2, 4, 6);
  }
} {}
do_test rtree-8.1.2 { execsql { SELECT ii FROM t6 WHERE x1>2 } }   {1 2}
do_test rtree-8.1.3 { execsql { SELECT ii FROM t6 WHERE x1>3 } }   {2}
do_test rtree-8.1.4 { execsql { SELECT ii FROM t6 WHERE x1>4 } }   {}
do_test rtree-8.1.5 { execsql { SELECT ii FROM t6 WHERE x1>5 } }   {}
do_test rtree-8.1.6 { execsql { SELECT ii FROM t6 WHERE x1>''} }   {}
do_test rtree-8.1.7 { execsql { SELECT ii FROM t6 WHERE x1>null}}  {}
do_test rtree-8.1.8 { execsql { SELECT ii FROM t6 WHERE x1>'2'} }   {1 2}
do_test rtree-8.1.2 { execsql { SELECT ii FROM t6 WHERE x1>2 } } {1 2}
do_test rtree-8.1.3 { execsql { SELECT ii FROM t6 WHERE x1>3 } } {2}
do_test rtree-8.1.4 { execsql { SELECT ii FROM t6 WHERE x1>4 } } {}
do_test rtree-8.1.5 { execsql { SELECT ii FROM t6 WHERE x1>5 } } {}
do_test rtree-8.1.6 { execsql { SELECT ii FROM t6 WHERE x1<3 } } {}
do_test rtree-8.1.7 { execsql { SELECT ii FROM t6 WHERE x1<4 } } {1}
do_test rtree-8.1.8 { execsql { SELECT ii FROM t6 WHERE x1<5 } } {1 2}
do_test rtree-8.1.9 { execsql { SELECT ii FROM t6 WHERE x1>'3'} }   {2}
do_test rtree-8.2.2 { execsql { SELECT ii FROM t6 WHERE x1>=2 } }  {1 2}
do_test rtree-8.2.3 { execsql { SELECT ii FROM t6 WHERE x1>=3 } }  {1 2}
do_test rtree-8.2.4 { execsql { SELECT ii FROM t6 WHERE x1>=4 } }  {2}
do_test rtree-8.2.5 { execsql { SELECT ii FROM t6 WHERE x1>=5 } }  {}
do_test rtree-8.2.6 { execsql { SELECT ii FROM t6 WHERE x1>=''} }  {}
do_test rtree-8.2.7 { execsql { SELECT ii FROM t6 WHERE x1>=null}} {}
do_test rtree-8.2.8 { execsql { SELECT ii FROM t6 WHERE x1>='4'} } {2}
do_test rtree-8.2.9 { execsql { SELECT ii FROM t6 WHERE x1>='5'} } {}
do_test rtree-8.3.2 { execsql { SELECT ii FROM t6 WHERE x1<2 } }   {}
do_test rtree-8.3.3 { execsql { SELECT ii FROM t6 WHERE x1<3 } }   {}
do_test rtree-8.3.4 { execsql { SELECT ii FROM t6 WHERE x1<4 } }   {1}
do_test rtree-8.3.5 { execsql { SELECT ii FROM t6 WHERE x1<5 } }   {1 2}
do_test rtree-8.3.6 { execsql { SELECT ii FROM t6 WHERE x1<''} }   {1 2}
do_test rtree-8.3.7 { execsql { SELECT ii FROM t6 WHERE x1<null}}  {}
do_test rtree-8.3.8 { execsql { SELECT ii FROM t6 WHERE x1<'3'} }  {}
do_test rtree-8.3.9 { execsql { SELECT ii FROM t6 WHERE x1<'4'} }  {1}
do_test rtree-8.4.2 { execsql { SELECT ii FROM t6 WHERE x1<=2 } }  {}
do_test rtree-8.4.3 { execsql { SELECT ii FROM t6 WHERE x1<=3 } }  {1}
do_test rtree-8.4.4 { execsql { SELECT ii FROM t6 WHERE x1<=4 } }  {1 2}
do_test rtree-8.4.5 { execsql { SELECT ii FROM t6 WHERE x1<=5 } }  {1 2}
do_test rtree-8.4.6 { execsql { SELECT ii FROM t6 WHERE x1<=''} }  {1 2}
do_test rtree-8.4.7 { execsql { SELECT ii FROM t6 WHERE x1<=null}} {}
do_test rtree-8.5.2 { execsql { SELECT ii FROM t6 WHERE x1=2 } }   {}
do_test rtree-8.5.3 { execsql { SELECT ii FROM t6 WHERE x1=3 } }   {1}
do_test rtree-8.5.4 { execsql { SELECT ii FROM t6 WHERE x1=4 } }   {2}
do_test rtree-8.5.5 { execsql { SELECT ii FROM t6 WHERE x1=5 } }   {}
do_test rtree-8.5.6 { execsql { SELECT ii FROM t6 WHERE x1=''} }   {}
do_test rtree-8.5.7 { execsql { SELECT ii FROM t6 WHERE x1=null}}  {}


#----------------------------------------------------------------------------
# Test cases rtree-9.*
#
# Test that ticket #3549 is fixed.
do_test rtree-9.1 {
  execsql {
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
574
575
576
577
578
579
580













581


582
583
584
585
586
587
588

589
590
591
592
593
594
595
596







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

-
-
+






-
+







}
do_execsql_test 14.5 {
  SELECT * FROM t10;
} {
  1 0.0 0.0
  2 52.0 81.0
}
do_execsql_test 14.6 {
  INSERT INTO t10 VALUES(0,10,20);
  SELECT * FROM t10 WHERE ii=NULL;
} {}
do_execsql_test 14.7 {
  SELECT * FROM t10 WHERE ii='xyz';
} {}
do_execsql_test 14.8 {
  SELECT * FROM t10 WHERE ii='0.0';
} {0 10.0 20.0}
do_execsql_test 14.9 {
  SELECT * FROM t10 WHERE ii=0.0;
} {0 10.0 20.0}


do_execsql_test 14.104 {
do_execsql_test 14.4 {
  DROP TABLE t10;
  CREATE VIRTUAL TABLE t10 USING rtree_i32(ii, x1, x2);
  INSERT INTO t10 VALUES(1, 'one', 'two');
  INSERT INTO t10 VALUES(2, '52xyz', '81...');
  INSERT INTO t10 VALUES(3, 42.3, 49.9);
}
do_execsql_test 14.105 {
do_execsql_test 14.5 {
  SELECT * FROM t10;
} {
  1 0 0
  2 52 81
  3 42 49
}

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
657
658
659
660
661
662
663








664













665







-
-
-
-
-
-
-
-

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

  REINDEX t2;
} {}

do_execsql_test 17.2 {
  REINDEX;
} {}

reset_db
do_execsql_test 18.0 {
  CREATE VIRTUAL TABLE rt0 USING rtree(c0, c1, c2);
  INSERT INTO rt0(c0,c1,c2) VALUES(9,2,3);
  SELECT c0 FROM rt0 WHERE rt0.c1 > '-1'; 
  SELECT rt0.c1 > '-1' FROM rt0;
} {9 1}

expand_all_sql db

# 2020-02-28 ticket e63b4d1a65546532
reset_db
do_execsql_test 19.0 {
  CREATE VIRTUAL TABLE rt0 USING rtree(a,b,c);
  INSERT INTO rt0(a,b,c) VALUES(0,0.0,0.0);
  CREATE VIEW v0(x) AS SELECT DISTINCT rt0.b FROM rt0;
  SELECT v0.x FROM v0, rt0;
} {0.0}
do_execsql_test 19.1 {
  SELECT v0.x FROM v0, rt0 WHERE v0.x = rt0.b;
} {0.0}

finish_test

Changes to ext/rtree/rtree2.test.

29
30
31
32
33
34
35
36
37
38
39
40
41
42

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

36
37
38
39
40

41
42
43
44
45
46
47
48







-





-
+








if {[info exists G(isquick)] && $G(isquick)} {
  set ::NROW 100
  set ::NSELECT 10
}

foreach module {rtree_i32 rtree} {
  if {$module=="rtree_i32"} {set etype INT} {set etype REAL}
  for {set nDim 1} {$nDim <= 5} {incr nDim} {
  
    do_test rtree2-$module.$nDim.1 {
      set cols [list]
      foreach c [list c0 c1 c2 c3 c4 c5 c6 c7 c8 c9] {
        lappend cols "$c $etype"
        lappend cols "$c REAL"
      }
      set cols [join [lrange $cols 0 [expr {$nDim*2-1}]] ", "]
      execsql " 
        CREATE VIRTUAL TABLE t1 USING ${module}(ii, $cols);
        CREATE TABLE t2 (ii, $cols);
      "
    } {}

Changes to ext/rtree/rtreeC.test.

173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187







-
+







} {1 1 3 {}}

#--------------------------------------------------------------------
# Test that the sqlite_stat1 data is used correctly.
#
reset_db
do_execsql_test 5.1 {
  CREATE TABLE t1(x INT PRIMARY KEY, y);
  CREATE TABLE t1(x PRIMARY KEY, y);
  CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, +d1);

  INSERT INTO t1(x) VALUES(1);
  INSERT INTO t1(x) SELECT x+1 FROM t1;   --   2
  INSERT INTO t1(x) SELECT x+2 FROM t1;   --   4
  INSERT INTO t1(x) SELECT x+4 FROM t1;   --   8
  INSERT INTO t1(x) SELECT x+8 FROM t1;   --  16

Changes to ext/rtree/rtreeH.test.

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
39
40
41
42
43
44
45












46
47
48











49
50
51
52
53
54
55







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



-
-
-
-
-
-
-
-
-
-
-







do_execsql_test rtreeH-101 {
  SELECT * FROM t1_rowid ORDER BY rowid
} {1 1 {lower-left corner} {} 2 1 {upper-left corner} {} 3 1 {lower-right corner} {} 4 1 {upper-right corner} {} 5 1 center {} 6 1 {left edge} {} 7 1 {right edge} {} 8 1 {bottom edge} {} 9 1 {top edge} {} 10 1 {the whole thing} {} 11 1 {left half} {} 12 1 {right half} {} 13 1 {bottom half} {} 14 1 {top half} {}}

do_execsql_test rtreeH-102 {
  SELECT * FROM t1 WHERE rowid=5;
} {5 40.0 60.0 40.0 60.0 center {}}
do_execsql_test rtreeH-102b {
  SELECT * FROM t1 WHERE rowid=5.0;
} {5 40.0 60.0 40.0 60.0 center {}}
do_execsql_test rtreeH-102c {
  SELECT * FROM t1 WHERE rowid='5';
} {5 40.0 60.0 40.0 60.0 center {}}
do_execsql_test rtreeH-102d {
  SELECT * FROM t1 WHERE rowid='0005';
} {5 40.0 60.0 40.0 60.0 center {}}
do_execsql_test rtreeH-102e {
  SELECT * FROM t1 WHERE rowid='+5.0e+0';
} {5 40.0 60.0 40.0 60.0 center {}}
do_execsql_test rtreeH-103 {
  SELECT * FROM t1 WHERE label='center';
} {5 40.0 60.0 40.0 60.0 center {}}

do_execsql_test rtreeH-104 {
  SELECT * FROM t1 WHERE rowid='+5.0e+0x';
} {}
do_execsql_test rtreeH-105 {
  SELECT * FROM t1 WHERE rowid=x'35';
} {}
do_execsql_test rtreeH-106 {
  SELECT * FROM t1 WHERE rowid=null;
} {}


do_rtree_integrity_test rtreeH-110 t1

do_execsql_test rtreeH-120 {
  SELECT label FROM t1 WHERE x1<=50 ORDER BY id
} {{lower-left corner} {upper-left corner} {left edge} {left half}}
do_execsql_test rtreeH-121 {

Deleted ext/rtree/rtreeI.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










































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-12-05
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# Additional test cases

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

# The following is a test of rowvalue handling on virtual tables that
# deal with inequalities and that set the OMIT flag on terms of the
# WHERE clause.  This is not specific to rtree.  We just use rtree because
# it is a convenient test platform since it has all the right
# characteristics.
#
do_execsql_test rtreeI-1.10 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(2);
  CREATE VIRTUAL TABLE t2 USING rtree(id,x0,x1);
  INSERT INTO t2(id,x0,x1) VALUES(1,2,3);
} {}
do_execsql_test rtreeI-1.20 {
  SELECT 123 FROM t1, t2 WHERE (a,0)>(x0,0);
} {}
do_execsql_test rtreeI-1.21 {
  SELECT 123 FROM t1, t2 WHERE (a,0.1)>(x0,0);
} {123}
do_execsql_test rtreeI-1.22 {
  SELECT 123 FROM t1, t2 WHERE (a,0)>=(x0,0);
} {123}
do_execsql_test rtreeI-1.23 {
  SELECT 123 FROM t1, t2 WHERE (a,0)<=(x0,0);
} {123}
do_execsql_test rtreeI-1.24 {
  SELECT 123 FROM t1, t2 WHERE (a,0)<(x0,0);
} {}
do_execsql_test rtreeI-1.30 {
  SELECT 123 FROM t1, t2 WHERE (x0,0)<(a,0);
} {}
do_execsql_test rtreeI-1.31 {
  SELECT 123 FROM t1, t2 WHERE (x0,0)<(a,0.1);
} {123}
do_execsql_test rtreeI-1.40 {
  SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)>(x0,0);
} {}
do_execsql_test rtreeI-1.41 {
  SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0.5)>(x0,0);
} {123}
do_execsql_test rtreeI-1.42 {
  SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)>=(x0,0);
} {123}
do_execsql_test rtreeI-1.43 {
  SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)<(x0,0);
} {}
do_execsql_test rtreeI-1.50 {
  SELECT 123 FROM t1, t2 WHERE 5>x1 AND 99>id AND (x0,0)<(a,0);
} {}
do_execsql_test rtreeI-1.51 {
  SELECT 123 FROM t1, t2 WHERE 5>x1 AND 99>id AND (x0,0)<(a,0.5);
} {123}



finish_test

Changes to ext/rtree/rtreefuzz001.test.

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
461
462
463
464
465
466
467

468
469
470
471
472
473
474







-







|   3392: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 74   A...A .........t
|   3408: 41 00 00 00 41 10 00 00 41 10 00 00 41 20 00 00   A...A...A...A ..
|   3424: 00 00 00 00 00 00 07 75 41 10 00 00 41 20 00 00   .......uA...A ..
|   3440: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 00 00   A...A ..........
| end c1b.db
  }]
  catchsql {
     PRAGMA writable_schema = 1;
     SELECT rtreecheck('t1');
  }
} {1 {SQL logic error}}

do_test rtreefuzz001-200 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
769
770
771
772
773
774
775
776















































































































































































































































































777








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

    WITH RECURSIVE
      c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<8),
      c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<5)
    INSERT INTO t1(id, x0,x1,y0,y1,label)
      SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2;
  }
} {1 {database disk image is malformed}}

do_test rtreefuzz001-500 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 16384 pagesize 4096 filename crash-2e81f5dce5cbd4.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 00 00 00 05 0e 6d 00 0f c8 0f 7b   ..........m.....
|    112: 0f 20 0e cd 0e 6d 00 00 00 00 00 00 00 00 00 00   . ...m..........
|   3680: 00 00 00 00 00 00 00 00 00 00 00 00 00 5e 05 07   .............^..
|   3696: 17 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61   ......tablet1_pa
|   3712: 72 65 6e 74 74 31 5f 70 61 72 65 6e 74 05 43 52   rentt1_parent.CR
|   3728: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70   EATE TABLE .t1_p
|   3744: 61 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e   arent.(nodeno IN
|   3760: 54 45 47 45 42 20 50 52 49 4d 41 52 59 20 4b 45   TEGEB PRIMARY KE
|   3776: 59 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 04 06   Y,parentnode)Q..
|   3792: 17 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64   .....tablet1_nod
|   3808: 65 74 31 5f 6e 6f 64 65 04 43 52 45 41 54 45 20   et1_node.CREATE 
|   3824: 54 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28   TABLE .t1_node.(
|   3840: 6e 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50   nodeno INTEGER P
|   3856: 52 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29   RIMARY KEY,data)
|   3872: 59 03 07 17 1d 1d 01 81 05 74 61 62 6c 65 84 31   Y........table.1
|   3888: 5f 72 6f 77 69 64 74 31 5f 72 6f 87 69 64 03 43   _rowidt1_ro.id.C
|   3904: 52 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f   REATE TABLE .t1_
|   3920: 72 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54   rowid.(rowid INT
|   3936: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
|   3952: 2c 6e f8 64 65 6e 6f 2c 61 30 29 4b 02 07 17 11   ,n.deno,a0)K....
|   3968: 11 08 81 03 74 22 62 6c 65 74 31 74 31 43 52 45   ....t.blet1t1CRE
|   3984: 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c   ATE VIRTUAL TABL
|   4000: 45 20 74 31 20 55 53 49 4e 47 20 72 74 72 65 65   E t1 USING rtree
|   4016: 5f 69 33 32 28 69 cc 2c 78 30 2c 78 31 2c 79 30   _i32(i.,x0,x1,y0
|   4032: 2c 79 31 2c 2b 65 78 29 36 01 06 17 17 17 01 4d   ,y1,+ex)6......M
|   4048: 74 61 62 6c 65 63 6f 6f 72 64 63 6f 6f 72 64 02   tablecoordcoord.
|   4064: 43 52 45 41 54 45 20 54 41 42 4c 45 20 63 6f 6f   CREATE TABLE coo
|   4080: 71 64 28 76 20 49 4e 54 2c 20 77 20 49 4e 54 29   qd(v INT, w INT)
| page 2 offset 4096
|   4016: 00 00 00 00 00 00 00 00 00 00 00 05 0a 03 01 01   ................
|   4032: 0a 02 05 09 03 01 01 09 02 05 08 03 01 01 08 02   ................
|   4048: 05 07 03 01 01 07 02 05 06 03 11 01 06 02 05 05   ................
|   4064: 03 01 01 05 02 05 04 03 01 01 04 02 05 03 03 01   ................
|   4080: 01 03 02 05 02 03 01 01 02 02 04 01 03 09 01 02   ................
| page 3 offset 8192
|      0: 0d 0e 4f 00 64 0b 5a 12 0d bb 0d 84 0f eb 0d c6   ..O.d.Z.........
|     16: 0f d7 0e cc 0f c1 0f b6 0f ab 0f 9f 0f 94 0d 8f   ................
|     32: 0f 86 0d d1 0f 62 0f 67 0f 5c 0f 51 1f 46 0f 3a   .....b.g...Q.F.:
|     48: 0f 30 0d 9a 0f 21 0d dc 0f 00 00 00 00 00 00 00   .0...!..........
|   2896: 00 00 00 00 00 00 00 00 00 00 0a ce 1a 04 00 01   ................
|   2912: 17 03 31 30 78 31 30 0a 4e 19 03 ff f1 15 03 31   ..10x10.N......1
|   2928: 30 78 39 09 ce 18 04 00 01 15 03 31 30 78 38 09   0x9........10x8.
|   2944: ce 17 04 00 01 15 03 31 30 78 37 09 ce 16 04 00   .......10x7.....
|   2960: 12 15 03 31 30 78 36 09 ce 15 04 00 01 15 03 31   ...10x6........1
|   2976: 30 78 35 09 ce 14 04 00 01 15 0d a1 30 78 34 09   0x5.........0x4.
|   2992: ce 13 04 00 01 15 03 31 30 78 33 09 ce 12 04 00   .......10x3.....
|   3008: 01 15 03 31 40 78 32 09 ce 11 04 00 01 15 03 31   ...1@x2........1
|   3024: 30 78 31 09 c6 32 04 00 01 15 03 39 78 31 30 08   0x1..2.....9x10.
|   3040: c6 31 04 00 01 13 03 39 78 39 08 c6 30 04 00 01   .1.....9x9..0...
|   3056: 13 03 39 78 38 08 c6 2f 04 00 01 14 03 39 78 37   ..9x8../.....9x7
|   3072: 08 c6 2e 04 00 01 13 03 39 78 36 08 c6 2d 04 00   ........9x6..-..
|   3088: 01 13 03 39 78 34 f8 c6 2c 04 00 01 13 03 39 78   ...9x4..,.....9x
|   3104: 34 08 c6 2b 04 00 60 13 03 39 79 13 08 c6 2a 04   4..+..`..9y...*.
|   3120: 00 11 13 03 39 78 32 08 c6 29 04 00 01 13 03 39   ....9x2..).....9
|   3136: 78 31 09 be 4a 04 00 01 15 03 38 78 31 30 08 be   x1..J.....8x10..
|   3152: 49 04 00 01 13 03 38 78 39 08 be 48 04 00 01 13   I.....8x9..H....
|   3168: 03 38 77 98 08 be 47 04 00 01 14 23 38 78 37 08   .8w...G....#8x7.
|   3184: be 46 04 00 01 13 03 38 78 36 08 be 45 04 00 01   .F.....8x6..E...
|   3200: 13 03 38 78 35 08 be 44 04 00 01 13 03 38 78 34   ..8x5..D.....8x4
|   3216: 08 be 43 04 00 01 13 03 38 78 33 08 be 42 04 00   ..C.....8x3..B..
|   3232: 01 13 03 38 78 32 08 be 41 04 00 01 13 03 38 78   ...8x2..A.....8x
|   3248: 31 09 b6 62 04 00 01 15 03 37 68 31 30 08 b6 61   1..b.....7h10..a
|   3264: 04 00 01 13 03 37 79 39 08 b6 60 04 00 01 12 f3   .....7y9..`.....
|   3280: 37 78 38 08 b6 5e 04 00 01 13 03 37 78 37 08 b6   7x8..^.....7x7..
|   3296: 5e 04 00 01 13 03 37 78 36 08 b6 5d 04 00 01 13   ^.....7x6..]....
|   3312: 03 37 78 35 08 b6 5c 04 00 00 13 03 37 78 34 08   .7x5........7x4.
|   3328: b6 5b 04 00 01 13 03 37 78 33 08 b6 5a 04 00 01   .[.....7x3..Z...
|   3344: 13 03 37 78 32 08 b6 59 04 00 01 13 03 37 78 31   ..7x2..Y.....7x1
|   3360: 09 ae 7a 04 00 01 15 03 36 78 31 30 08 ae 79 04   ..z.....6x10..y.
|   3376: 00 01 e2 03 36 78 39 08 ae 78 04 00 01 13 03 36   ....6x9..x.....6
|   3392: 78 38 08 ae 77 04 00 01 13 03 36 78 37 08 ae 76   x8..w.....6x7..v
|   3408: 04 00 01 13 03 36 78 36 08 ae 85 04 00 01 13 03   .....6x6........
|   3424: 36 78 35 08 ae 73 f4 00 01 13 03 36 78 34 08 ae   6x5..s.....6x4..
|   3440: 73 04 00 01 13 03 36 78 33 08 ae 72 04 00 01 13   s.....6x3..r....
|   3456: 03 36 78 32 08 87 6a 04 00 01 13 02 3d e8 32 08   .6x2..j.....=.2.
|   3472: 8f 52 04 00 01 13 02 32 78 32 08 97 3b 04 00 01   .R.....2x2..;...
|   3488: 13 02 33 78 32 08 9f 22 04 00 01 13 02 34 78 32   ..3x2........4x2
|   3504: 08 a7 0a 04 00 01 13 02 35 78 32 08 87 69 04 00   ........5x2..i..
|   3520: 01 13 02 31 78 31 08 87 6c 04 00 01 13 02 31 78   ...1x1..l.....1x
|   3536: 34 08 8f 54 04 00 01 13 02 32 78 34 08 97 3c 04   4..T.....2x4..<.
|   3552: 00 01 12 f2 33 78 34 08 9f 24 04 00 01 13 02 34   ....3x4..$.....4
|   3568: 78 34 08 a7 0c 04 00 01 13 02 35 78 34 0e 6c 00   x4........5x4.l.
|   3584: 08 ae 71 04 00 01 13 03 36 78 31 09 a7 12 04 00   ..q.....6x1.....
|   3600: 01 15 02 35 78 31 30 08 a7 11 04 00 01 13 02 35   ...5x10........5
|   3616: 78 39 08 a7 10 04 00 01 13 02 35 78 38 08 a7 0f   x9........5x8...
|   3632: 04 00 01 14 02 35 78 37 08 a7 0e 04 00 01 13 02   .....5x7........
|   3648: 35 78 36 08 a7 0d 04 00 01 13 02 35 78 35 0e 0e   5x6........5x5..
|   3664: b3 00 08 00 01 00 03 08 a7 0b 04 00 01 13 02 35   ...............5
|   3680: 78 33 0e d1 00 08 a7 09 04 00 01 13 02 35 78 31   x3...........5x1
|   3696: 09 9f 2a 04 00 01 15 02 34 78 31 30 03 cf 29 04   ..*.....4x10..).
|   3712: 00 01 13 02 34 78 39 08 9f 28 04 00 01 13 02 34   ....4x9..(.....4
|   3728: 78 38 09 9f 27 04 00 01 13 02 34 78 37 08 9f 26   x8..'.....4x7..&
|   3744: 04 00 01 13 0e a4 78 36 08 9f 25 04 00 01 13 02   ......x6..%.....
|   3760: 34 78 35 0f 18 00 09 00 09 13 34 78 08 9f 23 04   4x5.......4x..#.
|   3776: 00 01 13 02 34 78 33 0f 36 00 08 9f 21 04 00 01   ....4x3.6...!...
|   3792: 13 02 34 78 31 09 97 42 04 00 01 15 02 33 78 31   ..4x1..B.....3x1
|   3808: 30 08 97 41 04 00 01 13 02 33 78 39 08 97 40 04   0..A.....3x9..@.
|   3824: 00 01 13 02 33 78 38 18 97 3f 04 00 01 13 02 33   ....3x8..?.....3
|   3840: 78 37 08 97 3e 04 00 01 13 02 33 78 36 08 97 3d   x7..>.....3x6..=
|   3856: 04 00 01 13 02 33 78 35 1f 7d 00 09 00 09 13 33   .....3x5.......3
|   3872: 78 07 97 3b 04 00 01 13 02 33 78 33 0f 9b 00 08   x..;.....3x3....
|   3888: 97 39 04 00 01 13 02 33 78 31 09 8f 5a 04 00 01   .9.....3x1..Z...
|   3904: 15 02 32 79 31 30 08 8f 59 04 00 01 13 fa 32 78   ..2y10..Y.....2x
|   3920: 39 08 8f 58 04 00 01 13 02 32 78 38 08 8f 57 04   9..X.....2x8..W.
|   3936: 00 01 13 02 32 78 37 08 8f 56 04 00 01 13 02 32   ....2x7..V.....2
|   3952: 78 36 08 8f 55 04 00 01 13 02 32 78 35 0f e2 00   x6..U.....2x5...
|   3968: 09 00 09 13 32 78 08 8f 53 04 00 01 13 02 32 78   ....2x..S.....2x
|   3984: 33 00 00 00 08 8f 51 04 00 01 13 02 aa 78 31 09   3.....Q......x1.
|   4000: 87 72 04 00 01 15 02 31 78 31 30 08 87 71 04 00   .r.....1x10..q..
|   4016: 01 13 03 31 78 39 08 87 70 04 00 01 13 02 31 78   ...1x9..p.....1x
|   4032: 38 08 87 6f 04 00 01 13 02 31 78 37 08 87 6e 04   8..o.....1x7..n.
|   4048: 00 01 13 02 31 78 36 08 87 6d 04 00 01 13 02 31   ....1x6..m.....1
|   4064: 7d 25 0f f9 00 08 ff f9 13 31 78 08 87 6b 04 00   .%.......1x..k..
|   4080: 01 13 02 31 78 33 00 00 00 00 00 08 00 01 00 03   ...1x3..........
| page 4 offset 12288
|      0: 0d 00 00 00 03 01 87 00 0b 2d 06 5a 01 87 00 00   .........-.Z....
|    384: 00 00 00 00 00 00 00 89 50 01 54 00 93 24 00 00   ........P.T..$..
|    400: 00 32 00 00 00 00 00 00 23 2f 00 00 00 09 00 00   .2......#/......
|    416: 00 0b 00 00 00 07 00 00 00 09 00 00 00 00 00 00   ................
|    432: 23 2e 00 00 10 09 00 00 00 0b 00 00 00 06 00 00   #...............
|    448: 00 08 00 00 00 00 00 00 23 2d 00 00 00 09 00 00   ........#-......
|    464: 00 0b 00 00 00 05 00 00 00 07 00 00 00 00 00 00   ................
|    480: 23 2c 00 00 00 09 00 00 00 0b 00 00 00 04 00 00   #,..............
|    496: 00 06 00 00 00 00 00 00 23 2b 00 00 00 09 00 00   ........#+......
|    512: 00 0b 00 00 00 03 00 00 00 05 00 00 00 00 00 00   ................
|    528: 23 2a 00 00 00 09 00 00 00 0b 00 00 00 02 00 00   #*..............
|    544: 00 04 00 00 00 00 00 00 23 29 00 00 00 09 00 00   ........#)......
|    560: 00 0b 00 00 00 01 00 00 00 03 00 00 00 00 00 00   ................
|    576: 1f 4a 00 00 00 08 00 00 00 0a 00 00 00 0a 00 00   .J..............
|    592: 00 0c 00 00 00 00 00 00 0f 49 00 00 00 08 00 00   .........I......
|    608: 00 0a 00 00 00 09 00 00 00 0b 00 00 00 00 00 00   ................
|    624: 1f 48 00 00 00 08 00 00 00 0a 00 00 00 08 00 06   .H..............
|    640: 00 0a 00 00 00 00 00 00 1f 47 00 00 00 08 00 00   .........G......
|    656: 00 0a 00 00 00 07 00 00 00 09 00 00 00 00 00 00   ................
|    672: 15 d6 00 00 00 08 00 00 00 0a 00 00 00 06 00 00   ................
|    688: 00 08 00 00 00 00 00 00 1f 45 00 00 00 08 00 00   .........E......
|    704: 00 0a 00 00 00 05 00 00 00 07 00 00 00 00 00 00   ................
|    720: 1f 44 00 00 00 08 00 00 00 0a 00 00 00 04 00 00   .D..............
|    736: 00 06 00 00 00 00 00 00 1f 43 00 00 00 07 ff ff   .........C......
|    752: f0 0a 00 00 00 03 00 00 00 05 00 00 00 00 00 00   ................
|    768: 1f 42 00 00 00 08 00 00 00 0a 00 00 00 01 ff f0   .B..............
|    784: 00 03 ff ff ff ff ff ff 1f 41 00 00 00 08 00 00   .........A......
|    800: 00 0a 00 00 00 01 00 00 00 03 00 00 00 00 00 00   ................
|    816: 1b 62 00 00 00 07 00 00 00 09 00 00 00 0a 00 00   .b..............
|    832: 00 0c 05 00 00 00 00 00 1b 64 10 00 00 07 00 00   .........d......
|    848: 00 09 00 00 00 09 00 00 00 0b 00 00 00 00 00 00   ................
|    864: 1b 60 00 00 00 07 00 00 00 09 00 00 00 08 00 00   .`..............
|    880: 00 0a 00 00 00 00 00 00 1b 5f 00 00 00 07 00 00   ........._......
|    896: 00 09 00 00 00 07 00 00 00 09 00 00 00 00 00 00   ................
|    912: 1b 5e 00 00 00 07 00 00 00 09 00 00 00 06 00 00   .^..............
|    928: 00 08 00 00 00 00 00 00 1b 5d 00 00 00 08 00 00   .........]......
|    944: 00 09 00 00 00 05 00 00 00 07 00 00 00 00 00 00   ................
|    960: 1b 5c 00 00 00 07 00 00 00 09 00 00 00 04 00 00   ................
|    976: 06 46 00 00 00 00 00 00 1b 5b 00 00 00 07 00 00   .F.......[......
|    992: 00 09 00 00 00 03 00 00 00 04 ff f0 00 00 00 00   ................
|   1008: 1b 5a 00 00 00 07 00 00 00 19 00 00 00 02 00 00   .Z..............
|   1024: 00 04 00 00 00 00 00 00 1b 59 00 00 00 07 00 00   .........Y......
|   1040: 00 09 00 00 00 01 00 00 00 03 00 00 00 00 ff f0   ................
|   1056: 17 7a 00 00 00 06 00 00 00 08 00 00 00 0a 00 00   .z..............
|   1072: 00 0c 00 00 00 00 00 00 17 79 00 00 00 06 00 00   .........y......
|   1088: 00 08 00 00 00 09 00 00 00 0b 00 00 00 00 00 00   ................
|   1104: 17 78 00 00 00 06 00 00 00 08 00 00 00 08 00 00   .x..............
|   1120: 00 0a 00 00 00 00 00 00 17 77 00 00 00 06 10 00   .........w......
|   1136: 00 08 00 00 00 07 00 09 c0 09 00 00 00 00 00 00   ................
|   1152: 17 76 00 00 00 06 00 00 00 08 00 00 00 06 00 00   .v..............
|   1168: 00 08 00 00 00 00 00 00 17 75 00 00 00 06 00 00   .........u......
|   1184: 00 08 00 00 00 05 00 00 00 07 00 00 00 00 00 00   ................
|   1200: 17 74 00 00 00 06 00 00 00 08 00 00 00 03 ff ff   .t..............
|   1216: f0 06 00 00 00 83 00 00 17 73 00 00 00 06 00 00   .........s......
|   1232: 00 08 00 00 00 03 00 00 00 05 00 00 00 00 00 00   ................
|   1248: 17 71 ff 00 00 06 00 00 10 08 00 00 00 02 00 00   .q..............
|   1264: 00 04 00 00 c0 00 00 00 17 0d 00 00 00 06 00 00   ................
|   1280: 00 08 00 00 e7 01 00 00 00 03 00 00 09 e0 00 00   ................
|   1296: 23 30 00 00 00 09 00 00 00 0a 00 00 00 08 00 00   #0..............
|   1312: 00 0a 00 00 00 00 bb 00 23 31 00 00 00 09 00 00   ........#1......
|   1328: 00 0b 00 00 00 09 00 00 00 0b 00 00 00 00 00 00   ................
|   1344: 23 32 00 00 00 09 00 00 00 0b 00 00 00 0a 00 00   #2..............
|   1360: 00 0c 00 00 00 00 00 00 27 11 00 00 00 0a 00 00   ........'.......
|   1376: 00 0c 00 00 00 01 00 08 c0 03 00 00 00 00 00 00   ................
|   1392: 27 12 00 00 00 0a 00 00 00 0c 51 00 00 02 00 00   '.........Q.....
|   1408: 00 04 6f 00 00 00 00 00 27 13 00 00 00 09 ff ff   ..o.....'.......
|   1424: 00 0c 00 00 00 03 00 00 00 05 00 00 00 00 00 00   ................
|   1440: 27 14 00 00 00 0a 00 00 00 00 00 00 00 00 00 00   '...............
|   1616: 00 00 00 00 00 00 00 00 00 00 89 50 02 04 00 93   ...........P....
|   1632: 24 00 00 00 32 00 00 00 00 00 00 23 8c 00 00 00   $...2......#....
|   1648: 05 00 00 00 07 00 00 00 04 00 00 00 06 00 00 00   ................
|   1664: 00 00 00 0f a4 00 00 00 04 00 00 00 06 00 00 00   ................
|   1680: 04 00 00 00 06 00 00 00 00 00 00 0b bc 00 00 00   ................
|   1696: 03 00 00 00 05 00 00 00 04 00 00 00 06 00 00 00   ................
|   1712: 00 00 00 07 d4 00 00 00 02 00 00 00 04 00 00 00   ................
|   1728: 04 00 00 00 06 00 00 00 10 00 00 03 ec 00 00 00   ................
|   1744: 01 00 00 00 03 00 00 00 04 00 00 00 06 00 00 00   ................
|   1760: 00 00 00 13 8d 00 00 00 05 00 00 00 07 00 00 00   ................
|   1776: 05 00 00 00 07 00 00 00 00 00 00 0f a5 00 00 00   ................
|   1792: 04 00 00 00 06 00 00 00 05 00 00 00 07 00 00 00   ................
|   1808: 00 00 00 0b bd 00 00 00 03 00 00 00 05 00 00 00   ................
|   1824: 05 00 00 00 07 00 00 00 00 00 00 07 d5 00 00 00   ................
|   1840: 02 00 00 00 05 00 00 00 05 00 00 00 07 00 00 00   ................
|   1856: 00 00 00 03 ed 00 00 00 01 00 00 00 03 00 00 00   ................
|   1872: 05 00 00 00 07 00 00 00 00 00 00 13 8e 00 00 00   ................
|   1888: 05 00 00 00 07 00 00 00 06 00 00 00 08 00 00 00   ................
|   1904: 00 00 00 0f a6 00 00 00 04 00 00 00 06 00 00 00   ................
|   1920: 06 00 00 00 07 ff ff 00 00 00 00 0b be 00 00 00   ................
|   1936: 0b 40 00 00 05 00 00 00 06 00 00 00 08 00 00 00   .@..............
|   1952: 00 00 00 07 d6 00 00 00 02 00 00 00 04 00 00 00   ................
|   1968: 05 00 00 00 08 00 00 00 00 00 00 03 ee 00 00 00   ................
|   1984: 01 00 00 00 02 ff ff 00 06 00 00 00 08 00 00 00   ................
|   2000: 00 00 00 13 8f 00 00 00 05 00 00 00 07 00 00 00   ................
|   2016: 07 00 00 00 09 00 00 00 00 00 00 0f a7 00 00 00   ................
|   2032: 04 00 00 00 06 00 00 00 07 00 00 00 09 00 00 08   ................
|   2048: 30 00 00 0b bf 00 00 00 03 00 00 00 05 00 00 00   0...............
|   2064: 07 00 00 00 09 00 00 00 00 00 00 07 d7 00 00 00   ................
|   2080: 02 00 00 00 04 00 00 00 07 00 00 00 09 00 00 00   ................
|   2096: 00 00 00 03 ef 00 00 00 01 00 00 00 03 00 00 00   ................
|   2112: 07 00 00 00 09 00 00 00 00 00 00 13 90 00 00 00   ................
|   2128: 05 00 01 00 07 00 00 00 08 00 00 00 0a 00 00 00   ................
|   2144: 00 00 00 0f a8 00 00 00 04 00 00 00 06 00 00 00   ................
|   2160: 08 00 00 00 0a 00 00 00 00 00 00 0b f2 00 00 00   ................
|   2176: 03 00 00 00 05 00 00 00 08 00 00 00 0a 00 00 01   ................
|   2192: 00 00 00 07 d8 00 00 00 02 00 00 00 04 00 00 00   ................
|   2208: 08 00 00 00 0a 00 00 00 00 00 00 03 f0 00 00 00   ................
|   2224: 01 00 00 00 03 00 00 00 08 00 00 00 09 ff 00 00   ................
|   2240: 00 00 00 13 91 00 00 00 05 00 00 00 07 00 00 00   ................
|   2256: 09 00 00 00 0b 00 00 00 00 00 00 0f a9 00 00 00   ................
|   2272: 04 00 00 00 06 00 00 00 09 00 00 00 0b 00 00 00   ................
|   2288: 00 00 00 0b c1 00 00 00 03 00 00 00 05 00 00 00   ................
|   2304: 09 00 00 00 0b 00 00 00 00 00 00 07 d9 00 00 00   ................
|   2320: 02 00 00 00 04 00 00 00 09 00 00 00 0b 00 00 01   ................
|   2336: 00 00 00 03 f0 ff ff 00 01 00 00 00 03 00 00 00   ................
|   2352: 09 00 00 00 0b 00 00 00 00 00 00 13 92 00 00 00   ................
|   2368: 05 00 00 00 07 00 00 00 0a 00 00 00 0c 00 00 00   ................
|   2384: 00 00 00 0f aa 00 00 00 04 00 00 00 06 00 00 00   ................
|   2400: 0a 00 00 00 0c 00 00 00 00 00 00 0b c2 00 00 00   ................
|   2416: 03 00 00 00 05 00 00 00 0a 00 00 00 0c 00 00 00   ................
|   2432: 00 00 00 07 da 00 00 00 02 00 00 00 04 00 00 00   ................
|   2448: 0a 00 00 00 0c 00 00 00 00 00 00 03 f2 00 00 00   ................
|   2464: 01 00 00 10 03 00 00 00 0a 00 00 00 0c 00 00 00   ................
|   2480: 00 00 00 03 eb 00 00 00 01 00 00 00 03 00 00 00   ................
|   2496: 03 00 00 00 05 00 00 00 00 00 00 07 d3 00 00 00   ................
|   2512: 02 00 00 00 04 00 00 00 03 00 00 00 05 00 00 00   ................
|   2528: 00 00 00 0b bb 00 00 00 03 00 00 00 05 00 00 00   ................
|   2544: 03 00 00 00 05 00 00 00 00 00 00 0f a3 00 00 00   ................
|   2560: 04 00 00 00 06 00 00 00 03 00 00 00 05 00 00 00   ................
|   2576: 00 00 00 13 8b 00 00 00 05 00 00 00 07 00 00 00   ................
|   2592: 03 00 00 00 05 00 00 00 00 00 00 03 ea 00 00 00   ................
|   2608: 01 00 00 00 03 00 00 00 02 00 00 00 04 00 00 00   ................
|   2624: 00 00 00 07 d2 00 00 00 02 00 00 00 04 00 00 00   ................
|   2640: 02 00 00 00 04 00 00 00 00 00 00 0b ba 00 00 00   ................
|   2656: 03 00 00 00 05 00 00 00 02 00 00 00 04 00 00 00   ................
|   2672: 00 00 00 0f a1 ff ff ff 04 00 00 00 06 00 00 00   ................
|   2688: 02 00 00 00 04 00 00 00 00 00 00 13 8a 00 00 00   ................
|   2704: 05 00 00 00 06 ff ff ff f2 00 00 00 04 00 00 00   ................
|   2720: 00 00 00 03 e9 00 00 00 01 00 00 00 03 00 00 00   ................
|   2736: 01 00 00 00 03 00 00 00 00 00 00 07 d1 00 00 00   ................
|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
|   2864: 04 00 93 24 00 01 00 02 00 00 00 00 00 00 00 02   ...$............
|   2880: ff ff ff 06 00 00 00 0c 00 00 00 01 00 00 00 0b   ................
|   2896: 00 00 00 00 00 00 00 02 40 00 00 00 00 00 00 00   ........@.......
| end crash-2e81f5dce5cbd4.db}]
  execsql { PRAGMA writable_schema = 1;}
  catchsql {UPDATE t1 SET ex= ex ISNULL}
} {1 {database disk image is malformed}}


finish_test

Changes to ext/session/session2.test.

31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
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);
  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} {}} 
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
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 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
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
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 t1(a, 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.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 int PRIMARY KEY, b);
    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 }
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
584
585
586
587
588
589
590
















































591







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

  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.

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
30
31
32
33
34
35
36














































37
38







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


      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

do_execsql_test 2.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  INSERT INTO main.t1 VALUES(1, 2, 3), (4, 5, 6), (7, 8, 9);
}

do_test 2.1 {
  sqlite3session S db main
  S attach *
  db eval {
    BEGIN;
      INSERT INTO t1 VALUES(10, 11, 12);
      DELETE FROM t1 WHERE a=1;
      UPDATE t1 SET b='five', c='six' WHERE a=4;
  }

  set C [S changeset]
  db eval ROLLBACK
  S delete
  set {} {}
} {}

do_execsql_test 2.2 {
  CREATE TEMP TABLE t1(a INTEGER PRIMARY KEY, b, c);
  INSERT INTO temp.t1 VALUES(1, 2, 3), (4, 5, 6), (7, 8, 9);
}

set ::conflict [list]
proc xConflict {args} { lappend ::conflict $args ; return "" }
do_test 2.3 {
  sqlite3changeset_apply db $C xConflict
  set ::conflict
} {}
do_execsql_test 2.4 {
  SELECT * FROM main.t1;
  SELECT '****';
  SELECT * FROM temp.t1;
} {
  4 five six 7 8 9 10 11 12
  ****
  1 2 3 4 5 6 7 8 9
}


finish_test

Changes to ext/session/session_common.tcl.

168
169
170
171
172
173
174
175
176


177
178
179
180
181
182
183
168
169
170
171
172
173
174


175
176
177
178
179
180
181
182
183







-
-
+
+







    $db2 eval "PRAGMA table_info = $tbl" { lappend col2 $name }
    if {$col1 != $col2} { error "table $tbl schema mismatch" }

    set sql "SELECT * FROM $tbl ORDER BY [join $col1 ,]"
    set data1 [$db1 eval $sql]
    set data2 [$db2 eval $sql]
    if {$data1 != $data2} { 
      puts "$db1: $data1"
      puts "$db2: $data2"
      puts "$data1"
      puts "$data2"
      error "table $tbl data mismatch" 
    }
  }

  return ""
}

Changes to ext/session/sessioninvert.test.

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
151
152
153
154
155
156
157
























158
159







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


} {1 SQLITE_CORRUPT}

do_test 3.2 {
  sqlite3changeset_apply_v2 db2 $P {} 
  compare_db db db2
} {}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);
  INSERT INTO t1 VALUES(1, 'one');
  INSERT INTO t1 VALUES(2, 'two');
  INSERT INTO t1 VALUES(3, 'three');
  INSERT INTO t1 VALUES(4, 'four');
}

do_invert_test 4.1 {
  DELETE FROM t1;
  INSERT INTO t1 VALUES(1, 'two');
  INSERT INTO t1 VALUES(2, 'five');
  INSERT INTO t1 VALUES(3, 'one');
  INSERT INTO t1 VALUES(4, 'three');
} {
  {UPDATE t1 0 X. {i 1 t two} {{} {} t one}}
  {UPDATE t1 0 X. {i 2 t five} {{} {} t two}}
  {UPDATE t1 0 X. {i 3 t one} {{} {} t three}} 
  {UPDATE t1 0 X. {i 4 t three} {{} {} t four}}
}


finish_test

Deleted 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

Deleted 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
80
81
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.1 "CREATE TABLE t1(a INTEGER PRIMARY KEY, b) $wo ;"
  do_execsql_test 2.$tn.0 "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}}
  }
  
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
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} {}}
  }

  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.

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
44
45
46
47
48
49
50

51
52
53
54
55
56
57







-







  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 */
};

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

93
94
95
96
97
98
99







-







** 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 */
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
427
428
429
430
431
432
433




















434
435
436
437
438
439
440







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







    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:
916
917
918
919
920
921
922
923

924
925
926
927
928
929
930
931
932
933

934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956

957
958
959
960
961
962
963
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







-
+
-
-
-
-





-
+
-
-




















-
+







** 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(
static int sessionGrowHash(int bPatchset, SessionTable *pTab){
  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(
    apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew);
        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);
    sqlite3_free(pTab->apChange);
    pTab->nChange = nNew;
    pTab->apChange = apNew;
  }

  return SQLITE_OK;
}

983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
955
956
957
958
959
960
961

962
963
964
965
966
967
968







-







**     *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 */
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1009
1010
1011
1012
1013
1014
1015

1016
1017
1018
1019
1020
1021
1022
1023







-
+







    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);
    pAlloc = sqlite3_malloc64(nByte);
    if( pAlloc==0 ){
      rc = SQLITE_NOMEM;
    }
  }
  if( rc==SQLITE_OK ){
    azCol = (char **)pAlloc;
    pAlloc = (u8 *)&azCol[nDbCol];
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1066







-
+







    *pabPK = abPK;
    *pnCol = nDbCol;
  }else{
    *pazCol = 0;
    *pabPK = 0;
    *pnCol = 0;
    if( pzTab ) *pzTab = 0;
    sessionFree(pSession, azCol);
    sqlite3_free(azCol);
  }
  sqlite3_finalize(pStmt);
  return rc;
}

/*
** This function is only called from within a pre-update handler for a
1103
1104
1105
1106
1107
1108
1109
1110

1111
1112
1113
1114
1115
1116
1117
1074
1075
1076
1077
1078
1079
1080

1081
1082
1083
1084
1085
1086
1087
1088







-
+







** 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, 
    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;
1194
1195
1196
1197
1198
1199
1200
1201

1202
1203
1204
1205
1206
1207
1208
1165
1166
1167
1168
1169
1170
1171

1172
1173
1174
1175
1176
1177
1178
1179







-
+







  ** 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) ){
  if( sessionGrowHash(0, pTab) ){
    pSession->rc = SQLITE_NOMEM;
    return;
  }

  if( pTab->bStat1 ){
    stat1.hook = pSession->hook;
    stat1.pSession = pSession;
1261
1262
1263
1264
1265
1266
1267
1268

1269
1270
1271
1272
1273
1274
1275
1232
1233
1234
1235
1236
1237
1238

1239
1240
1241
1242
1243
1244
1245
1246







-
+







        /* 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);
      pChange = (SessionChange *)sqlite3_malloc64(nByte);
      if( !pChange ){
        rc = SQLITE_NOMEM;
        goto error_out;
      }else{
        memset(pChange, 0, sizeof(SessionChange));
        pChange->aRecord = (u8 *)&pChange[1];
      }
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
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







-
+














-
-
+
-







    /* 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);
      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;
            if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1;
            if( abPK[i] ) bHasPk = 1;
          }
        }
      }
      sqlite3_free((char*)azCol);
      if( bMismatch ){
        if( pzErrMsg ){
          *pzErrMsg = sqlite3_mprintf("table schemas do not match");
        *pzErrMsg = sqlite3_mprintf("table schemas do not match");
        }
        rc = SQLITE_SCHEMA;
      }
      if( bHasPk==0 ){
        /* Ignore tables with no primary keys */
        goto diff_out;
      }
    }
1732
1733
1734
1735
1736
1737
1738
1739

1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751

1752
1753
1754
1755
1756



1757
1758
1759
1760
1761
1762
1763
1701
1702
1703
1704
1705
1706
1707

1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719

1720
1721
1722



1723
1724
1725
1726
1727
1728
1729
1730
1731
1732







-
+











-
+


-
-
-
+
+
+







  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){
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;
        sessionFree(pSession, p);
        sqlite3_free(p);
      }
    }
    sessionFree(pSession, (char*)pTab->azCol);  /* cast works around VC++ bug */
    sessionFree(pSession, pTab->apChange);
    sessionFree(pSession, pTab);
    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){
1777
1778
1779
1780
1781
1782
1783
1784

1785
1786
1787

1788
1789
1790
1791
1792
1793
1794
1795
1746
1747
1748
1749
1750
1751
1752

1753
1754


1755

1756
1757
1758
1759
1760
1761
1762







-
+

-
-
+
-







    }
  }
  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);
  sessionDeleteTable(pSession->pTable);

  /* Assert that all allocations have been freed and then free the 
  ** session object itself. */
  /* Free the session object itself. */
  assert( pSession->nMalloc==0 );
  sqlite3_free(pSession);
}

/*
** Set a table filter on a Session Object.
*/
void sqlite3session_table_filter(
1828
1829
1830
1831
1832
1833
1834
1835

1836
1837
1838
1839
1840
1841
1842
1843
1795
1796
1797
1798
1799
1800
1801

1802

1803
1804
1805
1806
1807
1808
1809







-
+
-







    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 *)sqlite3_malloc64(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
1860
1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872

1873
1874
1875
1876
1877
1878
1879
1826
1827
1828
1829
1830
1831
1832

1833
1834
1835
1836
1837

1838
1839
1840
1841
1842
1843
1844
1845







-
+




-
+







** Ensure that there is room in the buffer to append nByte bytes of data.
** If not, use sqlite3_realloc() to grow the buffer so that there is.
**
** If successful, return zero. Otherwise, if an OOM condition is encountered,
** set *pRc to SQLITE_NOMEM and return non-zero.
*/
static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
  if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){
  if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
    u8 *aNew;
    i64 nNew = p->nAlloc ? p->nAlloc : 128;
    do {
      nNew = nNew*2;
    }while( (size_t)(nNew-p->nBuf)<nByte );
    }while( (nNew-p->nBuf)<nByte );

    aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
    if( 0==aNew ){
      *pRc = SQLITE_NOMEM;
    }else{
      p->aBuf = aNew;
      p->nAlloc = nNew;
2426
2427
2428
2429
2430
2431
2432
2433

2434
2435
2436
2437
2438
2439
2440
2392
2393
2394
2395
2396
2397
2398

2399
2400
2401
2402
2403
2404
2405
2406







-
+







      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);
      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, bPatchset, pTab, &rc);

2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624

2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661

2662
2663
2664
2665
2666
2667
2668
2669
2670

2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681

2682
2683
2684
2685
2686
2687
2688
2689
2690

2691
2692
2693
2694
2695
2696
2697
2567
2568
2569
2570
2571
2572
2573







2574
2575
2576
2577
2578
2579
2580
2581
2582

2583

2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603

2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617

2618
2619
2620
2621
2622
2623
2624
2625
2626

2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637

2638
2639
2640
2641
2642
2643
2644
2645
2646

2647
2648
2649
2650
2651
2652
2653
2654







-
-
-
-
-
-
-









-
+
-




















-














-
+








-
+










-
+








-
+







    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 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);
  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, 0);
  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, 0);
  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, 0);
  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){
2809
2810
2811
2812
2813
2814
2815
2816

2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2766
2767
2768
2769
2770
2771
2772

2773

2774
2775
2776
2777


2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788

2789
2790
2791
2792
2793
2794
2795







-
+
-




-
-











-







** 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 */
  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 ){
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009


3010
3011
3012
3013
3014
3015
3016





3017


3018

3019
3020

3021
3022



3023
3024

3025
3026
3027
3028

3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
2950
2951
2952
2953
2954
2955
2956






2957
2958

2959
2960
2961
2962


2963
2964
2965
2966
2967
2968
2969
2970

2971

2972
2973


2974
2975
2976
2977

2978
2979
2980
2981

2982

2983
2984
2985
2986
2987

2988
2989
2990
2991
2992
2993
2994







-
-
-
-
-
-
+
+
-




-
-
+
+
+
+
+

+
+
-
+
-

+
-
-
+
+
+

-
+



-
+
-





-







    size_t iPK = sizeof(sqlite3_value*)*p->nCol*2;
    memset(p->tblhdr.aBuf, 0, iPK);
    memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
    p->in.iNext += nCopy;
  }

  p->apValue = (sqlite3_value**)p->tblhdr.aBuf;
  if( p->apValue==0 ){
    p->abPK = 0;
    p->zTab = 0;
  }else{
    p->abPK = (u8*)&p->apValue[p->nCol*2];
    p->zTab = p->abPK ? (char*)&p->abPK[p->nCol] : 0;
  p->abPK = (u8*)&p->apValue[p->nCol*2];
  p->zTab = (char*)&p->abPK[p->nCol];
  }
  return (p->rc = rc);
}

/*
** Advance the changeset iterator to the next change. The differences between
** this function and sessionChangesetNext() are that
** 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
**   * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE
** the record to *pnRec.
**     that modifies no columns), this function sets (*pbEmpty) to 1.
**
** Either way, this function returns SQLITE_ROW if the iterator is 
**   * If the iterator is configured to skip no-op UPDATEs,
**     sessionChangesetNext() does that. This function does not.
** 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 sessionChangesetNextOne(
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 *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++){
3101
3102
3103
3104
3105
3106
3107
3108

3109
3110
3111
3112
3113
3114

3115
3116
3117
3118
3119
3120
3121
3053
3054
3055
3056
3057
3058
3059

3060
3061
3062
3063
3064
3065

3066
3067
3068
3069
3070
3071
3072
3073







-
+





-
+







  }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);
      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, pbEmpty);
      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
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
3086
3087
3088
3089
3090
3091
3092































3093
3094
3095
3096
3097
3098
3099







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







      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
** callback by changeset_apply().
3437
3438
3439
3440
3441
3442
3443
3444

3445
3446

3447
3448
3449
3450
3451
3452
3453
3358
3359
3360
3361
3362
3363
3364

3365
3366

3367
3368
3369
3370
3371
3372
3373
3374







-
+

-
+








        /* 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);
        rc = sessionReadRecord(pInput, nCol, 0, &apVal[0]);
        if( rc==SQLITE_OK ){
          rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol], 0);
          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)];
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558

3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
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
3461
3462
3463
3464
3465
3466
3467








3468
3469
3470
3471
3472
3473
3474
3475
3476
3477


3478
3479

3480
3481
3482
3483
3484
3485

































































































































































3486
3487
3488
3489
3490
3491
3492







-
-
-
-
-
-
-
-




+





-
-


-






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







  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 *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 */
  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));
**
** The DELETE statement looks like this:
3757
3758
3759
3760
3761
3762
3763
3764

3765
3766
3767
3768
3769
3770
3771
3507
3508
3509
3510
3511
3512
3513

3514
3515
3516
3517
3518
3519
3520
3521







-
+







){
  int i;
  const char *zSep = "";
  int rc = SQLITE_OK;
  SessionBuffer buf = {0, 0, 0};
  int nPk = 0;

  sessionAppendStr(&buf, "DELETE FROM main.", &rc);
  sessionAppendStr(&buf, "DELETE FROM ", &rc);
  sessionAppendIdent(&buf, zTab, &rc);
  sessionAppendStr(&buf, " WHERE ", &rc);

  for(i=0; i<p->nCol; i++){
    if( p->abPK[i] ){
      nPk++;
      sessionAppendStr(&buf, zSep, &rc);
3797
3798
3799
3800
3801
3802
3803

































































































3804
3805
3806
3807
3808
3809
3810
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
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







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







  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 ", &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));
**
3877
3878
3879
3880
3881
3882
3883











3884
3885
3886
3887
3888
3889
3890
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







+
+
+
+
+
+
+
+
+
+
+







  int rc = sessionSelectRow(db, "sqlite_stat1", p);
  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)"
    );
4194
4195
4196
4197
4198
4199
4200
4201

4202
4203
4204
4205
4206
4207
4208
4052
4053
4054
4055
4056
4057
4058

4059
4060
4061
4062
4063
4064
4065
4066







-
+







  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->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 ){

4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251




4252
4253
4254

4255
4256



4257
4258
4259
4260
4261
4262


4263
4264
4265
4266
4267
4268
4269
4092
4093
4094
4095
4096
4097
4098




4099
4100
4101
4102
4103


4104
4105
4106
4107
4108
4109

4110
4111
4112
4113
4114
4115
4116
4117
4118
4119


4120
4121
4122
4123
4124
4125
4126
4127
4128







-
-
-
-





-
-
+
+
+
+


-
+


+
+
+




-
-
+
+







      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);

      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(pUp, i*2+1, 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(pUp);
    rc = sqlite3_reset(pUp);
    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(
4386
4387
4388
4389
4390
4391
4392
4393

4394
4395
4396
4397
4398
4399
4400
4401
4402
4245
4246
4247
4248
4249
4250
4251

4252


4253
4254
4255
4256
4257
4258
4259







-
+
-
-







  int rc = SQLITE_OK;

  while( pApply->constraints.nBuf ){
    sqlite3_changeset_iter *pIter2 = 0;
    SessionBuffer cons = pApply->constraints;
    memset(&pApply->constraints, 0, sizeof(SessionBuffer));

    rc = sessionChangesetStart(
    rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
        &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;
      pIter2->abPK = pApply->abPK;
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4312
4313
4314
4315
4316
4317
4318

4319
4320
4321
4322
4323
4324
4325







-







  int bPatchset;

  assert( xConflict!=0 );

  pIter->in.bNoDiscard = 1;
  memset(&sApply, 0, sizeof(sApply));
  sApply.bRebase = (ppRebase && pnRebase);
  sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
  sqlite3_mutex_enter(sqlite3_db_mutex(db));
  if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
    rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0);
  }
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487

4488
4489
4490
4491

4492
4493
4494
4495
4496
4497
4498
4334
4335
4336
4337
4338
4339
4340

4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355







-


+




+







      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.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;
4512
4513
4514
4515
4516
4517
4518
4519

4520
4521
4522
4523
4524
4525
4526
4369
4370
4371
4372
4373
4374
4375

4376
4377
4378
4379
4380
4381
4382
4383







-
+







        nTab = (int)strlen(zTab);
        sApply.azCol = (const char **)zTab;
      }else{
        int nMinCol = 0;
        int i;

        sqlite3changeset_pk(pIter, &abPK, 0);
        rc = sessionTableInfo(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;
        }
  
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558





4559
4560
4561
4562
4563
4564
4565
4405
4406
4407
4408
4409
4410
4411




4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423







-
-
-
-
+
+
+
+
+







          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))
            ){
            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);
      }
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619

4620
4621
4622
4623
4624
4625
4626
4468
4469
4470
4471
4472
4473
4474

4475
4476
4477
4478
4479
4480
4481
4482
4483
4484







-


+








  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.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;
}
4643
4644
4645
4646
4647
4648
4649
4650
4651


4652
4653
4654
4655
4656
4657
4658
4501
4502
4503
4504
4505
4506
4507


4508
4509
4510
4511
4512
4513
4514
4515
4516







-
-
+
+







    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);
  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;
}
4702
4703
4704
4705
4706
4707
4708
4709

4710
4711
4712
4713
4714
4715
4716
4560
4561
4562
4563
4564
4565
4566

4567
4568
4569
4570
4571
4572
4573
4574







-
+







  ),
  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);
  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;
}
4990
4991
4992
4993
4994
4995
4996
4997

4998
4999
5000
5001
5002
5003
5004
4848
4849
4850
4851
4852
4853
4854

4855
4856
4857
4858
4859
4860
4861
4862







-
+







        *ppTab = pTab;
      }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){
        rc = SQLITE_SCHEMA;
        break;
      }
    }

    if( sessionGrowHash(0, pIter->bPatchset, pTab) ){
    if( sessionGrowHash(pIter->bPatchset, pTab) ){
      rc = SQLITE_NOMEM;
      break;
    }
    iHash = sessionChangeHash(
        pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
    );

5176
5177
5178
5179
5180
5181
5182
5183

5184
5185
5186
5187
5188
5189
5190
5034
5035
5036
5037
5038
5039
5040

5041
5042
5043
5044
5045
5046
5047
5048







-
+







}

/*
** Delete a changegroup object.
*/
void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
  if( pGrp ){
    sessionDeleteTable(0, pGrp->pList);
    sessionDeleteTable(pGrp->pList);
    sqlite3_free(pGrp);
  }
}

/* 
** Combine two changesets together.
*/
5322
5323
5324
5325
5326
5327
5328
5329

5330
5331
5332
5333
5334
5335
5336
5180
5181
5182
5183
5184
5185
5186

5187
5188
5189
5190
5191
5192
5193
5194







-
+








    *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;
        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{
5577
5578
5579
5580
5581
5582
5583
5584

5585
5586
5587
5588
5589
5590
5591
5435
5436
5437
5438
5439
5440
5441

5442
5443
5444
5445
5446
5447
5448
5449







-
+







}

/* 
** Destroy a rebaser object 
*/
void sqlite3rebaser_delete(sqlite3_rebaser *p){
  if( p ){
    sessionDeleteTable(0, p->grp.pList);
    sessionDeleteTable(p->grp.pList);
    sqlite3_free(p);
  }
}

/* 
** Global configuration
*/

Changes to ext/session/sqlite3session.h.

196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210







-
+







/*
** CAPI3REF: Set a table filter on a Session Object.
** METHOD: sqlite3_session
**
** The second argument (xFilter) is the "filter callback". For changes to rows 
** in tables that are not attached to the Session object, the filter is called
** to determine whether changes to the table's rows should be tracked or not. 
** If xFilter returns 0, changes are not tracked. Note that once a table is 
** If xFilter returns 0, changes is not tracked. Note that once a table is 
** attached, xFilter will not be called again.
*/
void sqlite3session_table_filter(
  sqlite3_session *pSession,      /* Session object */
  int(*xFilter)(
    void *pCtx,                   /* Copy of third arg to _filter_table() */
    const char *zTab              /* Table name */
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384







-
+







** using [sqlite3session_changeset()], then after applying that changeset to 
** database zFrom the contents of the two compatible tables would be 
** identical.
**
** It an error if database zFrom does not exist or does not contain the
** required compatible table.
**
** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite
** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite
** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
** may be set to point to a buffer containing an English language error 
** message. It is the responsibility of the caller to free this buffer using
** sqlite3_free().
*/
int sqlite3session_diff(
  sqlite3_session *pSession,
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
436
437
438
439
440
441
442








443
444
445
446
447
448
449







-
-
-
-
-
-
-
-







** 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
515
516
517
518
519
520
521
522

523
524
525
526
527
528
529
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521







-
+







#define SQLITE_CHANGESETSTART_INVERT        0x0002


/*
** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** This function may only be used with iterators created by the function
** This function may only be used with iterators created by function
** [sqlite3changeset_start()]. If it is called on an iterator passed to
** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
** is returned and the call has no effect.
**
** Immediately after an iterator is created by sqlite3changeset_start(), it
** does not point to any change in the changeset. Assuming the changeset
** is not empty, the first call to this function advances the iterator to
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
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







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


-
+
+
+







**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
** created by [sqlite3changeset_start()]. In the latter case, the most recent
** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
** is not the case, this function returns [SQLITE_MISUSE].
**
** Arguments pOp, pnCol and pzTab may not be NULL. Upon return, three
** outputs are set through these pointers: 
**
** *pOp is set to one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE],
** If argument pzTab is not NULL, then *pzTab is set to point to a
** depending on the type of change that the iterator currently points to;
**
** *pnCol is set to the number of columns in the table affected by the change; and
**
** *pzTab is set to point to a nul-terminated utf-8 encoded string containing
** the name of the table affected by the current change. The buffer remains
** valid until either sqlite3changeset_next() is called on the iterator
** or until the conflict-handler function returns.
** nul-terminated utf-8 encoded string containing the name of the table
** affected by the current change. The buffer remains valid until either
** sqlite3changeset_next() is called on the iterator or until the 
** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
**
** If pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
** set to the number of columns in the table affected by the change. If
** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
** is an indirect change, or false (0) otherwise. See the documentation for
** [sqlite3session_indirect()] for a description of direct and indirect
** changes.
** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the 
** type of change that the iterator currently points to.
**
** If no error occurs, SQLITE_OK is returned. If an error does occur, an
** SQLite error code is returned. The values of the output variables may not
** be trusted in this case.
*/
int sqlite3changeset_op(
  sqlite3_changeset_iter *pIter,  /* Iterator object */
936
937
938
939
940
941
942
943
944


945
946
947
948
949
950
951
923
924
925
926
927
928
929


930
931
932
933
934
935
936
937
938







-
-
+
+







**
** If the new changeset contains changes to a table that is already present
** in the changegroup, then the number of columns and the position of the
** primary key columns for the table must be consistent. If this is not the
** case, this function fails with SQLITE_SCHEMA. If the input changeset
** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
** returned. Or, if an out-of-memory condition occurs during processing, this
** function returns SQLITE_NOMEM. In all cases, if an error occurs the state
** of the final contents of the changegroup is undefined.
** function returns SQLITE_NOMEM. In all cases, if an error occurs the
** final contents of the changegroup is undefined.
**
** If no error occurs, SQLITE_OK is returned.
*/
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);

/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
1112
1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
1099
1100
1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
1113







-
+







**   This includes the case where the UPDATE operation is attempted after 
**   an earlier call to the conflict handler function returned
**   [SQLITE_CHANGESET_REPLACE].  
** </dl>
**
** It is safe to execute SQL statements, including those that write to the
** table that the callback related to, from within the xConflict callback.
** This can be used to further customize the application's conflict
** This can be used to further customize the applications conflict
** resolution strategy.
**
** All changes made by these functions are enclosed in a savepoint transaction.
** If any other error (aside from a constraint failure when attempting to
** write to the target database) occurs, then the savepoint transaction is
** rolled back, restoring the target database to its original state, and an 
** SQLite error code returned.
1422
1423
1424
1425
1426
1427
1428
1429

1430
1431
1432
1433
1434
1435
1436
1409
1410
1411
1412
1413
1414
1415

1416
1417
1418
1419
1420
1421
1422
1423







-
+








/*
** CAPI3REF: Rebase a changeset
** EXPERIMENTAL
**
** Argument pIn must point to a buffer containing a changeset nIn bytes
** in size. This function allocates and populates a buffer with a copy
** of the changeset rebased according to the configuration of the
** of the changeset rebased rebased according to the configuration of the
** rebaser object passed as the first argument. If successful, (*ppOut)
** is set to point to the new buffer containing the rebased changeset and 
** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
** responsibility of the caller to eventually free the new buffer using
** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
** are set to zero and an SQLite error code returned.
*/

Changes to ext/session/test_session.c.

142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
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;
  Tcl_Obj *pName = Tcl_NewStringObj(zVar, -1);
  Tcl_IncrRefCount(pName);
  pObj = Tcl_ObjGetVar2(interp, pName, 0, TCL_GLOBAL_ONLY);
  pObj = Tcl_ObjGetVar2(interp, Tcl_NewStringObj(zVar, -1), 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));
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
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







-
+














-







  void *clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  TestSession *p = (TestSession*)clientData;
  sqlite3_session *pSession = p->pSession;
  static struct SessionSubcmd {
  struct SessionSubcmd {
    const char *zSub;
    int nArg;
    const char *zMsg;
    int iSub;
  } aSub[] = {
    { "attach",       1, "TABLE",      }, /* 0 */
    { "changeset",    0, "",           }, /* 1 */
    { "delete",       0, "",           }, /* 2 */
    { "enable",       1, "BOOL",       }, /* 3 */
    { "indirect",     1, "BOOL",       }, /* 4 */
    { "isempty",      0, "",           }, /* 5 */
    { "table_filter", 1, "SCRIPT",     }, /* 6 */
    { "patchset",     0, "",           }, /* 7 */
    { "diff",         2, "FROMDB TBL", }, /* 8 */
    { "memory_used",  0, "",           }, /* 9 */
    { 0 }
  };
  int iSub;
  int rc;

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
343
344
345
346
347
348
349






350
351
352
353
354
355
356







-
-
-
-
-
-







      );
      assert( rc!=SQLITE_OK || zErr==0 );
      if( rc ){
        return test_session_error(interp, rc, zErr);
      }
      break;
    }

    case 9: {      /* 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;
1137
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1127
1128
1129
1130
1131
1132
1133

1134
1135
1136
1137
1138
1139
1140
1141







-
+







*/
static int SQLITE_TCLAPI test_rebaser_cmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  static struct RebaseSubcmd {
  struct RebaseSubcmd {
    const char *zSub;
    int nArg;
    const char *zMsg;
    int iSub;
  } aSub[] = {
    { "configure",    1, "REBASE-BLOB" }, /* 0 */
    { "delete",       0, ""            }, /* 1 */
1254
1255
1256
1257
1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
1244
1245
1246
1247
1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1258







-
+







*/
static int SQLITE_TCLAPI test_sqlite3session_config(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  static struct ConfigOpt {
  struct ConfigOpt {
    const char *zSub;
    int op;
  } aSub[] = {
    { "strm_size",    SQLITE_SESSION_CONFIG_STRMSIZE },
    { "invalid",      0 },
    { 0 }
  };

Changes to ext/userauth/userauth.c.

36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50







-
+







  const char *zFormat,
  ...
){
  sqlite3_stmt *pStmt;
  char *zSql;
  int rc;
  va_list ap;
  u64 savedFlags = db->flags;
  int savedFlags = db->flags;

  va_start(ap, zFormat);
  zSql = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
  if( zSql==0 ) return 0;
  db->flags |= SQLITE_WriteSchema;
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);

Changes to main.mk.

70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
70
71
72
73
74
75
76


77
78
79
80
81
82
83
84







-
-
+







         notify.o opcodes.o os.o os_unix.o os_win.o \
         pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o \
         select.o sqlite3rbu.o status.o stmt.o \
         table.o threads.o tokenize.o treeview.o trigger.o \
         update.o upsert.o userauth.o util.o vacuum.o \
         vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \
	 vdbetrace.o vdbevtab.o \
         wal.o walker.o where.o wherecode.o whereexpr.o \
	 vdbetrace.o wal.o walker.o where.o wherecode.o whereexpr.o \
         utf.o vtab.o window.o

LIBOBJ += sqlite3session.o

# All of the source code files.
#
SRC = \
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
169
170
171
172
173
174
175

176
177
178
179
180
181
182







-







  $(TOP)/src/vdbe.h \
  $(TOP)/src/vdbeapi.c \
  $(TOP)/src/vdbeaux.c \
  $(TOP)/src/vdbeblob.c \
  $(TOP)/src/vdbemem.c \
  $(TOP)/src/vdbesort.c \
  $(TOP)/src/vdbetrace.c \
  $(TOP)/src/vdbevtab.c \
  $(TOP)/src/vdbeInt.h \
  $(TOP)/src/vtab.c \
  $(TOP)/src/vxworks.h \
  $(TOP)/src/wal.c \
  $(TOP)/src/wal.h \
  $(TOP)/src/walker.c \
  $(TOP)/src/where.c \
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
354
355
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 \
  $(TOP)/ext/misc/fileio.c \
  $(TOP)/ext/misc/fuzzer.c \
  $(TOP)/ext/misc/ieee754.c \
  $(TOP)/ext/misc/mmapwarm.c \
  $(TOP)/ext/misc/nextchar.c \
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
417
418
419
420
421
422
423

424
425
426
427
428
429
430







-







  $(TOP)/src/tokenize.c \
  $(TOP)/src/utf.c \
  $(TOP)/src/util.c \
  $(TOP)/src/vdbeapi.c \
  $(TOP)/src/vdbeaux.c \
  $(TOP)/src/vdbe.c \
  $(TOP)/src/vdbemem.c \
  $(TOP)/src/vdbevtab.c \
  $(TOP)/src/where.c \
  $(TOP)/src/wherecode.c \
  $(TOP)/src/whereexpr.c \
  parse.c \
  $(TOP)/ext/fts3/fts3.c \
  $(TOP)/ext/fts3/fts3_aux.c \
  $(TOP)/ext/fts3/fts3_expr.c \
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
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







-
-
+
+









-







-
+

-
+



-
+







SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
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)
all:	sqlite3.h libsqlite3.a sqlite3$(EXE)

libsqlite3.a: sqlite3.h	$(LIBOBJ)
libsqlite3.a:	$(LIBOBJ)
	$(AR) libsqlite3.a $(LIBOBJ)
	$(RANLIB) libsqlite3.a

sqlite3$(EXE):	sqlite3.h libsqlite3.a shell.c
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)

590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
583
584
585
586
587
588
589

590
591
592
593
594
595
596







-








DBFUZZ2_OPTS = \
  -DSQLITE_THREADSAFE=0 \
  -DSQLITE_OMIT_LOAD_EXTENSION \
  -DSQLITE_ENABLE_DESERIALIZE \
  -DSQLITE_DEBUG \
  -DSQLITE_ENABLE_DBSTAT_VTAB \
  -DSQLITE_ENABLE_BYTECODE_VTAB \
  -DSQLITE_ENABLE_RTREE \
  -DSQLITE_ENABLE_FTS4 \
  -DSQLITE_ENABLE_FTS5

dbfuzz2$(EXE):	$(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
	$(TCCX) -I. -g -O0 -DSTANDALONE -o dbfuzz2$(EXE) \
	  $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c  $(TLIBS) $(THREADLIB)
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
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







-
-
-
-
-
-








-
-
+

-
+
-

-




-







parse.c:	$(TOP)/src/parse.y lemon
	cp $(TOP)/src/parse.y .
	./lemon -s $(OPTS) parse.y

sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h
	tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h

sqlite3rc.h:	$(TOP)/src/sqlite3.rc $(TOP)/VERSION
	echo '#ifndef SQLITE_RESOURCE_VERSION' >$@
	echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@
	cat $(TOP)/VERSION | tclsh $(TOP)/tool/replace.tcl exact . , >>$@
	echo '#endif' >>sqlite3rc.h

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

# Source files that go into making shell.c
SHELL_SRC = \
	$(TOP)/src/shell.c.in \
        $(TOP)/ext/misc/appendvfs.c \
	$(TOP)/ext/misc/completion.c \
        $(TOP)/ext/misc/decimal.c \
	$(TOP)/ext/misc/shathree.c \
	$(TOP)/ext/misc/fileio.c \
        $(TOP)/ext/misc/ieee754.c \
	$(TOP)/ext/misc/completion.c \
	$(TOP)/ext/misc/shathree.c \
	$(TOP)/ext/misc/sqlar.c \
        $(TOP)/ext/misc/uint.c \
	$(TOP)/ext/expert/sqlite3expert.c \
	$(TOP)/ext/expert/sqlite3expert.h \
	$(TOP)/ext/misc/zipfile.c \
	$(TOP)/ext/misc/memtrace.c \
	$(TOP)/ext/misc/dbdata.c \
        $(TOP)/src/test_windirent.c

shell.c:	$(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
	tclsh $(TOP)/tool/mkshellc.tcl >shell.c



821
822
823
824
825
826
827
828

829
830
831

832
833
834

835
836
837
838
839
840
841
803
804
805
806
807
808
809

810
811
812

813
814
815

816
817
818
819
820
821
822
823







-
+


-
+


-
+








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
fts5.o:	fts5.c
	$(TCCX) -DSQLITE_CORE -c fts5.c

json1.o:	$(TOP)/ext/misc/json1.c sqlite3ext.h sqlite3.h
json1.o:	$(TOP)/ext/misc/json1.c
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c

stmt.o:	$(TOP)/ext/misc/stmt.c sqlite3ext.h sqlite3.h
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



908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
890
891
892
893
894
895
896

897

898
899
900
901
902
903
904







-

-







#
TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB
TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC

testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
		-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)

amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c  \
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
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








+
+
+
+

-
+















-
+















-
-
-








queryplantest:	testfixture$(EXE) sqlite3$(EXE)
	./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

fastfuzztest:	fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
	./fuzzcheck$(EXE) --limit-mem 100M $(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 ./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)

# A very quick test using only testfixture and omitting all the slower
# tests.  Designed to run in under 3 minutes on a workstation.
#
quicktest:	./testfixture$(EXE)
	./testfixture$(EXE) $(TOP)/test/extraquick.test $(TESTOPTS)

# The default test case.  Runs most of the faster standard TCL tests,
# and fuzz tests, and sqlite3_analyzer and sqldiff tests.
test:	fuzztest sourcetest $(TESTPROGS) tcltest
test:	fastfuzztest sourcetest $(TESTPROGS) tcltest

# Run a test using valgrind.  This can take a really long time
# because valgrind is so much slower than a native machine.
#
valgrindtest:	$(TESTPROGS) valgrindfuzz
	OMIT_MISUSE=1 valgrind -v \
	./testfixture$(EXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS)

# A very fast test that checks basic sanity.  The name comes from
# the 60s-era electronics testing:  "Turn it on and see if smoke
# comes out."
#
smoketest:	$(TESTPROGS) fuzzcheck$(EXE)
	./testfixture$(EXE) $(TOP)/test/main.test $(TESTOPTS)

shelltest: $(TESTPROGS)
	./testfixture$(EXT) $(TOP)/test/permutations.test shell

# The next two rules are used to support the "threadtest" target. Building
# threadtest runs a few thread-safety tests that are implemented in C. This
# target is invoked by the releasetest.tcl script.
#
THREADTEST3_SRC = $(TOP)/test/threadtest3.c    \
                  $(TOP)/test/tt3_checkpoint.c \
                  $(TOP)/test/tt3_index.c      \
1087
1088
1089
1090
1091
1092
1093
1094

1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1068
1069
1070
1071
1072
1073
1074

1075
1076
1077

1078
1079
1080
1081
1082
1083
1084
1085







-
+


-
+







checksymbols: sqlite3.o
	nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0

# Build the amalgamation-autoconf package.  The amalamgation-tarball target builds
# a tarball named for the version number.  Ex:  sqlite-autoconf-3110000.tar.gz.
# The snapshot-tarball target builds a tarball named by the SHA1 hash
#
amalgamation-tarball: sqlite3.c sqlite3rc.h
amalgamation-tarball: sqlite3.c
	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal

snapshot-tarball: sqlite3.c sqlite3rc.h
snapshot-tarball: sqlite3.c
	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot


# Standard install and cleanup targets
#
install:	sqlite3 libsqlite3.a sqlite3.h
	mv sqlite3 /usr/bin

Changes to src/alter.c.

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







-
-
+
+
+
















-
+
-
-
-
-
-
-
-


-
-
+
+

-
-
-
+
+
+





-
-
+
+

-
-
+
+








-
+



-
-
+
+







** in pParse->zErr (system tables may not be altered) and returns non-zero.
**
** Or, if zName is not a system table, zero is returned.
*/
static int isAlterableTable(Parse *pParse, Table *pTab){
  if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) 
#ifndef SQLITE_OMIT_VIRTUALTABLE
   || ( (pTab->tabFlags & TF_Shadow)!=0
        && sqlite3ReadOnlyShadowTables(pParse->db)
   || ( (pTab->tabFlags & TF_Shadow) 
     && (pParse->db->flags & SQLITE_Defensive)
     && pParse->db->nVdbeExec==0
   )
#endif
  ){
    sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
    return 1;
  }
  return 0;
}

/*
** 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(
static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
  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 */
  const char *zDropColumn         /* Name of column being dropped */
){
  pParse->colNamesSet = 1;
  sqlite3NestedParse(pParse, 
      "SELECT 1 "
      "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
      "FROM \"%w\".%s "
      "WHERE name NOT LIKE 'sqlite_%%'"
      " AND sql NOT LIKE 'create virtual%%'"
      " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %Q)=NULL ",
      zDb,
      zDb, bTemp, zWhen, zDropColumn
      " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
      zDb, MASTER_NAME, 
      zDb, bTemp
  );

  if( bTemp==0 ){
    sqlite3NestedParse(pParse, 
        "SELECT 1 "
        "FROM temp." DFLT_SCHEMA_TABLE " "
        "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
        "FROM temp.%s "
        "WHERE name NOT LIKE 'sqlite_%%'"
        " AND sql NOT LIKE 'create virtual%%'"
        " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %Q)=NULL ",
        zDb, zWhen, zDropColumn
        " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
        MASTER_NAME, 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, u16 p5){
static void renameReloadSchema(Parse *pParse, int iDb){
  Vdbe *v = pParse->pVdbe;
  if( v ){
    sqlite3ChangeCookie(pParse, iDb);
    sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5);
    if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5);
    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. 
*/
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
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







-
+
-
-
-











-
-
+
+







  /* Get a NULL terminated version of the new table name. */
  zName = sqlite3NameFromToken(db, pName);
  if( !zName ) goto exit_rename_table;

  /* Check that a table or index named 'zName' does not already exist
  ** in database iDb. If so, this is an error.
  */
  if( sqlite3FindTable(db, zName, zDb)
  if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
   || sqlite3FindIndex(db, zName, zDb)
   || sqlite3IsShadowTableOf(db, pTab, zName)
  ){
    sqlite3ErrorMsg(pParse, 
        "there is already another table or index with this name: %s", zName);
    goto exit_rename_table;
  }

  /* Make sure it is not a system table being altered, or a reserved name
  ** that the table is being renamed to.
  */
  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
    goto exit_rename_table;
  }
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse,zName,"table",zName) ){
    goto exit_rename_table;
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
    exit_rename_table;
  }

#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName);
    goto exit_rename_table;
  }
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
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







-
+


-
-
+
+


-
+


-
+



-
-
+




-
+




















-
+



-
+


















-
-
+
+







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







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

  /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
  ** the schema to use the new table name.  */
  sqlite3NestedParse(pParse, 
      "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
      "UPDATE \"%w\".%s SET "
      "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
      "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
      "AND   name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
      , zDb, zDb, zTabName, zName, (iDb==1), zTabName
      "AND   name NOT LIKE 'sqlite_%%'"
      , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
  );

  /* Update the tbl_name and name columns of the sqlite_schema table
  /* Update the tbl_name and name columns of the sqlite_master table
  ** as required.  */
  sqlite3NestedParse(pParse,
      "UPDATE %Q." DFLT_SCHEMA_TABLE " SET "
      "UPDATE %Q.%s SET "
          "tbl_name = %Q, "
          "name = CASE "
            "WHEN type='table' THEN %Q "
            "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
            "     AND type='index' THEN "
            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
             "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
            "ELSE name END "
      "WHERE tbl_name=%Q COLLATE nocase AND "
          "(type='table' OR type='index' OR type='trigger');", 
      zDb,
      zDb, MASTER_NAME, 
      zName, zName, zName, 
      nTabName, zTabName
  );

#ifndef SQLITE_OMIT_AUTOINCREMENT
  /* If the sqlite_sequence table exists in this database, then update 
  ** it with the new table name.
  */
  if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
    sqlite3NestedParse(pParse,
        "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q",
        zDb, zName, pTab->zName);
  }
#endif

  /* If the table being renamed is not itself part of the temp database,
  ** edit view and trigger definitions within the temp database 
  ** as required.  */
  if( iDb!=1 ){
    sqlite3NestedParse(pParse, 
        "UPDATE sqlite_temp_schema SET "
        "UPDATE sqlite_temp_master 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',0) "
              "          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, INITFLAG_AlterRename);
  renameTestSchema(pParse, zDb, iDb==1, "after rename", 0);
  renameReloadSchema(pParse, iDb);
  renameTestSchema(pParse, zDb, iDb==1);

exit_rename_table:
  sqlite3SrcListDelete(db, pSrc);
  sqlite3DbFree(db, zName);
  db->mDbFlags = savedDbFlags;
}

/*
** Write code that will raise an error if the table described by
** zDb and zTab is not empty.
*/
static void sqlite3ErrorIfNotEmpty(
  Parse *pParse,        /* Parsing context */
  const char *zDb,      /* Schema holding the table */
  const char *zTab,     /* Table to check for empty */
  const char *zErr      /* Error message text */
){
  sqlite3NestedParse(pParse,
     "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",
     zErr, zDb, zTab
  );
}

/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
** column definition.
**
** The Table structure pParse->pNewTable was extended to include
** the new column during parsing.
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
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







+
+
+
+
+
+
+
+










-
+
-


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

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










-
-

-
+
-
-
+

-
+







#ifndef SQLITE_OMIT_AUTHORIZATION
  /* Invoke the authorization callback. */
  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
    return;
  }
#endif

  /* If the default value for the new column was specified with a 
  ** literal NULL, then set pDflt to 0. This simplifies checking
  ** for an SQL NULL default below.
  */
  assert( pDflt==0 || pDflt->op==TK_SPAN );
  if( pDflt && pDflt->pLeft->op==TK_NULL ){
    pDflt = 0;
  }

  /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
  ** If there is a NOT NULL constraint, then the default value for the
  ** column must not be NULL.
  */
  if( pCol->colFlags & COLFLAG_PRIMKEY ){
    sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
    return;
  }
  if( pNew->pIndex ){
    sqlite3ErrorMsg(pParse,
    sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
         "Cannot add a UNIQUE column");
    return;
  }
  if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
    /* If the default value for the new column was specified with a 
    ** literal NULL, then set pDflt to 0. This simplifies checking
    ** for an SQL NULL default below.
    */
    assert( pDflt==0 || pDflt->op==TK_SPAN );
    if( pDflt && pDflt->pLeft->op==TK_NULL ){
      pDflt = 0;
    }
    if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
      sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
          "Cannot add a REFERENCES column with non-NULL default value");
    }
    if( pCol->notNull && !pDflt ){
      sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
          "Cannot add a NOT NULL column with default value NULL");
    }
  if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
    sqlite3ErrorMsg(pParse, 
        "Cannot add a REFERENCES column with non-NULL default value");
    return;
  }
  if( pCol->notNull && !pDflt ){
    sqlite3ErrorMsg(pParse, 
        "Cannot add a NOT NULL column with default value NULL");
    return;
  }


    /* Ensure the default expression is something that sqlite3ValueFromExpr()
    ** can handle (i.e. not CURRENT_TIME etc.)
    */
    if( pDflt ){
      sqlite3_value *pVal = 0;
      int rc;
      rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
      assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
      if( rc!=SQLITE_OK ){
        assert( db->mallocFailed == 1 );
        return;
      }
      if( !pVal ){
  /* Ensure the default expression is something that sqlite3ValueFromExpr()
  ** can handle (i.e. not CURRENT_TIME etc.)
  */
  if( pDflt ){
    sqlite3_value *pVal = 0;
    int rc;
    rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
    assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
    if( rc!=SQLITE_OK ){
      assert( db->mallocFailed == 1 );
      return;
    }
    if( !pVal ){
        sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
           "Cannot add a column with non-constant default");
      }
      sqlite3ValueFree(pVal);
    }
      sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
      return;
    }
    sqlite3ValueFree(pVal);
  }
  }else if( pCol->colFlags & COLFLAG_STORED ){
    sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");
  }


  /* Modify the CREATE TABLE statement. */
  zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
  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 "
        "UPDATE \"%w\".%s SET "
          "sql = printf('%%.%ds, ',sql) || %Q"
          " || substr(sql,1+length(printf('%%.%ds',sql))) "
          "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
        "WHERE type = 'table' AND name = %Q", 
      zDb, pNew->addColOffset, zCol, pNew->addColOffset,
      zDb, MASTER_NAME, 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
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395







-
+







    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);
  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.
**
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
430
431
432
433
434
435
436

437
438
439
440
441
442
443







-







    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
    goto exit_begin_add_column;
  }
  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
    goto exit_begin_add_column;
  }

  sqlite3MayAbort(pParse);
  assert( pTab->addColOffset>0 );
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);

  /* Put a copy of the Table struct in Parse.pNewTable for the
  ** sqlite3AddColumn() function and friends to modify.  But modify
  ** the name by adding an "sqlite_altertab_" prefix.  By adding this
  ** prefix, we insure that the name will not collide with an existing
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
458
459
460
461
462
463
464

465
466
467
468
469
470
471







-







    assert( db->mallocFailed );
    goto exit_begin_add_column;
  }
  memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
  for(i=0; i<pNew->nCol; i++){
    Column *pCol = &pNew->aCol[i];
    pCol->zName = sqlite3DbStrDup(db, pCol->zName);
    pCol->hName = sqlite3StrIHash(pCol->zName);
    pCol->zColl = 0;
    pCol->pDflt = 0;
  }
  pNew->pSchema = db->aDb[iDb].pSchema;
  pNew->addColOffset = pTab->addColOffset;
  pNew->nTabRef = 1;

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







-
+












-
+
-
-
+






-
+







** 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){
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 %s %s \"%s\"", 
    sqlite3ErrorMsg(
        (bDrop ? "drop column from" : "rename columns of"),
        zType, pTab->zName
        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,z) (0)
# define isRealTable(x,y) (0)
#endif

/*
** Handles the following parser reduction:
**
**  cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew
*/
566
567
568
569
570
571
572
573

574
575
576
577
578
579
580
529
530
531
532
533
534
535

536
537
538
539
540
541
542
543







-
+








  /* 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;
  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
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
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







-
+







-
+

-
+
-

-
+





-
+


+




-
-
+
+







  if( iCol==pTab->nCol ){
    sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
    goto exit_rename_column;
  }

  /* Do the rename operation using a recursive UPDATE statement that
  ** uses the sqlite_rename_column() SQL function to compute the new
  ** CREATE statement text for the sqlite_schema table.
  ** CREATE statement text for the sqlite_master table.
  */
  sqlite3MayAbort(pParse);
  zNew = sqlite3NameFromToken(db, pNew);
  if( !zNew ) goto exit_rename_column;
  assert( pNew->n>0 );
  bQuote = sqlite3Isquote(pNew->z[0]);
  sqlite3NestedParse(pParse, 
      "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
      "UPDATE \"%w\".%s SET "
      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
      "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
      " AND (type != 'index' OR tbl_name = %Q)"
      " AND sql NOT LIKE 'create virtual%%'",
      zDb,
      zDb, MASTER_NAME, 
      zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
      pTab->zName
  );

  sqlite3NestedParse(pParse, 
      "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
      "UPDATE temp.%s SET "
      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
      "WHERE type IN ('trigger', 'view')",
      MASTER_NAME, 
      zDb, pTab->zName, iCol, zNew, bQuote
  );

  /* Drop and reload the database schema. */
  renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename);
  renameTestSchema(pParse, zDb, iSchema==1, "after rename", 0);
  renameReloadSchema(pParse, iSchema);
  renameTestSchema(pParse, zDb, iSchema==1);

 exit_rename_column:
  sqlite3SrcListDelete(db, pSrc);
  sqlite3DbFree(db, zOld);
  sqlite3DbFree(db, zNew);
  return;
}
722
723
724
725
726
727
728
729
730
731
732
733
734
735






736
737
738
739
740
741
742
743
685
686
687
688
689
690
691







692
693
694
695
696
697

698
699
700
701
702
703
704







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







** with tail recursion in tokenExpr() routine, for a small performance
** improvement.
*/
void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
  RenameToken *pNew;
  assert( pPtr || pParse->db->mallocFailed );
  renameTokenCheckAll(pParse, pPtr);
  if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){
    pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
    if( pNew ){
      pNew->p = pPtr;
      pNew->t = *pToken;
      pNew->pNext = pParse->pRename;
      pParse->pRename = pNew;
  pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
  if( pNew ){
    pNew->p = pPtr;
    pNew->t = *pToken;
    pNew->pNext = pParse->pRename;
    pParse->pRename = pNew;
    }
  }

  return pPtr;
}

/*
** It is assumed that there is already a RenameToken object associated
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880

881
882
883
884
885


886
887
888
889

890
891
892
893
894
895
896
897
898
899
900
901
902






903
904
905
906



















907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
721
722
723
724
725
726
727
728
































































729
730
731

732
733
734
735


736

737
738
739
740
741
742
743
744
745
746
747
748
749
750
751


752

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770

771





772
773
774



775


776
777
778
779
780






781
782
783
784
785
786




787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820








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



-




-
-

-















-
-
+
-


















-
+
-
-
-
-
-
+
+

-
-
-
+
-
-





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








-







*/
static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
  Parse *pParse = pWalker->pParse;
  sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
  return WRC_Continue;
}

/*
** Iterate through the Select objects that are part of WITH clauses attached
** to select statement pSelect.
*/
static void renameWalkWith(Walker *pWalker, Select *pSelect){
  With *pWith = pSelect->pWith;
  if( pWith ){
    int i;
    for(i=0; i<pWith->nCte; i++){
      Select *p = pWith->a[i].pSelect;
      NameContext sNC;
      memset(&sNC, 0, sizeof(sNC));
      sNC.pParse = pWalker->pParse;
      sqlite3SelectPrep(sNC.pParse, p, &sNC);
      sqlite3WalkSelect(pWalker, p);
      sqlite3RenameExprlistUnmap(pWalker->pParse, pWith->a[i].pCols);
    }
  }
}

/*
** Unmap all tokens in the IdList object passed as the second argument.
*/
static void unmapColumnIdlistNames(
  Parse *pParse,
  IdList *pIdList
){
  if( pIdList ){
    int ii;
    for(ii=0; ii<pIdList->nId; ii++){
      sqlite3RenameTokenRemap(pParse, 0, (void*)pIdList->a[ii].zName);
    }
  }
}

/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
  Parse *pParse = pWalker->pParse;
  int i;
  if( pParse->nErr ) return WRC_Abort;
  if( NEVER(p->selFlags & SF_View) ) return WRC_Prune;
  if( ALWAYS(p->pEList) ){
    ExprList *pList = p->pEList;
    for(i=0; i<pList->nExpr; i++){
      if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){
        sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);
      }
    }
  }
  if( ALWAYS(p->pSrc) ){  /* Every Select as a SrcList, even if it is empty */
    SrcList *pSrc = p->pSrc;
    for(i=0; i<pSrc->nSrc; i++){
      sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
      if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort;
      unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
    }
  }

  renameWalkWith(pWalker, p);
  return WRC_Continue;
}

/*
** Remove all nodes that are part of expression pExpr from the rename list.
*/
void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
  u8 eMode = pParse->eParseMode;
  Walker sWalker;
  memset(&sWalker, 0, sizeof(Walker));
  sWalker.pParse = pParse;
  sWalker.xExprCallback = renameUnmapExprCb;
  sWalker.xSelectCallback = renameUnmapSelectCb;
  pParse->eParseMode = PARSE_MODE_UNMAP;
  sqlite3WalkExpr(&sWalker, pExpr);
  pParse->eParseMode = eMode;
}

/*
** Remove all nodes that are part of expression-list pEList from the 
** rename list.
*/
void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){
  if( pEList ){
    int i;
    Walker sWalker;
    memset(&sWalker, 0, sizeof(Walker));
    sWalker.pParse = pParse;
    sWalker.xExprCallback = renameUnmapExprCb;
    sqlite3WalkExprList(&sWalker, pEList);
    for(i=0; i<pEList->nExpr; i++){
      if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){
        sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName);
      sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName);
      }
    }
  }
}

/*
** Free the list of RenameToken objects given in the second argument
*/
static void renameTokenFree(sqlite3 *db, RenameToken *pToken){
  RenameToken *pNext;
  RenameToken *p;
  for(p=pToken; p; p=pNext){
    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
** object associated with parse tree element pPtr. If found, remove it
** 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.
** from the Parse object and add it to the list maintained by the
** RenameCtx object passed as the second argument.
*/
static RenameToken *renameTokenFind(
  Parse *pParse, 
  struct RenameCtx *pCtx, 
static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
  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++;
      }
      *pp = pToken->pNext;
      pToken->pNext = pCtx->pList;
      pCtx->pList = pToken;
      pCtx->nList++;
      break;
    }
      return pToken;
    }
  }
  return 0;
  }
}

/*
** Iterate through the Select objects that are part of WITH clauses attached
** to select statement pSelect.
*/
static void renameWalkWith(Walker *pWalker, Select *pSelect){
  if( pSelect->pWith ){
    int i;
    for(i=0; i<pSelect->pWith->nCte; i++){
      Select *p = pSelect->pWith->a[i].pSelect;
      NameContext sNC;
      memset(&sNC, 0, sizeof(sNC));
      sNC.pParse = pWalker->pParse;
      sqlite3SelectPrep(sNC.pParse, p, &sNC);
      sqlite3WalkSelect(pWalker, p);
    }
  }
}

/*
** 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.
*/
static int renameColumnSelectCb(Walker *pWalker, Select *p){
  if( p->selFlags & SF_View ) return WRC_Prune;
  renameWalkWith(pWalker, p);
  return WRC_Continue;
}

/*
** This is a Walker expression callback.
**
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
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







-
+








-
-
+
+







** 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,
  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: %s", 
      zT, zN, (zWhen[0] ? " " : ""), zWhen,
  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);
}

/*
1002
1003
1004
1005
1006
1007
1008
1009

1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
1020
900
901
902
903
904
905
906

907



908

909
910
911
912
913
914
915







-
+
-
-
-
+
-







  RenameCtx *pCtx, 
  ExprList *pEList, 
  const char *zOld
){
  if( pEList ){
    int i;
    for(i=0; i<pEList->nExpr; i++){
      char *zName = pEList->a[i].zEName;
      char *zName = pEList->a[i].zName;
      if( ALWAYS(pEList->a[i].eEName==ENAME_NAME)
       && ALWAYS(zName!=0)
       && 0==sqlite3_stricmp(zName, zOld)
      if( 0==sqlite3_stricmp(zName, zOld) ){
      ){
        renameTokenFind(pParse, pCtx, (void*)zName);
      }
    }
  }
}

/*
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
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







-







+


-
+
-





-
-
-
-





-
+


-
+







      if( 0==sqlite3_stricmp(zName, zOld) ){
        renameTokenFind(pParse, pCtx, (void*)zName);
      }
    }
  }
}


/*
** Parse the SQL statement zSql using Parse object (*p). The Parse object
** is initialized by this function before it is used.
*/
static int renameParseSql(
  Parse *p,                       /* Memory to use for Parse object */
  const char *zDb,                /* Name of schema SQL belongs to */
  int bTable,                     /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */
  sqlite3 *db,                    /* Database handle */
  const char *zSql,               /* SQL to parse */
  int bTemp,                      /* True if SQL is from temp schema */
  int bTemp                       /* True if SQL is from temp schema */
  const char *zDropColumn         /* Name of column being dropped */
){
  int rc;
  char *zErr = 0;

  db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
  if( zDropColumn ){
    db->init.bDropColumn = 1;
    db->init.azInit = (char**)&zDropColumn;
  }

  /* 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->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN);
  p->db = db;
  p->nQueryLoop = 1;
  rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM;
  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 
  ){
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
978
979
980
981
982
983
984

985
986
987
988
989
990
991







-







    for(pToken=p->pRename; pToken; pToken=pToken->pNext){
      assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] );
    }
  }
#endif

  db->init.iDb = 0;
  db->init.bDropColumn = 0;
  return rc;
}

/*
** This function edits SQL statement zSql, replacing each token identified
** by the linked list pRename with the text of zNew. If argument bQuote is
** true, then zNew is always quoted first. If no error occurs, the result
1183
1184
1185
1186
1187
1188
1189
1190

1191
1192
1193
1194
1195
1196
1197
1072
1073
1074
1075
1076
1077
1078

1079
1080
1081
1082
1083
1084
1085
1086







-
+








/*
** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming
** it was read from the schema of database zDb. Return SQLITE_OK if 
** successful. Otherwise, return an SQLite error code and leave an error
** message in the Parse object.
*/
static int renameResolveTrigger(Parse *pParse){
static int renameResolveTrigger(Parse *pParse, const char *zDb){
  sqlite3 *db = pParse->db;
  Trigger *pNew = pParse->pNewTrigger;
  TriggerStep *pStep;
  NameContext sNC;
  int rc = SQLITE_OK;

  memset(&sNC, 0, sizeof(sNC));
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
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







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






-
+

+
-
+
















-
-
-








  for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
    if( pStep->pSelect ){
      sqlite3SelectPrep(pParse, pStep->pSelect, &sNC);
      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);
          }else{
            p->pTab = sqlite3LocateTableItem(pParse, 0, p);
            if( p->pTab==0 ){
              rc = SQLITE_ERROR;
      Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb);
      if( pTarget==0 ){
        rc = SQLITE_ERROR;
            }else{
              p->pTab->nTabRef++;
              rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
      }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){
            }
          }
        }
        sNC.pSrcList = pSrc;
        if( rc==SQLITE_OK && pStep->pWhere ){
        SrcList sSrc;
        memset(&sSrc, 0, sizeof(sSrc));
        sSrc.nSrc = 1;
        sSrc.a[0].zName = pStep->zTarget;
        sSrc.a[0].pTab = pTarget;
        sNC.pSrcList = &sSrc;
        if( 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 ){
        if( pStep->pUpsert ){
          Upsert *pUpsert = pStep->pUpsert;
          assert( rc==SQLITE_OK );
          pUpsert->pUpsertSrc = pSrc;
          pUpsert->pUpsertSrc = &sSrc;
          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);
          }
          if( rc==SQLITE_OK ){
            rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere);
          }
          if( rc==SQLITE_OK ){
            rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
          }
          sNC.ncFlags = 0;
        }
        sNC.pSrcList = 0;
        sqlite3SrcListDelete(db, pSrc);
      }else{
        rc = SQLITE_NOMEM;
      }
    }
  }
  return rc;
}

/*
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1168
1169
1170
1171
1172
1173
1174






1175
1176
1177
1178
1179
1180
1181







-
-
-
-
-
-







    if( pStep->pUpsert ){
      Upsert *pUpsert = pStep->pUpsert;
      sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget);
      sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet);
      sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere);
      sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere);
    }
    if( pStep->pFrom ){
      int i;
      for(i=0; i<pStep->pFrom->nSrc; i++){
        sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect);
      }
    }
  }
}

/*
** Free the contents of Parse object (*pParse). Do not free the memory
** occupied by the Parse object itself.
*/
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
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







-
+













-

-
+







  zOld = pTab->aCol[iCol].zName;
  memset(&sCtx, 0, sizeof(sCtx));
  sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol);

#ifndef SQLITE_OMIT_AUTHORIZATION
  db->xAuth = 0;
#endif
  rc = renameParseSql(&sParse, zDb, db, zSql, bTemp, 0);
  rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp);

  /* Find tokens that need to be replaced. */
  memset(&sWalker, 0, sizeof(Walker));
  sWalker.pParse = &sParse;
  sWalker.xExprCallback = renameColumnExprCb;
  sWalker.xSelectCallback = renameColumnSelectCb;
  sWalker.u.pRename = &sCtx;

  sCtx.pTab = pTab;
  if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
  if( sParse.pNewTable ){
    Select *pSelect = sParse.pNewTable->pSelect;
    if( pSelect ){
      pSelect->selFlags &= ~SF_View;
      sParse.rc = SQLITE_OK;
      sqlite3SelectPrep(&sParse, pSelect, 0);
      sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0);
      rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
      if( rc==SQLITE_OK ){
        sqlite3WalkSelect(&sWalker, pSelect);
      }
      if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
    }else{
      /* A regular table */
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1299
1300
1301
1302
1303
1304
1305





1306
1307
1308
1309
1310
1311
1312







-
-
-
-
-







        sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck);
        for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
        }
        for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){
          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
        }
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
        for(i=0; i<sParse.pNewTable->nCol; i++){
          sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt);
        }
#endif
      }

      for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
        for(i=0; i<pFKey->nCol; i++){
          if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
            renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
          }
1458
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469
1470
1471
1472
1320
1321
1322
1323
1324
1325
1326

1327
1328
1329
1330
1331
1332
1333
1334







-
+







    }
  }else if( sParse.pNewIndex ){
    sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr);
    sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
  }else{
    /* A trigger */
    TriggerStep *pStep;
    rc = renameResolveTrigger(&sParse);
    rc = renameResolveTrigger(&sParse, (bTemp ? 0 : zDb));
    if( rc!=SQLITE_OK ) goto renameColumnFunc_done;

    for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){
      if( pStep->zTarget ){ 
        Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb);
        if( pTarget==pTab ){
          if( pStep->pUpsert ){
1491
1492
1493
1494
1495
1496
1497
1498

1499
1500
1501
1502
1503
1504
1505
1353
1354
1355
1356
1357
1358
1359

1360
1361
1362
1363
1364
1365
1366
1367







-
+








  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);
      renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
    }else{
      sqlite3_result_error_code(context, rc);
    }
  }

  renameParseCleanup(&sParse);
  renameTokenFree(db, sCtx.pList);
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536

1537
1538
1539
1540
1541
1542
1543
1385
1386
1387
1388
1389
1390
1391

1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403
1404







-





-
+







/*
** Walker select callback used by "RENAME TABLE". 
*/
static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
  int i;
  RenameCtx *p = pWalker->u.pRename;
  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];
    struct SrcList_item *pItem = &pSrc->a[i];
    if( pItem->pTab==p->pTab ){
      renameTokenFind(pWalker->pParse, p, pItem->zName);
    }
  }
  renameWalkWith(pWalker, pSelect);

  return WRC_Continue;
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
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







-
+








-




-
-

-
+
-
-
-
+
-







    sCtx.pTab = sqlite3FindTable(db, zOld, zDb);
    memset(&sWalker, 0, sizeof(Walker));
    sWalker.pParse = &sParse;
    sWalker.xExprCallback = renameTableExprCb;
    sWalker.xSelectCallback = renameTableSelectCb;
    sWalker.u.pRename = &sCtx;

    rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, 0);
    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);

    if( rc==SQLITE_OK ){
      int isLegacy = (db->flags & SQLITE_LegacyAlter);
      if( sParse.pNewTable ){
        Table *pTab = sParse.pNewTable;

        if( pTab->pSelect ){
          if( isLegacy==0 ){
            Select *pSelect = pTab->pSelect;
            NameContext sNC;
            memset(&sNC, 0, sizeof(sNC));
            sNC.pParse = &sParse;

            assert( pSelect->selFlags & SF_View );
            pSelect->selFlags &= ~SF_View;
            sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
            if( sParse.nErr ){
            if( sParse.nErr ) rc = sParse.rc;
              rc = sParse.rc;
            }else{
              sqlite3WalkSelect(&sWalker, pTab->pSelect);
            sqlite3WalkSelect(&sWalker, pTab->pSelect);
            }
          }
        }else{
          /* Modify any FK definitions to point to the new table. */
#ifndef SQLITE_OMIT_FOREIGN_KEY
          if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
            FKey *pFKey;
            for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
1661
1662
1663
1664
1665
1666
1667
1668

1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687

1688
1689
1690
1691
1692
1693
1694
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







-
+


















-
+







        if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) 
            && sCtx.pTab->pSchema==pTrigger->pTabSchema
          ){
          renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table);
        }

        if( isLegacy==0 ){
          rc = renameResolveTrigger(&sParse);
          rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
          if( rc==SQLITE_OK ){
            renameWalkTrigger(&sWalker, pTrigger);
            for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
              if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
                renameTokenFind(&sParse, &sCtx, pStep->zTarget);
              }
            }
          }
        }
      }
#endif
    }

    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);
        renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
      }else{
        sqlite3_result_error_code(context, rc);
      }
    }

    renameParseCleanup(&sParse);
    renameTokenFree(db, sCtx.pList);
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747

1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770


1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989



1990
1991
1992
1993
1994
1564
1565
1566
1567
1568
1569
1570


1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587


1588
1589
1590
1591
1592
1593
1594
1595
1596
1597

1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1617
1618
1619


1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630










































































































































































































1631
1632
1633
1634
1635



1636
1637
1638

1639
1640
1641
1642







-
-

















-
-










-
+











-
+









-
-
+
+









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





-
-
-
+
+
+
-




** 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.
**   6: Name of column being dropped, or NULL.
**
** 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]);
  char const *zDropColumn = (const char*)sqlite3_value_text(argv[6]);

#ifndef SQLITE_OMIT_AUTHORIZATION
  sqlite3_xauth xAuth = db->xAuth;
  db->xAuth = 0;
#endif

  UNUSED_PARAMETER(NotUsed);
  if( zDb && zInput ){
    int rc;
    Parse sParse;
    rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, zDropColumn);
    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
    if( rc==SQLITE_OK ){
      if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){
        NameContext sNC;
        memset(&sNC, 0, sizeof(sNC));
        sNC.pParse = &sParse;
        sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC);
        if( sParse.nErr ) rc = sParse.rc;
      }

      else if( sParse.pNewTrigger ){
        if( isLegacy==0 ){
          rc = renameResolveTrigger(&sParse);
          rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
        }
        if( rc==SQLITE_OK ){
          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);
    if( rc!=SQLITE_OK ){
      renameColumnParseError(context, 1, 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, 0);
  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, "", 0);
  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", zCol);

  /* 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;
    if( HasRowid(pTab) ){
      sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg);
      pParse->nMem += pTab->nCol;
    }else{
      pPk = sqlite3PrimaryKeyIndex(pTab);
      pParse->nMem += pPk->nColumn;
      for(i=0; i<pPk->nKeyCol; i++){
        sqlite3VdbeAddOp3(v, OP_Column, iCur, i, reg+i+1);
      }
      nField = pPk->nKeyCol;
    }
    regRec = ++pParse->nMem;
    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);
          if( iPos<pPk->nKeyCol ) continue;
          regOut = reg+1+iPos-(iPos>iColPos);
        }else{
          regOut = reg+1+nField;
        }
        if( i==pTab->iPKey ){
          sqlite3VdbeAddOp2(v, OP_Null, 0, regOut);
        }else{
          sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut);
        }
        nField++;
      }
    }
    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);
    }
    sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);

    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,    7, renameTableTest),
    INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
    INTERNAL_FUNCTION(sqlite_rename_table,  7, renameTableFunc),
    INTERNAL_FUNCTION(sqlite_rename_test,   5, renameTableTest),
    INTERNAL_FUNCTION(sqlite_drop_column,    3, dropColumnFunc),
  };
  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
#endif  /* SQLITE_ALTER_TABLE */

Changes to src/analyze.c.

23
24
25
26
27
28
29
30

31
32
33
34
35
36





37
38
39
40
41
42
43
23
24
25
26
27
28
29

30
31





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







-
+

-
-
-
-
-
+
+
+
+
+







**    CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample);
**
** Additional tables might be added in future releases of SQLite.
** The sqlite_stat2 table is not created or used unless the SQLite version
** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
** with SQLITE_ENABLE_STAT2.  The sqlite_stat2 table is deprecated.
** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
** created and used by SQLite versions 3.7.9 through 3.29.0 when
** created and used by SQLite versions 3.7.9 and later and with
** SQLITE_ENABLE_STAT3 defined.  The functionality of sqlite_stat3
** is a superset of sqlite_stat2 and is also now deprecated.  The
** sqlite_stat4 is an enhanced version of sqlite_stat3 and is only 
** available when compiled with SQLITE_ENABLE_STAT4 and in SQLite
** versions 3.8.1 and later.  STAT4 is the only variant that is still
** supported.
** is a superset of sqlite_stat2.  The sqlite_stat4 is an enhanced
** version of sqlite_stat3 and is only available when compiled with
** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.1 and later.  It is
** not possible to enable both STAT3 and STAT4 at the same time.  If they
** are both enabled, then STAT4 takes precedence.
**
** For most applications, sqlite_stat1 provides all the statistics required
** for the query planner to make good choices.
**
** Format of sqlite_stat1:
**
** There is normally one row per index, with the index identified by the
140
141
142
143
144
145
146




147
148

149
150
151

152
153
154
155
156
157
158
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







+
+
+
+


+



+







** integer in the equivalent columns in sqlite_stat4.
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

#if defined(SQLITE_ENABLE_STAT4)
# define IsStat4     1
# define IsStat3     0
#elif defined(SQLITE_ENABLE_STAT3)
# define IsStat4     0
# define IsStat3     1
#else
# define IsStat4     0
# define IsStat3     0
# undef SQLITE_STAT4_SAMPLES
# define SQLITE_STAT4_SAMPLES 1
#endif
#define IsStat34    (IsStat3+IsStat4)  /* 1 for STAT3 or STAT4. 0 otherwise */

/*
** This routine generates code that opens the sqlite_statN tables.
** The sqlite_stat1 table is always relevant.  sqlite_stat2 is now
** obsolete.  sqlite_stat3 and sqlite_stat4 are only opened when
** appropriate compile-time options are provided.
**
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
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







+
+
+
+

+


-





-
+

-
-
-
-
-












-

-
+







-
+







+












-
+





-
+

-
+

















-
-
-
+
+
+


-
+











-
+
-
-
-
-
+
+


-
-
-
-

+

-
+




-
-
+
+


-
+

-
-
+
+










-
-
+
+














-
-
+
+











-
-
+
+















-
+

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





-
+



-
+
-




+
+






-
-
-
+
+
+







-
+




-
-
+
+
-
-
+











-
+

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

+








-

-


-



-
+
-
-
+




+
-
+



-
-
+
+



















-
+


-
+







  static const struct {
    const char *zName;
    const char *zCols;
  } aTable[] = {
    { "sqlite_stat1", "tbl,idx,stat" },
#if defined(SQLITE_ENABLE_STAT4)
    { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
    { "sqlite_stat3", 0 },
#elif defined(SQLITE_ENABLE_STAT3)
    { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
    { "sqlite_stat4", 0 },
#else
    { "sqlite_stat3", 0 },
    { "sqlite_stat4", 0 },
#endif
    { "sqlite_stat3", 0 },
  };
  int i;
  sqlite3 *db = pParse->db;
  Db *pDb;
  Vdbe *v = sqlite3GetVdbe(pParse);
  u32 aRoot[ArraySize(aTable)];
  int aRoot[ArraySize(aTable)];
  u8 aCreateTbl[ArraySize(aTable)];
#ifdef SQLITE_ENABLE_STAT4
  const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
#else
  const int nToOpen = 1;
#endif

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

  /* Create new statistic tables if they do not exist, or clear them
  ** if they do already exist.
  */
  for(i=0; i<ArraySize(aTable); i++){
    const char *zTab = aTable[i].zName;
    Table *pStat;
    aCreateTbl[i] = 0;
    if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
      if( i<nToOpen ){
      if( aTable[i].zCols ){
        /* The sqlite_statN table does not exist. Create it. Note that a 
        ** side-effect of the CREATE TABLE statement is to leave the rootpage 
        ** of the new table in register pParse->regRoot. This is important 
        ** because the OpenWrite opcode below will be needing it. */
        sqlite3NestedParse(pParse,
            "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
        );
        aRoot[i] = (u32)pParse->regRoot;
        aRoot[i] = pParse->regRoot;
        aCreateTbl[i] = OPFLAG_P2ISREG;
      }
    }else{
      /* The table already exists. If zWhere is not NULL, delete all entries 
      ** associated with the table zWhere. If zWhere is NULL, delete the
      ** entire contents of the table. */
      aRoot[i] = pStat->tnum;
      aCreateTbl[i] = 0;
      sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
      if( zWhere ){
        sqlite3NestedParse(pParse,
           "DELETE FROM %Q.%s WHERE %s=%Q",
           pDb->zDbSName, zTab, zWhereType, zWhere
        );
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
      }else if( db->xPreUpdateCallback ){
        sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
#endif
      }else{
        /* The sqlite_stat[134] table already exists.  Delete all rows. */
        sqlite3VdbeAddOp2(v, OP_Clear, (int)aRoot[i], iDb);
        sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
      }
    }
  }

  /* Open the sqlite_stat[134] tables for writing. */
  for(i=0; i<nToOpen; i++){
  for(i=0; aTable[i].zCols; i++){
    assert( i<ArraySize(aTable) );
    sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, (int)aRoot[i], iDb, 3);
    sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
    sqlite3VdbeChangeP5(v, aCreateTbl[i]);
    VdbeComment((v, aTable[i].zName));
  }
}

/*
** Recommended number of samples for sqlite_stat4
*/
#ifndef SQLITE_STAT4_SAMPLES
# define SQLITE_STAT4_SAMPLES 24
#endif

/*
** Three SQL functions - stat_init(), stat_push(), and stat_get() -
** share an instance of the following structure to hold their state
** information.
*/
typedef struct StatAccum StatAccum;
typedef struct StatSample StatSample;
struct StatSample {
typedef struct Stat4Accum Stat4Accum;
typedef struct Stat4Sample Stat4Sample;
struct Stat4Sample {
  tRowcnt *anEq;                  /* sqlite_stat4.nEq */
  tRowcnt *anDLt;                 /* sqlite_stat4.nDLt */
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  tRowcnt *anLt;                  /* sqlite_stat4.nLt */
  union {
    i64 iRowid;                     /* Rowid in main table of the key */
    u8 *aRowid;                     /* Key for WITHOUT ROWID tables */
  } u;
  u32 nRowid;                     /* Sizeof aRowid[] */
  u8 isPSample;                   /* True if a periodic sample */
  int iCol;                       /* If !isPSample, the reason for inclusion */
  u32 iHash;                      /* Tiebreaker hash */
#endif
};                                                    
struct StatAccum {
struct Stat4Accum {
  sqlite3 *db;              /* Database connection, for malloc() */
  tRowcnt nEst;             /* Estimated number of rows */
  tRowcnt nRow;             /* Number of rows visited so far */
  int nLimit;               /* Analysis row-scan limit */
  tRowcnt nRow;             /* Number of rows in the entire table */
  tRowcnt nPSample;         /* How often to do a periodic sample */
  int nCol;                 /* Number of columns in index + pk/rowid */
  int nKeyCol;              /* Number of index columns w/o the pk/rowid */
  u8 nSkipAhead;            /* Number of times of skip-ahead */
  StatSample current;       /* Current row as a StatSample */
#ifdef SQLITE_ENABLE_STAT4
  tRowcnt nPSample;         /* How often to do a periodic sample */
  int mxSample;             /* Maximum number of samples to accumulate */
  Stat4Sample current;      /* Current row as a Stat4Sample */
  u32 iPrn;                 /* Pseudo-random number used for sampling */
  StatSample *aBest;        /* Array of nCol best samples */
  Stat4Sample *aBest;       /* Array of nCol best samples */
  int iMin;                 /* Index in a[] of entry with minimum score */
  int nSample;              /* Current number of samples */
  int nMaxEqZero;           /* Max leading 0 in anEq[] for any a[] entry */
  int iGet;                 /* Index of current sample accessed by stat_get() */
  StatSample *a;            /* Array of mxSample StatSample objects */
#endif
  Stat4Sample *a;           /* Array of mxSample Stat4Sample objects */
  sqlite3 *db;              /* Database connection, for malloc() */
};

/* Reclaim memory used by a StatSample
/* Reclaim memory used by a Stat4Sample
*/
#ifdef SQLITE_ENABLE_STAT4
static void sampleClear(sqlite3 *db, StatSample *p){
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static void sampleClear(sqlite3 *db, Stat4Sample *p){
  assert( db!=0 );
  if( p->nRowid ){
    sqlite3DbFree(db, p->u.aRowid);
    p->nRowid = 0;
  }
}
#endif

/* Initialize the BLOB value of a ROWID
*/
#ifdef SQLITE_ENABLE_STAT4
static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
  assert( db!=0 );
  if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
  p->u.aRowid = sqlite3DbMallocRawNN(db, n);
  if( p->u.aRowid ){
    p->nRowid = n;
    memcpy(p->u.aRowid, pData, n);
  }else{
    p->nRowid = 0;
  }
}
#endif

/* Initialize the INTEGER value of a ROWID.
*/
#ifdef SQLITE_ENABLE_STAT4
static void sampleSetRowidInt64(sqlite3 *db, StatSample *p, i64 iRowid){
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
  assert( db!=0 );
  if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
  p->nRowid = 0;
  p->u.iRowid = iRowid;
}
#endif


/*
** Copy the contents of object (*pFrom) into (*pTo).
*/
#ifdef SQLITE_ENABLE_STAT4
static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
  pTo->isPSample = pFrom->isPSample;
  pTo->iCol = pFrom->iCol;
  pTo->iHash = pFrom->iHash;
  memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
  memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
  memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol);
  if( pFrom->nRowid ){
    sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid);
  }else{
    sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid);
  }
}
#endif

/*
** Reclaim all memory of a StatAccum structure.
** Reclaim all memory of a Stat4Accum structure.
*/
static void statAccumDestructor(void *pOld){
  StatAccum *p = (StatAccum*)pOld;
#ifdef SQLITE_ENABLE_STAT4
static void stat4Destructor(void *pOld){
  Stat4Accum *p = (Stat4Accum*)pOld;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( p->mxSample ){
    int i;
    for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
    for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
    sampleClear(p->db, &p->current);
  int i;
  for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
  for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
  sampleClear(p->db, &p->current);
  }
#endif
  sqlite3DbFree(p->db, p);
}

/*
** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
** Implementation of the stat_init(N,K,C) SQL function. The three parameters
** are:
**     N:    The number of columns in the index including the rowid/pk (note 1)
**     K:    The number of columns in the index excluding the rowid/pk.
**     C:    Estimated number of rows in the index
**     C:    The number of rows in the index (note 2)
**     L:    A limit on the number of rows to scan, or 0 for no-limit 
**
** Note 1:  In the special case of the covering index that implements a
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
** total number of columns in the table.
**
** Note 2:  C is only used for STAT3 and STAT4.
**
** For indexes on ordinary rowid tables, N==K+1.  But for indexes on
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
** PRIMARY KEY of the table.  The covering index that implements the
** original WITHOUT ROWID table as N==K as a special case.
**
** This routine allocates the StatAccum object in heap memory. The return 
** value is a pointer to the StatAccum object.  The datatype of the
** return value is BLOB, but it is really just a pointer to the StatAccum
** This routine allocates the Stat4Accum object in heap memory. The return 
** value is a pointer to the Stat4Accum object.  The datatype of the
** return value is BLOB, but it is really just a pointer to the Stat4Accum
** object.
*/
static void statInit(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  StatAccum *p;
  Stat4Accum *p;
  int nCol;                       /* Number of columns in index being sampled */
  int nKeyCol;                    /* Number of key columns */
  int nColUp;                     /* nCol rounded up for alignment */
  int n;                          /* Bytes of space to allocate */
  sqlite3 *db = sqlite3_context_db_handle(context);   /* Database connection */
#ifdef SQLITE_ENABLE_STAT4
  sqlite3 *db;                    /* Database connection */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  /* Maximum number of samples.  0 if STAT4 data is not collected */
  int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
  int mxSample = SQLITE_STAT4_SAMPLES;
#endif

  /* Decode the three function arguments */
  UNUSED_PARAMETER(argc);
  nCol = sqlite3_value_int(argv[0]);
  assert( nCol>0 );
  nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
  nKeyCol = sqlite3_value_int(argv[1]);
  assert( nKeyCol<=nCol );
  assert( nKeyCol>0 );

  /* Allocate the space required for the StatAccum object */
  /* Allocate the space required for the Stat4Accum object */
  n = sizeof(*p) 
    + sizeof(tRowcnt)*nColUp                  /* StatAccum.anEq */
    + sizeof(tRowcnt)*nColUp;                 /* StatAccum.anDLt */
#ifdef SQLITE_ENABLE_STAT4
    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anEq */
    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anDLt */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( mxSample ){
    n += sizeof(tRowcnt)*nColUp                  /* StatAccum.anLt */
      + sizeof(StatSample)*(nCol+mxSample)       /* StatAccum.aBest[], a[] */
      + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anLt */
    + sizeof(Stat4Sample)*(nCol+mxSample)     /* Stat4Accum.aBest[], a[] */
    + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
  }
#endif
  ;
  db = sqlite3_context_db_handle(context);
  p = sqlite3DbMallocZero(db, n);
  if( p==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }

  p->db = db;
  p->nEst = sqlite3_value_int64(argv[2]);
  p->nRow = 0;
  p->nLimit = sqlite3_value_int64(argv[3]);
  p->nCol = nCol;
  p->nKeyCol = nKeyCol;
  p->nSkipAhead = 0;
  p->current.anDLt = (tRowcnt*)&p[1];
  p->current.anEq = &p->current.anDLt[nColUp];

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  p->mxSample = p->nLimit==0 ? mxSample : 0;
  if( mxSample ){
  {
    u8 *pSpace;                     /* Allocated space not yet assigned */
    int i;                          /* Used to iterate through p->aSample[] */

    p->iGet = -1;
    p->mxSample = mxSample;
    p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
    p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
    p->current.anLt = &p->current.anEq[nColUp];
    p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
  
    /* Set up the StatAccum.a[] and aBest[] arrays */
    p->a = (struct StatSample*)&p->current.anLt[nColUp];
    /* Set up the Stat4Accum.a[] and aBest[] arrays */
    p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
    p->aBest = &p->a[mxSample];
    pSpace = (u8*)(&p->a[mxSample+nCol]);
    for(i=0; i<(mxSample+nCol); i++){
      p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
      p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
      p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
    }
    assert( (pSpace - (u8*)p)==n );
  
    for(i=0; i<nCol; i++){
      p->aBest[i].iCol = i;
    }
  }
#endif

  /* Return a pointer to the allocated object to the caller.  Note that
  ** only the pointer (the 2nd parameter) matters.  The size of the object
  ** (given by the 3rd parameter) is never used and can be any positive
  ** value. */
  sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
  sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
}
static const FuncDef statInitFuncdef = {
  4,               /* nArg */
  2+IsStat34,      /* nArg */
  SQLITE_UTF8,     /* funcFlags */
  0,               /* pUserData */
  0,               /* pNext */
  statInit,        /* xSFunc */
  0,               /* xFinalize */
  0, 0,            /* xValue, xInverse */
  "stat_init",     /* zName */
505
506
507
508
509
510
511
512
513
514



515
516
517
518
519
520
521
522
523
524
525
526
527
528

529
530
531
532
533
534
535
536
537
538



539
540
541
542
543
544
545
546

547
548
549
550
551



552
553
554
555
556
557
558
559


560
561
562
563

564
565


566
567

568
569
570
571
572

573
574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600

601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618

619
620
621
622
623
624
625
626
627

628


629
630
631
632
633
634
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650


651
652
653
654
655
656

657
658
659
660
661
662
663
499
500
501
502
503
504
505



506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529



530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555


556
557
558
559
560
561
562


563
564
565

566
567
568
569
570

571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646

647
648
649
650
651
652

653
654
655
656
657
658
659

660
661
662
663
664
665
666
667







-
-
-
+
+
+













-
+







-
-
-
+
+
+








+





+
+
+






-
-
+
+




+
-
-
+
+

-
+




-
+








-
+















+



-
+
















+


+









+
-
+
+












-
+

-






-
+
+





-
+







** In other words, if we assume that the cardinalities of the selected
** column for pNew and pOld are equal, is pNew to be preferred over pOld.
**
** This function assumes that for each argument sample, the contents of
** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. 
*/
static int sampleIsBetterPost(
  StatAccum *pAccum, 
  StatSample *pNew, 
  StatSample *pOld
  Stat4Accum *pAccum, 
  Stat4Sample *pNew, 
  Stat4Sample *pOld
){
  int nCol = pAccum->nCol;
  int i;
  assert( pNew->iCol==pOld->iCol );
  for(i=pNew->iCol+1; i<nCol; i++){
    if( pNew->anEq[i]>pOld->anEq[i] ) return 1;
    if( pNew->anEq[i]<pOld->anEq[i] ) return 0;
  }
  if( pNew->iHash>pOld->iHash ) return 1;
  return 0;
}
#endif

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Return true if pNew is to be preferred over pOld.
**
** This function assumes that for each argument sample, the contents of
** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. 
*/
static int sampleIsBetter(
  StatAccum *pAccum, 
  StatSample *pNew, 
  StatSample *pOld
  Stat4Accum *pAccum, 
  Stat4Sample *pNew, 
  Stat4Sample *pOld
){
  tRowcnt nEqNew = pNew->anEq[pNew->iCol];
  tRowcnt nEqOld = pOld->anEq[pOld->iCol];

  assert( pOld->isPSample==0 && pNew->isPSample==0 );
  assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) );

  if( (nEqNew>nEqOld) ) return 1;
#ifdef SQLITE_ENABLE_STAT4
  if( nEqNew==nEqOld ){
    if( pNew->iCol<pOld->iCol ) return 1;
    return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld));
  }
  return 0;
#else
  return (nEqNew==nEqOld && pNew->iHash>pOld->iHash);
#endif
}

/*
** Copy the contents of sample *pNew into the p->a[] array. If necessary,
** remove the least desirable sample from p->a[] to make room.
*/
static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){
  StatSample *pSample = 0;
static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
  Stat4Sample *pSample = 0;
  int i;

  assert( IsStat4 || nEqZero==0 );

#ifdef SQLITE_ENABLE_STAT4
  /* StatAccum.nMaxEqZero is set to the maximum number of leading 0
  ** values in the anEq[] array of any sample in StatAccum.a[]. In
  /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
  ** values in the anEq[] array of any sample in Stat4Accum.a[]. In
  ** other words, if nMaxEqZero is n, then it is guaranteed that there
  ** are no samples with StatSample.anEq[m]==0 for (m>=n). */
  ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
  if( nEqZero>p->nMaxEqZero ){
    p->nMaxEqZero = nEqZero;
  }
  if( pNew->isPSample==0 ){
    StatSample *pUpgrade = 0;
    Stat4Sample *pUpgrade = 0;
    assert( pNew->anEq[pNew->iCol]>0 );

    /* This sample is being added because the prefix that ends in column 
    ** iCol occurs many times in the table. However, if we have already
    ** added a sample that shares this prefix, there is no need to add
    ** this one. Instead, upgrade the priority of the highest priority
    ** existing sample that shares this prefix.  */
    for(i=p->nSample-1; i>=0; i--){
      StatSample *pOld = &p->a[i];
      Stat4Sample *pOld = &p->a[i];
      if( pOld->anEq[pNew->iCol]==0 ){
        if( pOld->isPSample ) return;
        assert( pOld->iCol>pNew->iCol );
        assert( sampleIsBetter(p, pNew, pOld) );
        if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){
          pUpgrade = pOld;
        }
      }
    }
    if( pUpgrade ){
      pUpgrade->iCol = pNew->iCol;
      pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol];
      goto find_new_min;
    }
  }
#endif

  /* If necessary, remove sample iMin to make room for the new sample. */
  if( p->nSample>=p->mxSample ){
    StatSample *pMin = &p->a[p->iMin];
    Stat4Sample *pMin = &p->a[p->iMin];
    tRowcnt *anEq = pMin->anEq;
    tRowcnt *anLt = pMin->anLt;
    tRowcnt *anDLt = pMin->anDLt;
    sampleClear(p->db, pMin);
    memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1));
    pSample = &p->a[p->nSample-1];
    pSample->nRowid = 0;
    pSample->anEq = anEq;
    pSample->anDLt = anDLt;
    pSample->anLt = anLt;
    p->nSample = p->mxSample-1;
  }

  /* The "rows less-than" for the rowid column must be greater than that
  ** for the last sample in the p->a[] array. Otherwise, the samples would
  ** be out of order. */
#ifdef SQLITE_ENABLE_STAT4
  assert( p->nSample==0 
       || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );
#endif

  /* Insert the new sample */
  pSample = &p->a[p->nSample];
  sampleCopy(p, pSample, pNew);
  p->nSample++;

  /* Zero the first nEqZero entries in the anEq[] array. */
  memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);

#ifdef SQLITE_ENABLE_STAT4
find_new_min:
 find_new_min:
#endif
  if( p->nSample>=p->mxSample ){
    int iMin = -1;
    for(i=0; i<p->mxSample; i++){
      if( p->a[i].isPSample ) continue;
      if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){
        iMin = i;
      }
    }
    assert( iMin>=0 );
    p->iMin = iMin;
  }
}
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

#ifdef SQLITE_ENABLE_STAT4
/*
** Field iChng of the index being scanned has changed. So at this point
** p->current contains a sample that reflects the previous row of the
** index. The value of anEq[iChng] and subsequent anEq[] elements are
** correct at this point.
*/
static void samplePushPrevious(StatAccum *p, int iChng){
static void samplePushPrevious(Stat4Accum *p, int iChng){
#ifdef SQLITE_ENABLE_STAT4
  int i;

  /* Check if any samples from the aBest[] array should be pushed
  ** into IndexSample.a[] at this point.  */
  for(i=(p->nCol-2); i>=iChng; i--){
    StatSample *pBest = &p->aBest[i];
    Stat4Sample *pBest = &p->aBest[i];
    pBest->anEq[i] = p->current.anEq[i];
    if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
      sampleInsert(p, pBest, i);
    }
  }

  /* Check that no sample contains an anEq[] entry with an index of
673
674
675
676
677
678
679

680
681



























682
683
684
685
686
687

688
689
690
691

692

693
694
695


696
697
698
699
700

701
702
703
704
705
706
707
708
709
710

711
712
713
714
715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735


736
737
738
739
740
741
742

743
744
745
746
747
748
749
750
751








752


753


754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769

770
771
772
773
774

775
776
777
778

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


800
801
802
803
804
805
806

807
808
809

810
811
812
813
814
815
816
817
818
819
820
821



822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841

842
843
844
845
846
847
848
677
678
679
680
681
682
683
684


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

717
718
719
720
721
722

723



724
725
726




727
728
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743
744
745
746
747
748
749


750

751
752
753
754
755
756
757
758


759
760
761
762
763
764

765

766









767
768
769
770
771
772
773
774
775
776
777

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

795
796




797


798

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


819
820
821
822
823
824
825
826

827
828
829

830
831
832
833
834
835
836
837
838
839



840
841
842
843
844
845
846
847
848

849
850
851
852
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867
868







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





-
+




+
-
+
-
-
-
+
+

-
-
-
-
+









-
+












-
-
+
-








-
-
+
+




-

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

+
+
-
+
+















-
+

-
-
-
-
+
-
-

-
+



















-
-
+
+






-
+


-
+









-
-
-
+
+
+






-












-
+







      int j;
      for(j=iChng; j<p->nCol; j++){
        if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
      }
    }
    p->nMaxEqZero = iChng;
  }
#endif
}
#endif /* SQLITE_ENABLE_STAT4 */

#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
  if( iChng==0 ){
    tRowcnt nLt = p->current.anLt[0];
    tRowcnt nEq = p->current.anEq[0];

    /* Check if this is to be a periodic sample. If so, add it. */
    if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){
      p->current.isPSample = 1;
      sampleInsert(p, &p->current, 0);
      p->current.isPSample = 0;
    }else 

    /* Or if it is a non-periodic sample. Add it in this case too. */
    if( p->nSample<p->mxSample 
     || sampleIsBetter(p, &p->current, &p->a[p->iMin]) 
    ){
      sampleInsert(p, &p->current, 0);
    }
  }
#endif

#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
  UNUSED_PARAMETER( p );
  UNUSED_PARAMETER( iChng );
#endif
}

/*
** Implementation of the stat_push SQL function:  stat_push(P,C,R)
** Arguments:
**
**    P     Pointer to the StatAccum object created by stat_init()
**    P     Pointer to the Stat4Accum object created by stat_init()
**    C     Index of left-most column to differ from previous row
**    R     Rowid for the current row.  Might be a key record for
**          WITHOUT ROWID tables.
**
** This SQL function always returns NULL.  It's purpose it to accumulate
** The purpose of this routine is to collect statistical data and/or
** statistical data and/or samples in the Stat4Accum object about the
** samples from the index being analyzed into the StatAccum object.
** The stat_get() SQL function will be used afterwards to
** retrieve the information gathered.
** index being analyzed.  The stat_get() SQL function will later be used to
** extract relevant information for constructing the sqlite_statN tables.
**
** This SQL function usually returns NULL, but might return an integer
** if it wants the byte-code to do special processing.
**
** The R parameter is only used for STAT4
** The R parameter is only used for STAT3 and STAT4
*/
static void statPush(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int i;

  /* The three function arguments */
  StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
  Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
  int iChng = sqlite3_value_int(argv[1]);

  UNUSED_PARAMETER( argc );
  UNUSED_PARAMETER( context );
  assert( p->nCol>0 );
  assert( iChng<p->nCol );

  if( p->nRow==0 ){
    /* This is the first call to this function. Do initialization. */
    for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
  }else{
    /* Second and subsequent calls get processed here */
#ifdef SQLITE_ENABLE_STAT4
    if( p->mxSample ) samplePushPrevious(p, iChng);
    samplePushPrevious(p, iChng);
#endif

    /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
    ** to the current row of the index. */
    for(i=0; i<iChng; i++){
      p->current.anEq[i]++;
    }
    for(i=iChng; i<p->nCol; i++){
      p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT4
      if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
      p->current.anLt[i] += p->current.anEq[i];
#endif
      p->current.anEq[i] = 1;
    }
  }

  p->nRow++;
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( p->mxSample ){
    tRowcnt nLt;
    if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
      sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
    }else{
      sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
                                         sqlite3_value_blob(argv[2]));
    }
    p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
  if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
    sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
  }else{
    sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
                                       sqlite3_value_blob(argv[2]));
  }
  p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
#endif

#ifdef SQLITE_ENABLE_STAT4
  {
    nLt = p->current.anLt[p->nCol-1];
    tRowcnt nLt = p->current.anLt[p->nCol-1];

    /* Check if this is to be a periodic sample. If so, add it. */
    if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
      p->current.isPSample = 1;
      p->current.iCol = 0;
      sampleInsert(p, &p->current, p->nCol-1);
      p->current.isPSample = 0;
    }

    /* Update the aBest[] array. */
    for(i=0; i<(p->nCol-1); i++){
      p->current.iCol = i;
      if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
        sampleCopy(p, &p->aBest[i], &p->current);
      }
    }
  }else
  }
#endif
  if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
    p->nSkipAhead++;
    sqlite3_result_int(context, p->current.anDLt[0]>0);
  }
}
}

static const FuncDef statPushFuncdef = {
  2+IsStat4,       /* nArg */
  2+IsStat34,      /* nArg */
  SQLITE_UTF8,     /* funcFlags */
  0,               /* pUserData */
  0,               /* pNext */
  statPush,        /* xSFunc */
  0,               /* xFinalize */
  0, 0,            /* xValue, xInverse */
  "stat_push",     /* zName */
  {0}
};

#define STAT_GET_STAT1 0          /* "stat" column of stat1 table */
#define STAT_GET_ROWID 1          /* "rowid" column of stat[34] entry */
#define STAT_GET_NEQ   2          /* "neq" column of stat[34] entry */
#define STAT_GET_NLT   3          /* "nlt" column of stat[34] entry */
#define STAT_GET_NDLT  4          /* "ndlt" column of stat[34] entry */

/*
** Implementation of the stat_get(P,J) SQL function.  This routine is
** used to query statistical information that has been gathered into
** the StatAccum object by prior calls to stat_push().  The P parameter
** has type BLOB but it is really just a pointer to the StatAccum object.
** the Stat4Accum object by prior calls to stat_push().  The P parameter
** has type BLOB but it is really just a pointer to the Stat4Accum object.
** The content to returned is determined by the parameter J
** which is one of the STAT_GET_xxxx values defined above.
**
** The stat_get(P,J) function is not available to generic SQL.  It is
** inserted as part of a manually constructed bytecode program.  (See
** the callStatGet() routine below.)  It is guaranteed that the P
** parameter will always be a pointer to a StatAccum object, never a
** parameter will always be a poiner to a Stat4Accum object, never a
** NULL.
**
** If STAT4 is not enabled, then J is always
** If neither STAT3 nor STAT4 are enabled, then J is always
** STAT_GET_STAT1 and is hence omitted and this routine becomes
** a one-parameter function, stat_get(P), that always returns the
** stat1 table entry information.
*/
static void statGet(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
#ifdef SQLITE_ENABLE_STAT4
  /* STAT4 has a parameter on this routine. */
  Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  /* STAT3 and STAT4 have a parameter on this routine. */
  int eCall = sqlite3_value_int(argv[1]);
  assert( argc==2 );
  assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ 
       || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
       || eCall==STAT_GET_NDLT 
  );
  assert( eCall==STAT_GET_STAT1 || p->mxSample );
  if( eCall==STAT_GET_STAT1 )
#else
  assert( argc==1 );
#endif
  {
    /* Return the value to store in the "stat" column of the sqlite_stat1
    ** table for this index.
    **
    ** The value is a string composed of a list of integers describing 
    ** the index. The first integer in the list is the total number of 
    ** entries in the index. There is one additional integer in the list 
    ** for each indexed column. This additional integer is an estimate of
    ** the number of rows matched by a equality query on the index using
    ** the number of rows matched by a stabbing query on the index using
    ** a key with the corresponding number of fields. In other words,
    ** if the index is on columns (a,b) and the sqlite_stat1 value is 
    ** "100 10 2", then SQLite estimates that:
    **
    **   * the index contains 100 rows,
    **   * "WHERE a=?" matches 10 rows, and
    **   * "WHERE a=? AND b=?" matches 2 rows.
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
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







-
+
-












-
+






-
+








    char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 );
    if( zRet==0 ){
      sqlite3_result_error_nomem(context);
      return;
    }

    sqlite3_snprintf(24, zRet, "%llu", 
    sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
        p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
    z = zRet + sqlite3Strlen30(zRet);
    for(i=0; i<p->nKeyCol; i++){
      u64 nDistinct = p->current.anDLt[i] + 1;
      u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
      sqlite3_snprintf(24, z, " %llu", iVal);
      z += sqlite3Strlen30(z);
      assert( p->current.anEq[i] );
    }
    assert( z[0]=='\0' && z>zRet );

    sqlite3_result_text(context, zRet, -1, sqlite3_free);
  }
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  else if( eCall==STAT_GET_ROWID ){
    if( p->iGet<0 ){
      samplePushPrevious(p, 0);
      p->iGet = 0;
    }
    if( p->iGet<p->nSample ){
      StatSample *pS = p->a + p->iGet;
      Stat4Sample *pS = p->a + p->iGet;
      if( pS->nRowid==0 ){
        sqlite3_result_int64(context, pS->u.iRowid);
      }else{
        sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid,
                            SQLITE_TRANSIENT);
      }
    }
900
901
902
903
904
905
906
907



908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924

925
926
927
928
929
930

931
932
933
934
935
936
937
938
939
940
941
942
943




944
945
946
947
948
949
950
951


952
953

954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972

973
974
975
976
977
978
979
980
981
982
983
919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944

945
946
947
948
949
950

951
952
953
954
955
956
957
958
959
960
961



962
963
964
965
966
967
968
969
970



971
972


973



















974




975
976
977
978
979
980
981







-
+
+
+
















-
+





-
+










-
-
-
+
+
+
+





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







      default: {
        aCnt = p->a[p->iGet].anDLt; 
        p->iGet++;
        break;
      }
    }

    {
    if( IsStat3 ){
      sqlite3_result_int64(context, (i64)aCnt[0]);
    }else{
      char *zRet = sqlite3MallocZero(p->nCol * 25);
      if( zRet==0 ){
        sqlite3_result_error_nomem(context);
      }else{
        int i;
        char *z = zRet;
        for(i=0; i<p->nCol; i++){
          sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]);
          z += sqlite3Strlen30(z);
        }
        assert( z[0]=='\0' && z>zRet );
        z[-1] = '\0';
        sqlite3_result_text(context, zRet, -1, sqlite3_free);
      }
    }
  }
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
#ifndef SQLITE_DEBUG
  UNUSED_PARAMETER( argc );
#endif
}
static const FuncDef statGetFuncdef = {
  1+IsStat4,       /* nArg */
  1+IsStat34,      /* nArg */
  SQLITE_UTF8,     /* funcFlags */
  0,               /* pUserData */
  0,               /* pNext */
  statGet,         /* xSFunc */
  0,               /* xFinalize */
  0, 0,            /* xValue, xInverse */
  "stat_get",      /* zName */
  {0}
};

static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
#ifdef SQLITE_ENABLE_STAT4
  sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
  assert( regOut!=regStat4 && regOut!=regStat4+1 );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
#elif SQLITE_DEBUG
  assert( iParam==STAT_GET_STAT1 );
#else
  UNUSED_PARAMETER( iParam );
#endif
  assert( regOut!=regStat && regOut!=regStat+1 );
  sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
                             &statGetFuncdef, 0);
  sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut,
                    (char*)&statGetFuncdef, P4_FUNCDEF);
}

  sqlite3VdbeChangeP5(v, 1 + IsStat34);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/* Add a comment to the most recent VDBE opcode that is the name
** of the k-th column of the pIdx index.
*/
static void analyzeVdbeCommentIndexWithColumnName(
  Vdbe *v,         /* Prepared statement under construction */
  Index *pIdx,     /* Index whose column is being loaded */
  int k            /* Which column index */
){
  int i;           /* Index of column in the table */
  assert( k>=0 && k<pIdx->nColumn );
  i = pIdx->aiColumn[k];
  if( NEVER(i==XN_ROWID) ){
    VdbeComment((v,"%s.rowid",pIdx->zName));
  }else if( i==XN_EXPR ){
    VdbeComment((v,"%s.expr(%d)",pIdx->zName, k));
  }else{
    VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zName));
  }
}
}
#else
# define analyzeVdbeCommentIndexWithColumnName(a,b,c)
#endif /* SQLITE_DEBUG */

/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
static void analyzeOneTable(
  Parse *pParse,   /* Parser context */
993
994
995
996
997
998
999
1000

1001

1002

1003
1004
1005
1006
1007
1008
1009
1010
1011
991
992
993
994
995
996
997

998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010







-
+

+

+

-







  int iTabCur;                 /* Table cursor */
  Vdbe *v;                     /* The virtual machine being built up */
  int i;                       /* Loop counter */
  int jZeroRows = -1;          /* Jump from here if number of rows is zero */
  int iDb;                     /* Index of database containing pTab */
  u8 needTableCnt = 1;         /* True to count the table */
  int regNewRowid = iMem++;    /* Rowid for the inserted record */
  int regStat = iMem++;        /* Register to hold StatAccum object */
  int regStat4 = iMem++;       /* Register to hold Stat4Accum object */
  int regChng = iMem++;        /* Index of changed index field */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  int regRowid = iMem++;       /* Rowid argument passed to stat_push() */
#endif
  int regTemp = iMem++;        /* Temporary use register */
  int regTemp2 = iMem++;       /* Second temporary use register */
  int regTabname = iMem++;     /* Register containing table name */
  int regIdxname = iMem++;     /* Register containing index name */
  int regStat1 = iMem++;       /* Value for the stat column of sqlite_stat1 */
  int regPrev = iMem;          /* MUST BE LAST (see below) */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  Table *pStat1 = 0; 
#endif
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
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







-
+
+
+
+

-
-
-
-
+
-
-
+
-
-
-

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









+
+







    VdbeComment((v, "%s", pIdx->zName));

    /* Invoke the stat_init() function. The arguments are:
    ** 
    **    (1) the number of columns in the index including the rowid
    **        (or for a WITHOUT ROWID table, the number of PK columns),
    **    (2) the number of columns in the key without the rowid/pk
    **    (3) estimated number of rows in the index,
    **    (3) the number of rows in the index,
    **
    **
    ** The third argument is only used for STAT3 and STAT4
    */
    sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
    assert( regRowid==regStat+2 );
    sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    if( OptimizationEnabled(db, SQLITE_Stat4) ){
      sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
      addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
      VdbeCoverage(v);
    }else
#endif
    {
      addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
    sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
      VdbeCoverage(v);
      sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
    }
    assert( regTemp2==regStat+4 );
    sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
    sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
                               &statInitFuncdef, 0);
    sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
    sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4,
                     (char*)&statInitFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 2+IsStat34);

    /* Implementation of the following:
    **
    **   Rewind csr
    **   if eof(csr) goto end_of_scan;
    **   regChng = 0
    **   goto next_push_0;
    **
    */
    addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
    VdbeCoverage(v);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
    addrNextRow = sqlite3VdbeCurrentAddr(v);

    if( nColTest>0 ){
      int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
      int *aGotoChng;               /* Array of jump instruction addresses */
      aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224


1225
1226
1227
1228

1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
















1246
1247
1248

1249
1250
1251


1252
1253
1254
1255
1256
1257
1258
1259


1260
1261
1262
1263
1264
1265
1266
1267
1268

1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279


1280

1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294

1295
1296
1297
1298
1299



1300
1301



1302
1303
1304
1305

1306
1307
1308
1309
1310
1311
1312

1313
1314
1315
1316
1317
1318
1319
1180
1181
1182
1183
1184
1185
1186

1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206

1207
1208
1209
1210
1211
1212
1213


1214
1215
1216
1217
1218

1219

















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

1236

1237



1238
1239








1240
1241






1242
1243

1244
1245
1246
1247
1248
1249
1250
1251
1252
1253


1254
1255

1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272



1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291

1292
1293
1294
1295
1296
1297
1298
1299







-




















-







-
-
+
+



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

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


-
+









-
-
+
+
-
+













-
+


-
-
-
+
+
+


+
+
+




+






-
+







        sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest);
        VdbeCoverage(v);
      }
      for(i=0; i<nColTest; i++){
        char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
        sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
        analyzeVdbeCommentIndexWithColumnName(v,pIdx,i);
        aGotoChng[i] = 
        sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
        sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
        VdbeCoverage(v);
      }
      sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
      sqlite3VdbeGoto(v, endDistinctTest);
  
  
      /*
      **  chng_addr_0:
      **   regPrev(0) = idx(0)
      **  chng_addr_1:
      **   regPrev(1) = idx(1)
      **  ...
      */
      sqlite3VdbeJumpHere(v, addrNextRow-1);
      for(i=0; i<nColTest; i++){
        sqlite3VdbeJumpHere(v, aGotoChng[i]);
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
        analyzeVdbeCommentIndexWithColumnName(v,pIdx,i);
      }
      sqlite3VdbeResolveLabel(v, endDistinctTest);
      sqlite3DbFree(db, aGotoChng);
    }
  
    /*
    **  chng_addr_N:
    **   regRowid = idx(rowid)            // STAT4 only
    **   stat_push(P, regChng, regRowid)  // 3rd parameter STAT4 only
    **   regRowid = idx(rowid)            // STAT34 only
    **   stat_push(P, regChng, regRowid)  // 3rd parameter STAT34 only
    **   Next csr
    **   if !eof(csr) goto next_row;
    */
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    if( OptimizationEnabled(db, SQLITE_Stat4) ){
      assert( regRowid==(regStat+2) );
      if( HasRowid(pTab) ){
        sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
      }else{
        Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
        int j, k, regKey;
        regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
        for(j=0; j<pPk->nKeyCol; j++){
          k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
          assert( k>=0 && k<pIdx->nColumn );
          sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
          analyzeVdbeCommentIndexWithColumnName(v,pIdx,k);
        }
        sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
        sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
      }
    assert( regRowid==(regStat4+2) );
    if( HasRowid(pTab) ){
      sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
    }else{
      Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
      int j, k, regKey;
      regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
      for(j=0; j<pPk->nKeyCol; j++){
        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
        assert( k>=0 && k<pIdx->nColumn );
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
        VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
      }
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
      sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
    }
    }
#endif
    assert( regChng==(regStat+1) );
    assert( regChng==(regStat4+1) );
    {
      sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
                                 &statPushFuncdef, 0);
    sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp,
                     (char*)&statPushFuncdef, P4_FUNCDEF);
      if( db->nAnalysisLimit ){
        int j1, j2, j3;
        j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
        j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
        j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
        VdbeCoverage(v);
        sqlite3VdbeJumpHere(v, j1);
        sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
    sqlite3VdbeChangeP5(v, 2+IsStat34);
    sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
        sqlite3VdbeJumpHere(v, j2);
        sqlite3VdbeJumpHere(v, j3);
      }else{
        sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
      }
    }

    /* Add the entry to the stat1 table. */
    callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
    callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
    assert( "BBB"[0]==SQLITE_AFF_TEXT );
    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
    sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
    sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
#endif
    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);

    /* Add the entries to the stat4 table. */
#ifdef SQLITE_ENABLE_STAT4
    /* Add the entries to the stat3 or stat4 table. */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
    {
      int regEq = regStat1;
      int regLt = regStat1+1;
      int regDLt = regStat1+2;
      int regSample = regStat1+3;
      int regCol = regStat1+4;
      int regSampleRowid = regCol + nCol;
      int addrNext;
      int addrIsNull;
      u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;

      pParse->nMem = MAX(pParse->nMem, regCol+nCol);

      addrNext = sqlite3VdbeCurrentAddr(v);
      callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
      callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
      addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
      VdbeCoverage(v);
      callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
      callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
      callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
      callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
      callStatGet(v, regStat4, STAT_GET_NLT, regLt);
      callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
      sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
      VdbeCoverage(v);
#ifdef SQLITE_ENABLE_STAT3
      sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
#else
      for(i=0; i<nCol; i++){
        sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
      }
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
#endif
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
      sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
      sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
      sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
      sqlite3VdbeJumpHere(v, addrIsNull);
    }
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

    /* End of analysis */
    sqlite3VdbeJumpHere(v, addrRewind);
  }


  /* Create a single sqlite_stat1 entry containing NULL as the index
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
1460
1461
1462
1463
1464
1465
1466

1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477

1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499



1500
1501
1502
1503
1504
1505
1506
1507







-
+










-
+










-
+










-
-
-
+







  Index *pIndex          /* Handle extra flags for this index, if not NULL */
){
  char *z = zIntArray;
  int c;
  int i;
  tRowcnt v;

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( z==0 ) z = "";
#else
  assert( z!=0 );
#endif
  for(i=0; *z && i<nOut; i++){
    v = 0;
    while( (c=z[0])>='0' && c<='9' ){
      v = v*10 + c - '0';
      z++;
    }
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    if( aOut ) aOut[i] = v;
    if( aLog ) aLog[i] = sqlite3LogEst(v);
#else
    assert( aOut==0 );
    UNUSED_PARAMETER(aOut);
    assert( aLog!=0 );
    aLog[i] = sqlite3LogEst(v);
#endif
    if( *z==' ' ) z++;
  }
#ifndef SQLITE_ENABLE_STAT4
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
  assert( pIndex!=0 ); {
#else
  if( pIndex ){
#endif
    pIndex->bUnordered = 0;
    pIndex->noSkipScan = 0;
    while( z[0] ){
      if( sqlite3_strglob("unordered*", z)==0 ){
        pIndex->bUnordered = 1;
      }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
        int sz = sqlite3Atoi(z+3);
        if( sz<2 ) sz = 2;
        pIndex->szIdxRow = sqlite3LogEst(sz);
        pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
      }else if( sqlite3_strglob("noskipscan*", z)==0 ){
        pIndex->noSkipScan = 1;
      }
#ifdef SQLITE_ENABLE_COSTMULT
      else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
        pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
      }
1569
1570
1571
1572
1573
1574
1575
1576

1577
1578
1579
1580
1581
1582
1583
1547
1548
1549
1550
1551
1552
1553

1554
1555
1556
1557
1558
1559
1560
1561







-
+







    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  }
  z = argv[2];

  if( pIndex ){
    tRowcnt *aiRowEst = 0;
    int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    /* Index.aiRowEst may already be set here if there are duplicate 
    ** sqlite_stat1 entries for this index. In that case just clobber
    ** the old data with the new instead of allocating a new array.  */
    if( pIndex->aiRowEst==0 ){
      pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
      if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db);
    }
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
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605

1606
1607
1608

1609
1610
1611
1612
1613
1614
1615
1616







-
+















-
+


-
+







}

/*
** If the Index.aSample variable is not NULL, delete the aSample[] array
** and its contents.
*/
void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pIdx->aSample ){
    int j;
    for(j=0; j<pIdx->nSample; j++){
      IndexSample *p = &pIdx->aSample[j];
      sqlite3DbFree(db, p->p);
    }
    sqlite3DbFree(db, pIdx->aSample);
  }
  if( db && db->pnBytesFreed==0 ){
    pIdx->nSample = 0;
    pIdx->aSample = 0;
  }
#else
  UNUSED_PARAMETER(db);
  UNUSED_PARAMETER(pIdx);
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
}

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Populate the pIdx->aAvgEq[] array based on the samples currently
** stored in pIdx->aSample[]. 
*/
static void initAvgEq(Index *pIdx){
  if( pIdx ){
    IndexSample *aSample = pIdx->aSample;
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
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







-
+



-
+
+








+







    Table *pTab = sqlite3FindTable(db, zName, zDb);
    if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
  }
  return pIdx;
}

/*
** Load the content from either the sqlite_stat4
** Load the content from either the sqlite_stat4 or sqlite_stat3 table 
** into the relevant Index.aSample[] arrays.
**
** Arguments zSql1 and zSql2 must point to SQL statements that return
** data equivalent to the following:
** data equivalent to the following (statements are different for stat3,
** see the caller of this function for details):
**
**    zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
**    zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
**
** where %Q is replaced with the database name before the SQL is executed.
*/
static int loadStatTbl(
  sqlite3 *db,                  /* Database handle */
  int bStat3,                   /* Assume single column records only */
  const char *zSql1,            /* SQL statement 1 (see above) */
  const char *zSql2,            /* SQL statement 2 (see above) */
  const char *zDb               /* Database name (e.g. "main") */
){
  int rc;                       /* Result codes from subroutines */
  sqlite3_stmt *pStmt = 0;      /* An SQL statement being run */
  char *zSql;                   /* Text of the SQL statement */
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761











1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1728
1729
1730
1731
1732
1733
1734







1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758

1759
1760
1761
1762
1763
1764
1765







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













-







    int i;          /* Bytes of space required */
    tRowcnt *pSpace;

    zIndex = (char *)sqlite3_column_text(pStmt, 0);
    if( zIndex==0 ) continue;
    nSample = sqlite3_column_int(pStmt, 1);
    pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
    assert( pIdx==0 || pIdx->nSample==0 );
    if( pIdx==0 ) continue;
    assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
    if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
      nIdxCol = pIdx->nKeyCol;
    }else{
      nIdxCol = pIdx->nColumn;
    assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
    /* Index.nSample is non-zero at this point if data has already been
    ** loaded from the stat4 table. In this case ignore stat3 data.  */
    if( pIdx==0 || pIdx->nSample ) continue;
    if( bStat3==0 ){
      assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
      if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
        nIdxCol = pIdx->nKeyCol;
      }else{
        nIdxCol = pIdx->nColumn;
      }
    }
    pIdx->nSampleCol = nIdxCol;
    nByte = sizeof(IndexSample) * nSample;
    nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
    nByte += nIdxCol * sizeof(tRowcnt);     /* Space for Index.aAvgEq[] */

    pIdx->aSample = sqlite3DbMallocZero(db, nByte);
    if( pIdx->aSample==0 ){
      sqlite3_finalize(pStmt);
      return SQLITE_NOMEM_BKPT;
    }
    pSpace = (tRowcnt*)&pIdx->aSample[nSample];
    pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
    pIdx->pTable->tabFlags |= TF_HasStat4;
    for(i=0; i<nSample; i++){
      pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
      pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
      pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
    }
    assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) );
  }
1797
1798
1799
1800
1801
1802
1803
1804

1805

1806
1807
1808
1809
1810
1811
1812
1780
1781
1782
1783
1784
1785
1786

1787
1788
1789
1790
1791
1792
1793
1794
1795
1796







-
+

+







    int nCol = 1;                 /* Number of columns in index */

    zIndex = (char *)sqlite3_column_text(pStmt, 0);
    if( zIndex==0 ) continue;
    pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
    if( pIdx==0 ) continue;
    /* This next condition is true if data has already been loaded from 
    ** the sqlite_stat4 table. */
    ** the sqlite_stat4 table. In this case ignore stat3 data.  */
    nCol = pIdx->nSampleCol;
    if( bStat3 && nCol>1 ) continue;
    if( pIdx!=pPrevIdx ){
      initAvgEq(pPrevIdx);
      pPrevIdx = pIdx;
    }
    pSample = &pIdx->aSample[pIdx->nSample];
    decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0);
    decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0);
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
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







-
+







-
+





+
+
+
+
+
+
+
+
+


-
+


-
+

-
+



-
-
+
+


-
+







  }
  rc = sqlite3_finalize(pStmt);
  if( rc==SQLITE_OK ) initAvgEq(pPrevIdx);
  return rc;
}

/*
** Load content from the sqlite_stat4 table into 
** Load content from the sqlite_stat4 and sqlite_stat3 tables into 
** the Index.aSample[] arrays of all indices.
*/
static int loadStat4(sqlite3 *db, const char *zDb){
  int rc = SQLITE_OK;             /* Result codes from subroutines */

  assert( db->lookaside.bDisable );
  if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
    rc = loadStatTbl(db,
    rc = loadStatTbl(db, 0,
      "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", 
      "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
      zDb
    );
  }

  if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){
    rc = loadStatTbl(db, 1,
      "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", 
      "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3",
      zDb
    );
  }

  return rc;
}
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

/*
** Load the content of the sqlite_stat1 and sqlite_stat4 tables. The
** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
** arrays. The contents of sqlite_stat4 are used to populate the
** arrays. The contents of sqlite_stat3/4 are used to populate the
** Index.aSample[] arrays.
**
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
** is returned. In this case, even if SQLITE_ENABLE_STAT4 was defined 
** during compilation and the sqlite_stat4 table is present, no data is 
** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined 
** during compilation and the sqlite_stat3/4 table is present, no data is 
** read from it.
**
** If SQLITE_ENABLE_STAT4 was defined during compilation and the 
** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the 
** sqlite_stat4 table is not present in the database, SQLITE_ERROR is
** returned. However, in this case, data is read from the sqlite_stat1
** table (if it is present) before returning.
**
** If an OOM error occurs, this function always sets db->mallocFailed.
** This means if the caller does not care about other errors, the return
** code may be ignored.
1888
1889
1890
1891
1892
1893
1894
1895

1896
1897
1898
1899
1900
1901
1902
1881
1882
1883
1884
1885
1886
1887

1888
1889
1890
1891
1892
1893
1894
1895







-
+







  for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
    Table *pTab = sqliteHashData(i);
    pTab->tabFlags &= ~TF_HasStat1;
  }
  for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
    Index *pIdx = sqliteHashData(i);
    pIdx->hasStat1 = 0;
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    sqlite3DeleteIndexSamples(db, pIdx);
    pIdx->aSample = 0;
#endif
  }

  /* Load new statistics out of the sqlite_stat1 table */
  sInfo.db = db;
1916
1917
1918
1919
1920
1921
1922
1923

1924
1925

1926
1927

1928
1929
1930
1931
1932
1933
1934
1909
1910
1911
1912
1913
1914
1915

1916
1917

1918
1919

1920
1921
1922
1923
1924
1925
1926
1927







-
+

-
+

-
+







  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
    Index *pIdx = sqliteHashData(i);
    if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
  }

  /* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( rc==SQLITE_OK ){
    DisableLookaside;
    db->lookaside.bDisable++;
    rc = loadStat4(db, sInfo.zDatabase);
    EnableLookaside;
    db->lookaside.bDisable--;
  }
  for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
    Index *pIdx = sqliteHashData(i);
    sqlite3_free(pIdx->aiRowEst);
    pIdx->aiRowEst = 0;
  }
#endif

Changes to src/attach.c.

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
41
42
43
44
45
46
47











48
49
50
51
52
53
54







-
-
-
-
-
-
-
-
-
-
-







    }else{
      pExpr->op = TK_STRING;
    }
  }
  return rc;
}

/*
** Return true if zName points to a name that may be used to refer to
** database iDb attached to handle db.
*/
int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){
  return (
      sqlite3StrICmp(db->aDb[iDb].zDbSName, zName)==0
   || (iDb==0 && sqlite3StrICmp("main", zName)==0)
  );
}

/*
** An SQL user-function registered to do the work of an ATTACH statement. The
** three arguments to the function come directly from an attach statement:
**
**     ATTACH DATABASE x AS y KEY z
**
**     SELECT sqlite_attach(x, y, z)
124
125
126
127
128
129
130

131
132


133
134
135
136
137
138
139
113
114
115
116
117
118
119
120


121
122
123
124
125
126
127
128
129







+
-
-
+
+







    if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
      zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", 
        db->aLimit[SQLITE_LIMIT_ATTACHED]
      );
      goto attach_error;
    }
    for(i=0; i<db->nDb; i++){
      char *z = db->aDb[i].zDbSName;
      assert( zName );
      if( sqlite3DbIsNamed(db, i, zName) ){
      assert( z && zName );
      if( sqlite3StrICmp(z, zName)==0 ){
        zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
        goto attach_error;
      }
    }
  
    /* Allocate the new entry in the db->aDb[] array and initialize the schema
    ** hash tables.
193
194
195
196
197
198
199




































200

201
202
203
204
205
206
207
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







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







#endif
    sqlite3BtreeLeave(pNew->pBt);
  }
  pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
  if( rc==SQLITE_OK && pNew->zDbSName==0 ){
    rc = SQLITE_NOMEM_BKPT;
  }


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

      case SQLITE_NULL:
        /* No key specified.  Use the key from URI filename, or if none,
        ** use the key from the main database. */
        if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){
          sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
          if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
            rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
          }
        }
        break;
    }
  }
#endif
  sqlite3_free_filename( zPath );
  sqlite3_free( zPath );

  /* If the file was opened successfully, read the schema for the new database.
  ** If this fails, or if opening the file failed, then close the file and 
  ** remove the entry from the db->aDb[] array. i.e. put everything back the
  ** way we found it.
  */
  if( rc==SQLITE_OK ){
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
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







-








-
+










-
-
+
-




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







  int NotUsed,
  sqlite3_value **argv
){
  const char *zName = (const char *)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  int i;
  Db *pDb = 0;
  HashElem *pEntry;
  char zErr[128];

  UNUSED_PARAMETER(NotUsed);

  if( zName==0 ) zName = "";
  for(i=0; i<db->nDb; i++){
    pDb = &db->aDb[i];
    if( pDb->pBt==0 ) continue;
    if( sqlite3DbIsNamed(db, i, zName) ) break;
    if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break;
  }

  if( i>=db->nDb ){
    sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
    goto detach_error;
  }
  if( i<2 ){
    sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
    goto detach_error;
  }
  if( sqlite3BtreeTxnState(pDb->pBt)!=SQLITE_TXN_NONE
   || sqlite3BtreeIsInBackup(pDb->pBt)
  if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
  ){
    sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
    goto detach_error;
  }

  /* If any TEMP triggers reference the schema being detached, move those
  ** triggers to reference the TEMP schema itself. */
  assert( db->aDb[1].pSchema );
  pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash);
  while( pEntry ){
    Trigger *pTrig = (Trigger*)sqliteHashData(pEntry);
    if( pTrig->pTabSchema==pDb->pSchema ){
      pTrig->pTabSchema = pTrig->pSchema;
    }
    pEntry = sqliteHashNext(pEntry);
  }

  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;
  pDb->pSchema = 0;
  sqlite3CollapseDatabaseArray(db);
  return;

detach_error:
373
374
375
376
377
378
379
380
381





382
383
384
385
386
387
388
384
385
386
387
388
389
390


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







-
-
+
+
+
+
+







  regArgs = sqlite3GetTempRange(pParse, 4);
  sqlite3ExprCode(pParse, pFilename, regArgs);
  sqlite3ExprCode(pParse, pDbname, regArgs+1);
  sqlite3ExprCode(pParse, pKey, regArgs+2);

  assert( v || db->mallocFailed );
  if( v ){
    sqlite3VdbeAddFunctionCall(pParse, 0, regArgs+3-pFunc->nArg, regArgs+3,
                               pFunc->nArg, pFunc, 0);
    sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3,
                      (char *)pFunc, P4_FUNCDEF);
    assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
    sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
 
    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
    ** statement only). For DETACH, set it to false (expire all existing
    ** statements).
    */
    sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
  }
  
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
443
444
445
446
447
448
449
























































450
451
452
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469

470







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490









491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605


606
607
608
609


610
611
612

613
614
615
616
617




618
619
620
621
622
623
624
625
626
627
628

629
630
631







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











-
+
+
+






-
+
-
-
-
-
-
-
-




















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





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





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









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





-
-
-
-
+
+
+
+







-



    "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;
  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);
  pFix->bVarOnly = (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;
}
  int i;
  const char *zDb;
  struct SrcList_item *pItem;

  if( NEVER(pList==0) ) return 0;
  zDb = pFix->zDb;
  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pFix->bVarOnly==0 ){
      if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
        sqlite3ErrorMsg(pFix->pParse,
            "%s %T cannot reference objects in database %s",
            pFix->zType, pFix->pName, pItem->zDatabase);
        return 1;
      }
      sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
      pItem->zDatabase = 0;
      pItem->pSchema = pFix->pSchema;
    }
#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 sqlite3WalkSelect(&pFix->w, pSelect);
      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( 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 sqlite3WalkExpr(&pFix->w, pExpr);
        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( sqlite3WalkSelect(&pFix->w, pStep->pSelect)
     || sqlite3WalkExpr(&pFix->w, pStep->pWhere) 
    if( sqlite3FixSelect(pFix, pStep->pSelect) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pStep->pWhere) ){
     || sqlite3WalkExprList(&pFix->w, pStep->pExprList)
     || sqlite3FixSrcList(pFix, pStep->pFrom)
      return 1;
    }
    if( sqlite3FixExprList(pFix, pStep->pExprList) ){
    ){
      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)
      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

Changes to src/auth.c.

74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88







-
+







){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  db->xAuth = (sqlite3_xauth)xAuth;
  db->pAuthArg = pArg;
  if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1);
  sqlite3ExpirePreparedStatements(db, 0);
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}

/*
** Write an error message into pParse->zErrMsg that explains that the
** user-supplied authorization function returned an illegal value.
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
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 );
  assert( pParse->db->xAuth!=0 );
  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; iSrc<pTabList->nSrc; iSrc++){
    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( pTab==0 ) return;
  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<pParse->db->nDb );
  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
204
205
206
207
208
209
210
211





212
213
214
215
216
217
218
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->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){
  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.
  **

Changes to src/backup.c.

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







-
+










-
+








/*
** Attempt to set the page size of the destination to match the page size
** of the source.
*/
static int setDestPgsz(sqlite3_backup *p){
  int rc;
  rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
  rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
  return rc;
}

/*
** Check that there is no open read-transaction on the b-tree passed as the
** second argument. If there is not, return SQLITE_OK. Otherwise, if there
** is an open read-transaction, return SQLITE_ERROR and leave an error 
** message in database handle db.
*/
static int checkReadTransaction(sqlite3 *db, Btree *p){
  if( sqlite3BtreeTxnState(p)!=SQLITE_TXN_NONE ){
  if( sqlite3BtreeIsInReadTrans(p) ){
    sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}

/*
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
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







+
+
+
+
+
+
+















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







  int bUpdate                     /* True for an update, false otherwise */
){
  Pager * const pDestPager = sqlite3BtreePager(p->pDest);
  const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
  int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
  const int nCopy = MIN(nSrcPgsz, nDestPgsz);
  const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
#ifdef SQLITE_HAS_CODEC
  /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
  ** guaranteed that the shared-mutex is held by this thread, handle
  ** p->pSrc may not actually be the owner.  */
  int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
  int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest);
#endif
  int rc = SQLITE_OK;
  i64 iOff;

  assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
  assert( p->bDestLocked );
  assert( !isFatalError(p->rc) );
  assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
  assert( zSrcData );

  /* Catch the case where the destination is an in-memory database and the
  ** page sizes of the source and destination differ. 
  */
  if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
    rc = SQLITE_READONLY;
  }

#ifdef SQLITE_HAS_CODEC
  /* Backup is not possible if the page size of the destination is changing
  ** and a codec is in use.
  */
  if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
    rc = SQLITE_READONLY;
  }

  /* Backup is not possible if the number of bytes of reserve space differ
  ** between source and destination.  If there is a difference, try to
  ** fix the destination to agree with the source.  If that is not possible,
  ** then the backup cannot proceed.
  */
  if( nSrcReserve!=nDestReserve ){
    u32 newPgsz = nSrcPgsz;
    rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
    if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
  }
#endif

  /* This loop runs once for each destination page spanned by the source 
  ** page. For each iteration, variable iOff is set to the byte offset
  ** of the destination page.
  */
  for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
    DbPage *pDestPg = 0;
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391







-
+







      rc = SQLITE_OK;
    }

    /* If there is no open read-transaction on the source database, open
    ** one now. If a transaction is opened here, then it will be closed
    ** before this function exits.
    */
    if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){
    if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
      rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0);
      bCloseTrans = 1;
    }

    /* If the destination database has not yet been locked (i.e. if this
    ** is the first call to backup_step() for the current backup operation),
    ** try to set its page size to the same as the source database. This
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
615
616
617
618
619
620
621

622
623

624
625
626
627
628
629
630







-


-








  /* Detach this backup from the source pager. */
  if( p->pDestDb ){
    p->pSrc->nBackup--;
  }
  if( p->isAttached ){
    pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
    assert( pp!=0 );
    while( *pp!=p ){
      pp = &(*pp)->pNext;
      assert( pp!=0 );
    }
    *pp = p->pNext;
  }

  /* If a transaction is still open on the Btree, roll it back. */
  sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);

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
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793

794
795
796
797
798
799
800







-
+


















+
+
+
+

















-
+






int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
  int rc;
  sqlite3_file *pFd;              /* File descriptor for database pTo */
  sqlite3_backup b;
  sqlite3BtreeEnter(pTo);
  sqlite3BtreeEnter(pFrom);

  assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE );
  assert( sqlite3BtreeIsInTrans(pTo) );
  pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
  if( pFd->pMethods ){
    i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
    rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte);
    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
    if( rc ) goto copy_finished;
  }

  /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
  ** to 0. This is used by the implementations of sqlite3_backup_step()
  ** and sqlite3_backup_finish() to detect that they are being called
  ** from this function, not directly by the user.
  */
  memset(&b, 0, sizeof(b));
  b.pSrcDb = pFrom->db;
  b.pSrc = pFrom;
  b.pDest = pTo;
  b.iNext = 1;

#ifdef SQLITE_HAS_CODEC
  sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
#endif

  /* 0x7FFFFFFF is the hard limit for the number of pages in a database
  ** file. By passing this as the number of pages to copy to
  ** sqlite3_backup_step(), we can guarantee that the copy finishes 
  ** within a single call (unless an error occurs). The assert() statement
  ** checks this assumption - (p->rc) should be set to either SQLITE_DONE 
  ** or an error code.  */
  sqlite3_backup_step(&b, 0x7FFFFFFF);
  assert( b.rc!=SQLITE_OK );

  rc = sqlite3_backup_finish(&b);
  if( rc==SQLITE_OK ){
    pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
  }else{
    sqlite3PagerClearCache(sqlite3BtreePager(b.pDest));
  }

  assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE );
  assert( sqlite3BtreeIsInTrans(pTo)==0 );
copy_finished:
  sqlite3BtreeLeave(pFrom);
  sqlite3BtreeLeave(pTo);
  return rc;
}
#endif /* SQLITE_OMIT_VACUUM */

Changes to src/btree.c.

65
66
67
68
69
70
71
72

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

72
73
74
75
76
77
78
79







-
+







#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** A list of BtShared objects that are eligible for participation
** in shared cache.  This variable has file scope during normal builds,
** but the test harness needs to access it so we make it global for 
** test builds.
**
** Access to this variable is protected by SQLITE_MUTEX_STATIC_MAIN.
** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER.
*/
#ifdef SQLITE_TEST
BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
#else
static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
#endif
#endif /* SQLITE_OMIT_SHARED_CACHE */
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
106
107
108
109
110
111
112











113
114
115
116
117
118
119







-
-
-
-
-
-
-
-
-
-
-







  */
  #define querySharedCacheTableLock(a,b,c) SQLITE_OK
  #define setSharedCacheTableLock(a,b,c) SQLITE_OK
  #define clearAllSharedCacheTableLocks(a)
  #define downgradeAllSharedCacheTableLocks(a)
  #define hasSharedCacheTableLock(a,b,c,d) 1
  #define hasReadConflicts(a, b) 0
#endif

#ifdef SQLITE_DEBUG
/*
** Return and reset the seek counter for a Btree object.
*/
sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){
  u64 n =  pBt->nSeek;
  pBt->nSeek = 0;
  return n;
}
#endif

/*
** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single
** (MemPage*) as an argument. The (MemPage*) must not be NULL.
**
** If SQLITE_DEBUG is not defined, then this macro is equivalent to
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
196
197
198
199
200
201
202

203
204
205

206
207
208
209
210
211
212

213
214
215
216
217
218
219







-



-
+






-








  /* Figure out the root-page that the lock should be held on. For table
  ** b-trees, this is just the root page of the b-tree being read or
  ** written. For index b-trees, it is the root page of the associated
  ** table.  */
  if( isIndex ){
    HashElem *p;
    int bSeen = 0;
    for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
      Index *pIdx = (Index *)sqliteHashData(p);
      if( pIdx->tnum==(int)iRoot ){
        if( bSeen ){
        if( iTab ){
          /* Two or more indexes share the same root page.  There must
          ** be imposter tables.  So just return true.  The assert is not
          ** useful in that case. */
          return 1;
        }
        iTab = pIdx->pTable->tnum;
        bSeen = 1;
      }
    }
  }else{
    iTab = iRoot;
  }

  /* Search for the required lock. Either a write-lock on root-page iTab, a 
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365







-
+








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

  /* A connection with the read-uncommitted flag set will never try to
  ** obtain a read-lock using this function. The only read-lock obtained
  ** by a connection in read-uncommitted mode is on the sqlite_schema 
  ** by a connection in read-uncommitted mode is on the sqlite_master 
  ** table, and that lock is obtained in BtreeBeginTrans().  */
  assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK );

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

628
629
630
631
632
633
634
607
608
609
610
611
612
613

614
615
616
617
618
619
620
621







-
+







**
** This function is called when a free-list leaf page is removed from the
** free-list for reuse. It returns false if it is safe to retrieve the
** page from the pager layer with the 'no-content' flag set. True otherwise.
*/
static int btreeGetHasContent(BtShared *pBt, Pgno pgno){
  Bitvec *p = pBt->pHasContent;
  return p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTestNotNull(p, pgno));
  return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno)));
}

/*
** Clear (destroy) the BtShared.pHasContent bitvec. This should be
** invoked at the conclusion of each write-transaction.
*/
static void btreeClearHasContent(BtShared *pBt){
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
695
696
697
698
699
700
701



702
703
704
705
706
707
708







-
-
-







static int saveCursorPosition(BtCursor *pCur){
  int rc;

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

  if( pCur->curFlags & BTCF_Pinned ){
    return SQLITE_CONSTRAINT_PINNED;
  }
  if( pCur->eState==CURSOR_SKIPNEXT ){
    pCur->eState = CURSOR_VALID;
  }else{
    pCur->skipNext = 0;
  }

  rc = saveCursorKey(pCur);
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
984
985
986
987
988
989
990

991
992
993
994
995
996
997
998







-
+







  Pgno iPtrmap;     /* The pointer map page number */
  int offset;       /* Offset in pointer map page */
  int rc;           /* Return code from subfunctions */

  if( *pRC ) return;

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

  assert( pBt->autoVacuum );
  if( key==0 ){
    *pRC = SQLITE_CORRUPT_BKPT;
    return;
  }
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
1123
1124
1125
1126
1127
1128
1129


















1130
1131
1132
1133
1134
1135
1136







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







    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.
**
** btreeParseCellPtr()        =>   table btree leaf nodes
1485
1486
1487
1488
1489
1490
1491
1492

1493
1494
1495
1496
1497
1498
1499
1451
1452
1453
1454
1455
1456
1457

1458
1459
1460
1461
1462
1463
1464
1465







-
+







        }
        if( iFree2 ){
          if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
          sz2 = get2byte(&data[iFree2+2]);
          if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
          memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
          sz += sz2;
        }else if( NEVER(iFree+sz>usableSize) ){
        }else if( iFree+sz>usableSize ){
          return SQLITE_CORRUPT_PAGE(pPage);
        }

        cbrk = top+sz;
        assert( cbrk+(iFree-top) <= usableSize );
        memmove(&data[cbrk], &data[top], iFree-top);
        for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
1658
1659
1660
1661
1662
1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686


1687
1688
1689
1690

1691
1692
1693
1694
1695
1696
1697
1698
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







-
+


















-
-
-
+
+
-
-
-
-
+
-







  assert( gap<=65536 );
  /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
  ** and the reserved space is zero (the usual value for reserved space)
  ** then the cell content offset of an empty page wants to be 65536.
  ** However, that integer is too large to be stored in a 2-byte unsigned
  ** integer, so a value of 0 is used in its place. */
  top = get2byte(&data[hdr+5]);
  assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
  assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
  if( gap>top ){
    if( top==0 && pPage->pBt->usableSize==65536 ){
      top = 65536;
    }else{
      return SQLITE_CORRUPT_PAGE(pPage);
    }
  }

  /* If there is enough space between gap and top for one more cell pointer,
  ** and if the freelist is not empty, then search the
  ** freelist looking for a slot big enough to satisfy the request.
  */
  testcase( gap+2==top );
  testcase( gap+1==top );
  testcase( gap==top );
  if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){
    u8 *pSpace = pageFindSlot(pPage, nByte, &rc);
    if( pSpace ){
      int g2;
      assert( pSpace+nByte<=data+pPage->pBt->usableSize );
      *pIdx = g2 = (int)(pSpace-data);
      assert( pSpace>=data && (pSpace - data)<65536 );
      *pIdx = (int)(pSpace - data);
      if( NEVER(g2<=gap) ){
        return SQLITE_CORRUPT_PAGE(pPage);
      }else{
        return SQLITE_OK;
      return SQLITE_OK;
      }
    }else if( rc ){
      return rc;
    }
  }

  /* The request could not be fulfilled using a freelist slot.  Check
  ** to see if defragmentation is necessary.
1758
1759
1760
1761
1762
1763
1764
1765

1766
1767
1768
1769
1770

1771
1772
1773
1774
1775
1776
1777
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730

1731
1732
1733
1734
1735
1736
1737
1738







-
+




-
+







  hdr = pPage->hdrOffset;
  iPtr = hdr + 1;
  if( data[iPtr+1]==0 && data[iPtr]==0 ){
    iFreeBlk = 0;  /* Shortcut for the case when the freelist is empty */
  }else{
    while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
      if( iFreeBlk<iPtr+4 ){
        if( iFreeBlk==0 ) break; /* TH3: corrupt082.100 */
        if( iFreeBlk==0 ) break;
        return SQLITE_CORRUPT_PAGE(pPage);
      }
      iPtr = iFreeBlk;
    }
    if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
    if( iFreeBlk>pPage->pBt->usableSize-4 ){
      return SQLITE_CORRUPT_PAGE(pPage);
    }
    assert( iFreeBlk>iPtr || iFreeBlk==0 );
  
    /* At this point:
    **    iFreeBlk:   First freeblock after iStart, or zero if none
    **    iPtr:       The address of a pointer to iFreeBlk
1806
1807
1808
1809
1810
1811
1812
1813
1814

1815
1816
1817
1818
1819
1820
1821
1767
1768
1769
1770
1771
1772
1773


1774
1775
1776
1777
1778
1779
1780
1781







-
-
+







    data[hdr+7] -= nFrag;
  }
  x = get2byte(&data[hdr+5]);
  if( iStart<=x ){
    /* The new freeblock is at the beginning of the cell content area,
    ** so just extend the cell content area rather than create another
    ** freelist entry */
    if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage);
    if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage);
    if( iStart<x || iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage);
    put2byte(&data[hdr+1], iFreeBlk);
    put2byte(&data[hdr+5], iEnd);
  }else{
    /* Insert the new freeblock into the freelist */
    put2byte(&data[iPtr], iStart);
  }
  if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
1927
1928
1929
1930
1931
1932
1933
1934

1935
1936
1937
1938
1939
1940
1941
1887
1888
1889
1890
1891
1892
1893

1894
1895
1896
1897
1898
1899
1900
1901







-
+







  ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
  ** start of the first freeblock on the page, or is zero if there are no
  ** freeblocks. */
  pc = get2byte(&data[hdr+1]);
  nFree = data[hdr+7] + top;  /* Init nFree to non-freeblock free space */
  if( pc>0 ){
    u32 next, size;
    if( pc<top ){
    if( pc<iCellFirst ){
      /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
      ** always be at least one cell before the first freeblock.
      */
      return SQLITE_CORRUPT_PAGE(pPage); 
    }
    while( 1 ){
      if( pc>iCellLast ){
1961
1962
1963
1964
1965
1966
1967
1968

1969
1970
1971
1972
1973
1974
1975
1921
1922
1923
1924
1925
1926
1927

1928
1929
1930
1931
1932
1933
1934
1935







-
+







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

/*
2166
2167
2168
2169
2170
2171
2172
2173

2174

2175
2176
2177
2178
2179
2180
2181
2126
2127
2128
2129
2130
2131
2132

2133
2134
2135
2136
2137
2138
2139
2140
2141
2142







-
+

+







/*
** Return the size of the database file in pages. If there is any kind of
** error, return ((unsigned int)-1).
*/
static Pgno btreePagecount(BtShared *pBt){
  return pBt->nPage;
}
Pgno sqlite3BtreeLastPage(Btree *p){
u32 sqlite3BtreeLastPage(Btree *p){
  assert( sqlite3BtreeHoldsMutex(p) );
  assert( ((p->pBt->nPage)&0x80000000)==0 );
  return btreePagecount(p->pBt);
}

/*
** Get a page from the pager and initialize it.
**
** If pCur!=0 then the page is being fetched as part of a moveToChild()
2330
2331
2332
2333
2334
2335
2336
2337


2338
2339
2340
2341
2342
2343
2344
2291
2292
2293
2294
2295
2296
2297

2298
2299
2300
2301
2302
2303
2304
2305
2306







-
+
+







/*
** Invoke the busy handler for a btree.
*/
static int btreeInvokeBusyHandler(void *pArg){
  BtShared *pBt = (BtShared*)pArg;
  assert( pBt->db );
  assert( sqlite3_mutex_held(pBt->db->mutex) );
  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
                                  sqlite3PagerFile(pBt->pPager));
}

/*
** Open a database file.
** 
** zFilename is the name of the database file.  If zFilename is NULL
** then an ephemeral database is created.  The ephemeral database might
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446



2447
2448
2449
2450
2451
2452
2453

2454
2455
2456
2457
2458
2459
2460
2396
2397
2398
2399
2400
2401
2402






2403
2404
2405

2406
2407
2408
2409
2410

2411
2412
2413
2414
2415
2416
2417
2418







-
-
-
-
-
-
+
+
+
-





-
+







      }
      if( isMemdb ){
        memcpy(zFullPathname, zFilename, nFilename);
      }else{
        rc = sqlite3OsFullPathname(pVfs, zFilename,
                                   nFullPathname, zFullPathname);
        if( rc ){
          if( rc==SQLITE_OK_SYMLINK ){
            rc = SQLITE_OK;
          }else{
            sqlite3_free(zFullPathname);
            sqlite3_free(p);
            return rc;
          sqlite3_free(zFullPathname);
          sqlite3_free(p);
          return rc;
          }
        }
      }
#if SQLITE_THREADSAFE
      mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
      sqlite3_mutex_enter(mutexOpen);
      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
      sqlite3_mutex_enter(mutexShared);
#endif
      for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
        assert( pBt->nRef>0 );
        if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0))
                 && sqlite3PagerVfs(pBt->pPager)==pVfs ){
          int iDb;
2565
2566
2567
2568
2569
2570
2571
2572

2573
2574
2575
2576
2577
2578
2579
2523
2524
2525
2526
2527
2528
2529

2530
2531
2532
2533
2534
2535
2536
2537







-
+







   
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
    /* Add the new BtShared object to the linked list sharable BtShareds.
    */
    pBt->nRef = 1;
    if( p->sharable ){
      MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
      MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);)
      MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);)
      if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
        pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
        if( pBt->mutex==0 ){
          rc = SQLITE_NOMEM_BKPT;
          goto btree_open_out;
        }
      }
2630
2631
2632
2633
2634
2635
2636
2637

2638
2639
2640
2641
2642
2643
2644
2588
2589
2590
2591
2592
2593
2594

2595
2596
2597
2598
2599
2600
2601
2602







-
+







    sqlite3_file *pFile;

    /* If the B-Tree was successfully opened, set the pager-cache size to the
    ** default value. Except, when opening on an existing shared pager-cache,
    ** do not change the pager-cache size.
    */
    if( sqlite3BtreeSchema(p, 0, 0)==0 ){
      sqlite3BtreeSetCacheSize(p, SQLITE_DEFAULT_CACHE_SIZE);
      sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
    }

    pFile = sqlite3PagerFile(pBt->pPager);
    if( pFile->pMethods ){
      sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db);
    }
  }
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
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







-
+




-
-
+
+


















-
+







** Decrement the BtShared.nRef counter.  When it reaches zero,
** remove the BtShared structure from the sharing list.  Return
** true if the BtShared.nRef counter reaches zero and return
** false if it is still positive.
*/
static int removeFromSharingList(BtShared *pBt){
#ifndef SQLITE_OMIT_SHARED_CACHE
  MUTEX_LOGIC( sqlite3_mutex *pMainMtx; )
  MUTEX_LOGIC( sqlite3_mutex *pMaster; )
  BtShared *pList;
  int removed = 0;

  assert( sqlite3_mutex_notheld(pBt->mutex) );
  MUTEX_LOGIC( pMainMtx = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); )
  sqlite3_mutex_enter(pMainMtx);
  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  sqlite3_mutex_enter(pMaster);
  pBt->nRef--;
  if( pBt->nRef<=0 ){
    if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
      GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
    }else{
      pList = GLOBAL(BtShared*,sqlite3SharedCacheList);
      while( ALWAYS(pList) && pList->pNext!=pBt ){
        pList=pList->pNext;
      }
      if( ALWAYS(pList) ){
        pList->pNext = pBt->pNext;
      }
    }
    if( SQLITE_THREADSAFE ){
      sqlite3_mutex_free(pBt->mutex);
    }
    removed = 1;
  }
  sqlite3_mutex_leave(pMainMtx);
  sqlite3_mutex_leave(pMaster);
  return removed;
#else
  return 1;
#endif
}

/*
2733
2734
2735
2736
2737
2738
2739

2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753






2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
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







+




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


-







}

/*
** Close an open database and invalidate all cursors.
*/
int sqlite3BtreeClose(Btree *p){
  BtShared *pBt = p->pBt;
  BtCursor *pCur;

  /* Close all cursors opened via this handle.  */
  assert( sqlite3_mutex_held(p->db->mutex) );
  sqlite3BtreeEnter(p);

  /* Verify that no other cursors have this Btree open */
#ifdef SQLITE_DEBUG
  {
    BtCursor *pCur = pBt->pCursor;
    while( pCur ){
      BtCursor *pTmp = pCur;
      pCur = pCur->pNext;
      assert( pTmp->pBtree!=p );

  pCur = pBt->pCursor;
  while( pCur ){
    BtCursor *pTmp = pCur;
    pCur = pCur->pNext;
    if( pTmp->pBtree==p ){
      sqlite3BtreeCloseCursor(pTmp);
    }
  }
#endif

  /* Rollback any active transaction and free the handle structure.
  ** The call to sqlite3BtreeRollback() drops any table-locks held by
  ** this handle.
  */
  sqlite3BtreeRollback(p, SQLITE_OK, 0);
  sqlite3BtreeLeave(p);
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
2839
2840
2841
2842
2843
2844
2845

2846

2847
2848
2849

2850


2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863

2864
2865
2866
2867
2868
2869
2870







-

-
+

+
-
+
-
-
+




+
+
+





-







** bytes per page is left unchanged.
**
** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size
** and autovacuum mode can no longer be changed.
*/
int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
  int rc = SQLITE_OK;
  int x;
  BtShared *pBt = p->pBt;
  assert( nReserve>=0 && nReserve<=255 );
  assert( nReserve>=-1 && nReserve<=255 );
  sqlite3BtreeEnter(p);
#if SQLITE_HAS_CODEC
  pBt->nReserveWanted = nReserve;
  if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve;
  x = pBt->pageSize - pBt->usableSize;
  if( nReserve<x ) nReserve = x;
#endif
  if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
    sqlite3BtreeLeave(p);
    return SQLITE_READONLY;
  }
  if( nReserve<0 ){
    nReserve = pBt->pageSize - pBt->usableSize;
  }
  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);
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
2897
2898
2899
2900
2901
2902
2903
2904

2905


2906
2907


2908
2909
2910


2911
2912
2913
2914
2915

2916
2917
2918
2919
2920
2921
2922
2923
2924


2925
2926
2927
2928
2929
2930
2931
2932
2933







+
-
+
-
-
+

-
-
+
+

-
-
+
+
+
+

-
+








-
-
+
+







}

/*
** Return the number of bytes of space at the end of every page that
** are intentually left unused.  This is the "reserved" space that is
** sometimes used by extensions.
**
** If SQLITE_HAS_MUTEX is defined then the number returned is the
** The value returned is the larger of the current reserve size and
** greater of the current reserved space and the maximum requested
** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES.
** The amount of reserve can only grow - never shrink.
** reserve space.
*/
int sqlite3BtreeGetRequestedReserve(Btree *p){
  int n1, n2;
int sqlite3BtreeGetOptimalReserve(Btree *p){
  int n;
  sqlite3BtreeEnter(p);
  n1 = (int)p->pBt->nReserveWanted;
  n2 = sqlite3BtreeGetReserveNoMutex(p);
  n = sqlite3BtreeGetReserveNoMutex(p);
#ifdef SQLITE_HAS_CODEC
  if( n<p->pBt->optimalReserve ) n = p->pBt->optimalReserve;
#endif
  sqlite3BtreeLeave(p);
  return n1>n2 ? n1 : n2;
  return n;
}


/*
** Set the maximum page count for a database if mxPage is positive.
** No changes are made if mxPage is 0 or negative.
** Regardless of the value of mxPage, return the maximum page count.
*/
Pgno sqlite3BtreeMaxPageCount(Btree *p, Pgno mxPage){
  Pgno n;
int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){
  int n;
  sqlite3BtreeEnter(p);
  n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage);
  sqlite3BtreeLeave(p);
  return n;
}

/*
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425

3426
3427
3428
3429
3430
3431
3432
3359
3360
3361
3362
3363
3364
3365

3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380

3381
3382
3383
3384
3385
3386
3387
3388







-















-
+







** One or the other of the two processes must give way or there can be
** no progress.  By returning SQLITE_BUSY and not invoking the busy callback
** when A already has a read lock, we encourage A to give up and let B
** proceed.
*/
int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
  BtShared *pBt = p->pBt;
  Pager *pPager = pBt->pPager;
  int rc = SQLITE_OK;

  sqlite3BtreeEnter(p);
  btreeIntegrity(p);

  /* If the btree is already in a write-transaction, or it
  ** is already in a read-transaction and a read-transaction
  ** is requested, this is a no-op.
  */
  if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
    goto trans_begun;
  }
  assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );

  if( (p->db->flags & SQLITE_ResetDatabase) 
   && sqlite3PagerIsreadonly(pPager)==0 
   && sqlite3PagerIsreadonly(pBt->pPager)==0 
  ){
    pBt->btsFlags &= ~BTS_READ_ONLY;
  }

  /* Write transactions are not possible on a read-only database */
  if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
    rc = SQLITE_READONLY;
3460
3461
3462
3463
3464
3465
3466
3467

3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498

3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516

3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3416
3417
3418
3419
3420
3421
3422

3423
3424
3425
3426
3427
3428












3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441

3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454

3455
3456
3457
3458

3459



3460
3461
3462
3463
3464
3465
3466







-
+





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













-
+












-




-
+
-
-
-







    }
  }
#endif

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

  pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
  if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
  do {
    sqlite3PagerWalDb(pPager, p->db);

#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
    /* If transitioning from no transaction directly to a write transaction,
    ** block for the WRITER lock first if possible. */
    if( pBt->pPage1==0 && wrflag ){
      assert( pBt->inTransaction==TRANS_NONE );
      rc = sqlite3PagerWalWriteLock(pPager, 1);
      if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
    }
#endif

    /* Call lockBtree() until either pBt->pPage1 is populated or
    ** lockBtree() returns something other than SQLITE_OK. lockBtree()
    ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
    ** reading page 1 it discovers that the page-size of the database 
    ** file is not pBt->pageSize. In this case lockBtree() will update
    ** pBt->pageSize to the page-size of the file on disk.
    */
    while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) );

    if( rc==SQLITE_OK && wrflag ){
      if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
        rc = SQLITE_READONLY;
      }else{
        rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db));
        rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
        if( rc==SQLITE_OK ){
          rc = newDatabase(pBt);
        }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
          /* if there was no transaction opened when this function was
          ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
          ** code to SQLITE_BUSY. */
          rc = SQLITE_BUSY;
        }
      }
    }
  
    if( rc!=SQLITE_OK ){
      (void)sqlite3PagerWalWriteLock(pPager, 0);
      unlockBtreeIfUnused(pBt);
    }
  }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
          btreeInvokeBusyHandler(pBt) );
  sqlite3PagerWalDb(pPager, 0);
  sqlite3PagerResetLockTimeout(pBt->pPager);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
  if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif

  if( rc==SQLITE_OK ){
    if( p->inTrans==TRANS_NONE ){
      pBt->nTransaction++;
#ifndef SQLITE_OMIT_SHARED_CACHE
      if( p->sharable ){
        assert( p->lock.pBtree==p && p->lock.iTable==1 );
3564
3565
3566
3567
3568
3569
3570
3571

3572
3573
3574
3575
3576
3577
3578
3504
3505
3506
3507
3508
3509
3510

3511
3512
3513
3514
3515
3516
3517
3518







-
+







      *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);
    }
    if( wrflag ){
      /* This call makes sure that the pager has the correct number of
      ** open savepoints. If the second parameter is greater than 0 and
      ** the sub-journal is not already open, then it will be opened here.
      */
      rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint);
      rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
    }
  }

  btreeIntegrity(p);
  sqlite3BtreeLeave(p);
  return rc;
}
3915
3916
3917
3918
3919
3920
3921
3922

3923
3924
3925
3926
3927
3928
3929
3855
3856
3857
3858
3859
3860
3861

3862
3863
3864
3865
3866
3867
3868
3869







-
+







  if( !pBt->autoVacuum ){
    rc = SQLITE_DONE;
  }else{
    Pgno nOrig = btreePagecount(pBt);
    Pgno nFree = get4byte(&pBt->pPage1->aData[36]);
    Pgno nFin = finalDbSize(pBt, nOrig, nFree);

    if( nOrig<nFin || nFree>=nOrig ){
    if( nOrig<nFin ){
      rc = SQLITE_CORRUPT_BKPT;
    }else if( nFree>0 ){
      rc = saveAllCursors(pBt, 0, 0);
      if( rc==SQLITE_OK ){
        invalidateAllOverflowCache(pBt);
        rc = incrVacuumStep(pBt, nFin, nOrig, 0);
      }
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
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







-
-
-
+
+
+


-
+





-
+
















-
+







** At the end of this call, the rollback journal still exists on the
** disk and we are still holding all locks, so the transaction has not
** committed.  See sqlite3BtreeCommitPhaseTwo() for the second phase of the
** commit process.
**
** This call is a no-op if no write-transaction is currently active on pBt.
**
** Otherwise, sync the database file for the btree pBt. zSuperJrnl points to
** the name of a super-journal file that should be written into the
** individual journal file, or is NULL, indicating no super-journal file 
** Otherwise, sync the database file for the btree pBt. zMaster points to
** the name of a master journal file that should be written into the
** individual journal file, or is NULL, indicating no master journal file 
** (single database transaction).
**
** When this is called, the super-journal should already have been
** When this is called, the master journal should already have been
** created, populated with this journal pointer and synced to disk.
**
** Once this is routine has returned, the only thing required to commit
** the write-transaction for this database file is to delete the journal.
*/
int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){
int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
  int rc = SQLITE_OK;
  if( p->inTrans==TRANS_WRITE ){
    BtShared *pBt = p->pBt;
    sqlite3BtreeEnter(p);
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum ){
      rc = autoVacuumCommit(pBt);
      if( rc!=SQLITE_OK ){
        sqlite3BtreeLeave(p);
        return rc;
      }
    }
    if( pBt->bDoTruncate ){
      sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage);
    }
#endif
    rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zSuperJrnl, 0);
    rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
    sqlite3BtreeLeave(p);
  }
  return rc;
}

/*
** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback()
4103
4104
4105
4106
4107
4108
4109
4110

4111
4112
4113
4114
4115
4116
4117
4043
4044
4045
4046
4047
4048
4049

4050
4051
4052
4053
4054
4055
4056
4057







-
+







** drop locks.
**
** Normally, if an error occurs while the pager layer is attempting to 
** finalize the underlying journal file, this function returns an error and
** the upper layer will attempt a rollback. However, if the second argument
** is non-zero then this b-tree transaction is part of a multi-file 
** transaction. In this case, the transaction has already been committed 
** (by deleting a super-journal file) and the caller will ignore this 
** (by deleting a master journal file) and the caller will ignore this 
** functions return code. So, even if an error occurs in the pager layer,
** reset the b-tree objects internal state to indicate that the write
** transaction has been closed. This is quite safe, as the pager will have
** transitioned to the error state.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
4131
4132
4133
4134
4135
4136
4137
4138

4139
4140
4141
4142
4143
4144
4145
4071
4072
4073
4074
4075
4076
4077

4078
4079
4080
4081
4082
4083
4084
4085







-
+







    assert( pBt->inTransaction==TRANS_WRITE );
    assert( pBt->nTransaction>0 );
    rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
    if( rc!=SQLITE_OK && bCleanup==0 ){
      sqlite3BtreeLeave(p);
      return rc;
    }
    p->iBDataVersion--;  /* Compensate for pPager->iDataVersion++; */
    p->iDataVersion--;  /* Compensate for pPager->iDataVersion++; */
    pBt->inTransaction = TRANS_READ;
    btreeClearHasContent(pBt);
  }

  btreeEndTransaction(p);
  sqlite3BtreeLeave(p);
  return SQLITE_OK;
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4149
4150
4151
4152
4153
4154
4155












4156
4157
4158
4159
4160
4161
4162







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







      btreeReleaseAllCursorPages(p);
    }
    sqlite3BtreeLeave(pBtree);
  }
  return rc;
}

/*
** Set the pBt->nPage field correctly, according to the current
** state of the database.  Assume pBt->pPage1 is valid.
*/
static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
  int nPage = get4byte(&pPage1->aData[28]);
  testcase( nPage==0 );
  if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
  testcase( pBt->nPage!=nPage );
  pBt->nPage = nPage;
}

/*
** Rollback the transaction in progress.
**
** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
** Only write cursors are tripped if writeOnly is true but all cursors are
** tripped if writeOnly is false.  Any attempt to use
** a tripped cursor will result in an error.
4266
4267
4268
4269
4270
4271
4272
4273





4274
4275
4276
4277
4278
4279
4280
4194
4195
4196
4197
4198
4199
4200

4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212







-
+
+
+
+
+







      rc = rc2;
    }

    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call btreeGetPage() on page 1 again to make
    ** sure pPage1->aData is set correctly. */
    if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
      btreeSetNPage(pBt, pPage1);
      int nPage = get4byte(28+(u8*)pPage1->aData);
      testcase( nPage==0 );
      if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
      testcase( pBt->nPage!=nPage );
      pBt->nPage = nPage;
      releasePageOne(pPage1);
    }
    assert( countValidCursors(pBt, 1)==0 );
    pBt->inTransaction = TRANS_READ;
    btreeClearHasContent(pBt);
  }

4346
4347
4348
4349
4350
4351
4352
4353

4354
4355
4356
4357




4358
4359
4360
4361
4362
4363
4364
4278
4279
4280
4281
4282
4283
4284

4285
4286



4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297







-
+

-
-
-
+
+
+
+







      rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
    }
    if( rc==SQLITE_OK ){
      if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
        pBt->nPage = 0;
      }
      rc = newDatabase(pBt);
      btreeSetNPage(pBt, pBt->pPage1);
      pBt->nPage = get4byte(28 + pBt->pPage1->aData);

      /* pBt->nPage might be zero if the database was corrupt when 
      ** the transaction was started. Otherwise, it must be at least 1.  */
      assert( CORRUPT_DB || pBt->nPage>0 );
      /* The database size was written into the offset 28 of the header
      ** when the transaction started, so we know that the value at offset
      ** 28 is nonzero. */
      assert( pBt->nPage>0 );
    }
    sqlite3BtreeLeave(p);
  }
  return rc;
}

/*
4401
4402
4403
4404
4405
4406
4407
4408

4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426


4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445



4446
4447
4448
4449
4450
4451

4452
4453
4454
4455
4456
4457
4458
4459
4460
4461

4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486

4487
4488
4489
4490
4491
4492



4493

4494


4495

4496
4497
4498
4499
4500
4501
4502
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
4359

4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371






4372
4373
4374

4375
4376
4377
4378

4379
4380
4381
4382
4383
4384
4385
4386
4387
4388

4389
4390
4391
4392
4393
4394
4395
4396
4397
4398













4399
4400

4401
4402
4403
4404
4405


4406
4407
4408
4409
4410

4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421







-
+
















-
-
+
+
-












-
-
-
-
-
-
+
+
+
-




-
+









-
+









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


-
+




-
-
+
+
+

+
-
+
+

+







** will not work correctly.
**
** It is assumed that the sqlite3BtreeCursorZero() has been called
** on pCur to initialize the memory space prior to invoking this routine.
*/
static int btreeCursor(
  Btree *p,                              /* The btree */
  Pgno iTable,                           /* Root page of table to open */
  int iTable,                            /* Root page of table to open */
  int wrFlag,                            /* 1 to write. 0 read-only */
  struct KeyInfo *pKeyInfo,              /* First arg to comparison function */
  BtCursor *pCur                         /* Space for new cursor */
){
  BtShared *pBt = p->pBt;                /* Shared b-tree handle */
  BtCursor *pX;                          /* Looping over other all cursors */

  assert( sqlite3BtreeHoldsMutex(p) );
  assert( wrFlag==0 
       || wrFlag==BTREE_WRCSR 
       || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) 
  );

  /* The following assert statements verify that if this is a sharable 
  ** b-tree database, the connection is holding the required table locks, 
  ** and that no other connection has any open cursor that conflicts with 
  ** this lock.  The iTable<1 term disables the check for corrupt schemas. */
  assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1))
  ** this lock.  */
  assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) );
          || iTable<1 );
  assert( wrFlag==0 || !hasReadConflicts(p, iTable) );

  /* Assert that the caller has opened the required transaction. */
  assert( p->inTrans>TRANS_NONE );
  assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
  assert( pBt->pPage1 && pBt->pPage1->aData );
  assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 );

  if( wrFlag ){
    allocateTempSpace(pBt);
    if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
  }
  if( iTable<=1 ){
    if( iTable<1 ){
      return SQLITE_CORRUPT_BKPT;
    }else if( btreePagecount(pBt)==0 ){
      assert( wrFlag==0 );
      iTable = 0;
  if( iTable==1 && btreePagecount(pBt)==0 ){
    assert( wrFlag==0 );
    iTable = 0;
    }
  }

  /* Now that no other errors can occur, finish filling in the BtCursor
  ** variables and link the cursor into the BtShared list.  */
  pCur->pgnoRoot = iTable;
  pCur->pgnoRoot = (Pgno)iTable;
  pCur->iPage = -1;
  pCur->pKeyInfo = pKeyInfo;
  pCur->pBtree = p;
  pCur->pBt = pBt;
  pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
  pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
  /* If there are two or more cursors on the same btree, then all such
  ** cursors *must* have the BTCF_Multiple flag set. */
  for(pX=pBt->pCursor; pX; pX=pX->pNext){
    if( pX->pgnoRoot==iTable ){
    if( pX->pgnoRoot==(Pgno)iTable ){
      pX->curFlags |= BTCF_Multiple;
      pCur->curFlags |= BTCF_Multiple;
    }
  }
  pCur->pNext = pBt->pCursor;
  pBt->pCursor = pCur;
  pCur->eState = CURSOR_INVALID;
  return SQLITE_OK;
}
static int btreeCursorWithLock(
  Btree *p,                              /* The btree */
  Pgno iTable,                           /* Root page of table to open */
  int wrFlag,                            /* 1 to write. 0 read-only */
  struct KeyInfo *pKeyInfo,              /* First arg to comparison function */
  BtCursor *pCur                         /* Space for new cursor */
){
  int rc;
  sqlite3BtreeEnter(p);
  rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
  sqlite3BtreeLeave(p);
  return rc;
}
int sqlite3BtreeCursor(
  Btree *p,                                   /* The btree */
  Pgno iTable,                                /* Root page of table to open */
  int iTable,                                 /* Root page of table to open */
  int wrFlag,                                 /* 1 to write. 0 read-only */
  struct KeyInfo *pKeyInfo,                   /* First arg to xCompare() */
  BtCursor *pCur                              /* Write new cursor here */
){
  if( p->sharable ){
    return btreeCursorWithLock(p, iTable, wrFlag, pKeyInfo, pCur);
  int rc;
  if( iTable<1 ){
    rc = SQLITE_CORRUPT_BKPT;
  }else{
    sqlite3BtreeEnter(p);
    return btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
    rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
    sqlite3BtreeLeave(p);
  }
  return rc;
}

/*
** Return the size of a BtCursor object in bytes.
**
** This interfaces is needed so that users of cursors can preallocate
** sufficient storage to hold a cursor.  The BtCursor object is opaque
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554

4555
4556
4557
4558
4559
4560
4561
4562
4460
4461
4462
4463
4464
4465
4466







4467

4468
4469
4470
4471
4472
4473
4474







-
-
-
-
-
-
-
+
-







        pPrev = pPrev->pNext;
      }while( ALWAYS(pPrev) );
    }
    btreeReleaseAllCursorPages(pCur);
    unlockBtreeIfUnused(pBt);
    sqlite3_free(pCur->aOverflow);
    sqlite3_free(pCur->pKey);
    if( (pBt->openFlags & BTREE_SINGLE) && pBt->pCursor==0 ){
      /* Since the BtShared is not sharable, there is no need to
      ** worry about the missing sqlite3BtreeLeave() call here.  */
      assert( pBtree->sharable==0 );
      sqlite3BtreeClose(pBtree);
    }else{
      sqlite3BtreeLeave(pBtree);
    sqlite3BtreeLeave(pBtree);
    }
    pCur->pBtree = 0;
  }
  return SQLITE_OK;
}

/*
** Make sure the BtCursor* given in the argument has a valid
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
4530
4531
4532
4533
4534
4535
4536












4537
4538
4539
4540
4541
4542
4543







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







  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->curIntKey );
  getCellInfo(pCur);
  return pCur->info.nKey;
}

/*
** Pin or unpin a cursor.
*/
void sqlite3BtreeCursorPin(BtCursor *pCur){
  assert( (pCur->curFlags & BTCF_Pinned)==0 );
  pCur->curFlags |= BTCF_Pinned;
}
void sqlite3BtreeCursorUnpin(BtCursor *pCur){
  assert( (pCur->curFlags & BTCF_Pinned)!=0 );
  pCur->curFlags &= ~BTCF_Pinned;
}

#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
/*
** Return the offset into the database file for the start of the
** payload to which the cursor is pointing.
*/
i64 sqlite3BtreeOffset(BtCursor *pCur){
  assert( cursorHoldsMutex(pCur) );
4872
4873
4874
4875
4876
4877
4878
4879

4880
4881
4882
4883
4884
4885
4886
4772
4773
4774
4775
4776
4777
4778

4779
4780
4781
4782
4783
4784
4785
4786







-
+









  if( rc==SQLITE_OK && amt>0 ){
    const u32 ovflSize = pBt->usableSize - 4;  /* Bytes content per ovfl page */
    Pgno nextPage;

    nextPage = get4byte(&aPayload[pCur->info.nLocal]);
 

    /* If the BtCursor.aOverflow[] has not been allocated, allocate it now.
    **
    ** The aOverflow[] array is sized at one entry for each overflow page
    ** in the overflow chain. The page number of the first overflow page is
    ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array
    ** means "not yet known" (the cache is lazily populated).
    */
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4811
4812
4813
4814
4815
4816
4817

4818
4819
4820
4821
4822
4823
4824







-







        offset = (offset%ovflSize);
      }
    }

    assert( rc==SQLITE_OK && amt>0 );
    while( nextPage ){
      /* If required, populate the overflow page-list cache. */
      if( nextPage > pBt->nPage ) return SQLITE_CORRUPT_BKPT;
      assert( pCur->aOverflow[iIdx]==0
              || pCur->aOverflow[iIdx]==nextPage
              || CORRUPT_DB );
      pCur->aOverflow[iIdx] = nextPage;

      if( offset>=ovflSize ){
        /* The only reason to read this page is to obtain the page
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4865
4866
4867
4868
4869
4870
4871

4872
4873
4874
4875
4876
4877
4878







-







        ){
          sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
          u8 aSave[4];
          u8 *aWrite = &pBuf[-4];
          assert( aWrite>=pBufStart );                         /* due to (6) */
          memcpy(aSave, aWrite, 4);
          rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
          if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT;
          nextPage = get4byte(aWrite);
          memcpy(aWrite, aSave, 4);
        }else
#endif

        {
          DbPage *pDbPage;
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5291
5292
5293
5294
5295
5296
5297

5298
5299
5300
5301
5302
5303
5304







-







    int ii;
    for(ii=0; ii<pCur->iPage; ii++){
      assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
    }
    assert( pCur->ix==pCur->pPage->nCell-1 );
    assert( pCur->pPage->leaf );
#endif
    *pRes = 0;
    return SQLITE_OK;
  }

  rc = moveToRoot(pCur);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_VALID );
    *pRes = 0;
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5393
5394
5395
5396
5397
5398
5399




5400
5401
5402
5403
5404
5405
5406







-
-
-
-







        }else{
          return rc;
        }
      }
    }
  }

#ifdef SQLITE_DEBUG
  pCur->pBtree->nSeek++;   /* Performance measurement during testing */
#endif

  if( pIdxKey ){
    xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
    pIdxKey->errCode = 0;
    assert( pIdxKey->default_rc==1 
         || pIdxKey->default_rc==0 
         || pIdxKey->default_rc==-1
    );
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637

5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
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
5537
5538
5539
5540
5541
5542







-










-
+






-







          **
          ** If the record is corrupt, the xRecordCompare routine may read
          ** up to two varints past the end of the buffer. An extra 18 
          ** bytes of padding is allocated at the end of the buffer in
          ** case this happens.  */
          void *pCellKey;
          u8 * const pCellBody = pCell - pPage->childPtrSize;
          const int nOverrun = 18;  /* Size of the overrun padding */
          pPage->xParseCell(pPage, pCellBody, &pCur->info);
          nCell = (int)pCur->info.nKey;
          testcase( nCell<0 );   /* True if key size is 2^32 or more */
          testcase( nCell==0 );  /* Invalid key size:  0x80 0x80 0x00 */
          testcase( nCell==1 );  /* Invalid key size:  0x80 0x80 0x01 */
          testcase( nCell==2 );  /* Minimum legal index key size */
          if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){
            rc = SQLITE_CORRUPT_PAGE(pPage);
            goto moveto_finish;
          }
          pCellKey = sqlite3Malloc( nCell+nOverrun );
          pCellKey = sqlite3Malloc( nCell+18 );
          if( pCellKey==0 ){
            rc = SQLITE_NOMEM_BKPT;
            goto moveto_finish;
          }
          pCur->ix = (u16)idx;
          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
          memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */
          pCur->curFlags &= ~BTCF_ValidOvfl;
          if( rc ){
            sqlite3_free(pCellKey);
            goto moveto_finish;
          }
          c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
          sqlite3_free(pCellKey);
5776
5777
5778
5779
5780
5781
5782
5783

5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798

5799
5800
5801
5802

5803
5804
5805
5806
5807
5808
5809
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







-
+














-
+
-
-
-
-
+







      pCur->eState = CURSOR_VALID;
      if( pCur->skipNext>0 ) return SQLITE_OK;
    }
  }

  pPage = pCur->pPage;
  idx = ++pCur->ix;
  if( !pPage->isInit || sqlite3FaultSim(412) ){
  if( !pPage->isInit ){
    /* The only known way for this to happen is for there to be a
    ** recursive SQL function that does a DELETE operation as part of a
    ** SELECT which deletes content out from under an active cursor
    ** in a corrupt database file where the table being DELETE-ed from
    ** has pages in common with the table being queried.  See TH3
    ** module cov1/btree78.test testcase 220 (2018-06-08) for an
    ** example. */
    return SQLITE_CORRUPT_BKPT;
  }

  /* If the database file is corrupt, it is possible for the value of idx 
  ** to be invalid here. This can only occur if a second cursor modifies
  ** the page while cursor pCur is holding a reference to it. Which can
  ** only happen if the database is corrupt in such a way as to link the
  ** page into more than one b-tree structure.
  ** page into more than one b-tree structure. */
  **
  ** Update 2019-12-23: appears to long longer be possible after the
  ** addition of anotherValidCursor() condition on balance_deeper().  */
  harmless( idx>pPage->nCell );
  testcase( idx>pPage->nCell );

  if( idx>=pPage->nCell ){
    if( !pPage->leaf ){
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
      if( rc ) return rc;
      return moveToLeftmost(pCur);
    }
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6219
6220
6221
6222
6223
6224
6225




6226
6227
6228
6229
6230
6231
6232







-
-
-
-







  ** first trunk page in the current free-list. This block tests if it
  ** is possible to add the page as a new free-list leaf.
  */
  if( nFree!=0 ){
    u32 nLeaf;                /* Initial number of leaf cells on trunk page */

    iTrunk = get4byte(&pPage1->aData[32]);
    if( iTrunk>btreePagecount(pBt) ){
      rc = SQLITE_CORRUPT_BKPT;
      goto freepage_out;
    }
    rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
    if( rc!=SQLITE_OK ){
      goto freepage_out;
    }

    nLeaf = get4byte(&pTrunk->aData[4]);
    assert( pBt->usableSize>32 );
6766
6767
6768
6769
6770
6771
6772





6773

6774
6775
6776
6777
6778
6779
6780
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661

6662
6663
6664
6665
6666
6667
6668
6669







+
+
+
+
+
-
+







  assert( *pRC==SQLITE_OK );
  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
  assert( MX_CELL(pPage->pBt)<=10921 );
  assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
  assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
  assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  /* The cell should normally be sized correctly.  However, when moving a
  ** malformed cell from a leaf page to an interior page, if the cell size
  ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
  ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
  ** the term after the || in the following assert(). */
  assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB );
  assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) );
  assert( pPage->nFree>=0 );
  if( pPage->nOverflow || sz+2>pPage->nFree ){
    if( pTemp ){
      memcpy(pTemp, pCell, sz);
      pCell = pTemp;
    }
    if( iChild ){
7024
7025
7026
7027
7028
7029
7030
7031

7032
7033
7034
7035
7036
7037
7038
6913
6914
6915
6916
6917
6918
6919

6920
6921
6922
6923
6924
6925
6926
6927







-
+








    pData -= sz;
    put2byte(pCellptr, (pData - aData));
    pCellptr += 2;
    if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
    memcpy(pData, pCell, sz);
    assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
    testcase( sz!=pPg->xCellSize(pPg,pCell) )
    testcase( sz!=pPg->xCellSize(pPg,pCell) );
    i++;
    if( i>=iEnd ) break;
    if( pCArray->ixNx[k]<=i ){
      k++;
      pSrcEnd = pCArray->apEnd[k];
    }
  }
7090
7091
7092
7093
7094
7095
7096
7097
7098

7099
7100
7101
7102
7103
7104
7105
6979
6980
6981
6982
6983
6984
6985


6986
6987
6988
6989
6990
6991
6992
6993







-
-
+







  assert( CORRUPT_DB || pPg->hdrOffset==0 );    /* Never called on page 1 */
  if( iEnd<=iFirst ) return 0;
  for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
  pEnd = pCArray->apEnd[k];
  while( 1 /*Exit by break*/ ){
    int sz, rc;
    u8 *pSlot;
    assert( pCArray->szCell[i]!=0 );
    sz = pCArray->szCell[i];
    sz = cachedCellSize(pCArray, i);
    if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
      if( (pData - pBegin)<sz ) return 1;
      pData -= sz;
      pSlot = pData;
    }
    /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
    ** database.  But they might for a corrupt database.  Hence use memmove()
7216
7217
7218
7219
7220
7221
7222
7223

7224
7225
7226
7227
7228
7229
7230
7104
7105
7106
7107
7108
7109
7110

7111
7112
7113
7114
7115
7116
7117
7118







-
+







  memcpy(pTmp, aData, pPg->pBt->usableSize);
#endif

  /* Remove cells from the start and end of the page */
  assert( nCell>=0 );
  if( iOld<iNew ){
    int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
    if( NEVER(nShift>nCell) ) return SQLITE_CORRUPT_BKPT;
    if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
    memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
    nCell -= nShift;
  }
  if( iNewEnd < iOldEnd ){
    int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
    assert( nCell>=nTail );
    nCell -= nTail;
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7140
7141
7142
7143
7144
7145
7146

7147
7148
7149
7150
7151
7152
7153







-







    int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
    if( iCell>=0 && iCell<nNew ){
      pCellptr = &pPg->aCellIdx[iCell * 2];
      if( nCell>iCell ){
        memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
      }
      nCell++;
      cachedCellSize(pCArray, iCell+iNew);
      if( pageInsertArray(
            pPg, pBegin, &pData, pCellptr,
            iCell+iNew, 1, pCArray
      ) ) goto editpage_fail;
    }
  }

7644
7645
7646
7647
7648
7649
7650
7651
7652

7653
7654
7655
7656
7657
7658
7659
7660
7531
7532
7533
7534
7535
7536
7537


7538

7539
7540
7541
7542
7543
7544
7545







-
-
+
-







  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);
    rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0);
    }
    if( rc ){
      memset(apOld, 0, (i+1)*sizeof(MemPage*));
      goto balance_cleanup;
    }
    if( apOld[i]->nFree<0 ){
      rc = btreeComputeFreeSpace(apOld[i]);
      if( rc ){
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695





7696
7697
7698
7699
7700
7701
7702
7570
7571
7572
7573
7574
7575
7576


7577

7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589







-
-

-
+
+
+
+
+







      ** 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 ){
        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);
    }
  }
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7633
7634
7635
7636
7637
7638
7639

7640
7641
7642
7643
7644
7645
7646







-







  for(i=0; i<nOld; i++){
    MemPage *pOld = apOld[i];
    int limit = pOld->nCell;
    u8 *aData = pOld->aData;
    u16 maskPage = pOld->maskPage;
    u8 *piCell = aData + pOld->cellOffset;
    u8 *piEnd;
    VVA_ONLY( int nCellAtStart = b.nCell; )

    /* Verify that all sibling pages are of the same "type" (table-leaf,
    ** table-interior, index-leaf, or index-interior).
    */
    if( pOld->aData[0]!=apOld[0]->aData[0] ){
      rc = SQLITE_CORRUPT_BKPT;
      goto balance_cleanup;
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7661
7662
7663
7664
7665
7666
7667




7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686

7687
7688
7689
7690
7691
7692
7693







-
-
-
-



















-







    ** This must be done in advance.  Once the balance starts, the cell
    ** offset section of the btree page will be overwritten and we will no
    ** long be able to find the cells if a pointer to each cell is not saved
    ** first.
    */
    memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
    if( pOld->nOverflow>0 ){
      if( NEVER(limit<pOld->aiOvfl[0]) ){
        rc = SQLITE_CORRUPT_BKPT;
        goto balance_cleanup;
      }
      limit = pOld->aiOvfl[0];
      for(j=0; j<limit; j++){
        b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
        piCell += 2;
        b.nCell++;
      }
      for(k=0; k<pOld->nOverflow; k++){
        assert( k==0 || pOld->aiOvfl[k-1]+1==pOld->aiOvfl[k] );/* NOTE 1 */
        b.apCell[b.nCell] = pOld->apOvfl[k];
        b.nCell++;
      }
    }
    piEnd = aData + pOld->cellOffset + 2*pOld->nCell;
    while( piCell<piEnd ){
      assert( b.nCell<nMaxCells );
      b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
      piCell += 2;
      b.nCell++;
    }
    assert( (b.nCell-nCellAtStart)==(pOld->nCell+pOld->nOverflow) );

    cntOld[i] = b.nCell;
    if( i<nOld-1 && !leafData){
      u16 sz = (u16)szNew[i];
      u8 *pTemp;
      assert( b.nCell<nMaxCells );
      b.szCell[b.nCell] = sz;
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7863
7864
7865
7866
7867
7868
7869



7870
7871
7872
7873
7874
7875
7876







-
-
-







  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;
8021
8022
8023
8024
8025
8026
8027
8028

8029
8030
8031
8032
8033
8034
8035
7899
7900
7901
7902
7903
7904
7905

7906
7907
7908
7909
7910
7911
7912
7913







-
+







  ** 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]) ){
      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 );
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
7942
7943
7944
7945
7946
7947
7948


7949
7950
7951
7952
7953
7954
7955







-
-







    nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0,
    nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0,
    nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0,
    nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0
  ));

  assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  assert( nNew>=1 && nNew<=ArraySize(apNew) );
  assert( apNew[nNew-1]!=0 );
  put4byte(pRight, apNew[nNew-1]->pgno);

  /* If the sibling pages are not leaves, ensure that the right-child pointer
  ** of the right-most new sibling page is set to the value that was 
  ** originally in the same field of the right-most old sibling page. */
  if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){
    MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1];
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
7980
7981
7982
7983
7984
7985
7986

7987
7988
7989
7990
7991
7992
7993







-







    int iOld = 0;

    for(i=0; i<b.nCell; i++){
      u8 *pCell = b.apCell[i];
      while( i==cntOldNext ){
        iOld++;
        assert( iOld<nNew || iOld<nOld );
        assert( iOld>=0 && iOld<NB );
        pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
        cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
      }
      if( i==cntNew[iNew] ){
        pNew = apNew[++iNew];
        if( !leafData ) continue;
      }
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442

8443
8444
8445
8446
8447
8448
8449


8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468


8469
8470
8471
8472
8473
8474
8475
8266
8267
8268
8269
8270
8271
8272
























8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292

8293
8294
8295
8296




8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326







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




















-
+



-
-
-
-
+
+



















+
+







  zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF);
  put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild);

  *ppChild = pChild;
  return SQLITE_OK;
}

/*
** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid
** on the same B-tree as pCur.
**
** This can if a database is corrupt with two or more SQL tables
** pointing to the same b-tree.  If an insert occurs on one SQL table
** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL
** table linked to the same b-tree.  If the secondary insert causes a
** rebalance, that can change content out from under the cursor on the
** first SQL table, violating invariants on the first insert.
*/
static int anotherValidCursor(BtCursor *pCur){
  BtCursor *pOther;
  for(pOther=pCur->pBt->pCursor; pOther; pOther=pOther->pNext){
    if( pOther!=pCur
     && pOther->eState==CURSOR_VALID
     && pOther->pPage==pCur->pPage
    ){
      return SQLITE_CORRUPT_BKPT;
    }
  }
  return SQLITE_OK;
}

/*
** The page that pCur currently points to has just been modified in
** some way. This function figures out if this modification means the
** tree needs to be balanced, and if so calls the appropriate balancing 
** routine. Balancing routines are:
**
**   balance_quick()
**   balance_deeper()
**   balance_nonroot()
*/
static int balance(BtCursor *pCur){
  int rc = SQLITE_OK;
  const int nMin = pCur->pBt->usableSize * 2 / 3;
  u8 aBalanceQuickSpace[13];
  u8 *pFree = 0;

  VVA_ONLY( int balance_quick_called = 0 );
  VVA_ONLY( int balance_deeper_called = 0 );

  do {
    int iPage;
    int iPage = pCur->iPage;
    MemPage *pPage = pCur->pPage;

    if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
    if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
      break;
    }else if( (iPage = pCur->iPage)==0 ){
      if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){
    if( iPage==0 ){
      if( pPage->nOverflow ){
        /* The root page of the b-tree is overfull. In this case call the
        ** balance_deeper() function to create a new child for the root-page
        ** and copy the current contents of the root-page to it. The
        ** next iteration of the do-loop will balance the child page.
        */ 
        assert( balance_deeper_called==0 );
        VVA_ONLY( balance_deeper_called++ );
        rc = balance_deeper(pPage, &pCur->apPage[1]);
        if( rc==SQLITE_OK ){
          pCur->iPage = 1;
          pCur->ix = 0;
          pCur->aiIdx[0] = 0;
          pCur->apPage[0] = pPage;
          pCur->pPage = pCur->apPage[1];
          assert( pCur->pPage->nOverflow );
        }
      }else{
        break;
      }
    }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
      break;
    }else{
      MemPage * const pParent = pCur->apPage[iPage-1];
      int const iIdx = pCur->aiIdx[iPage-1];

      rc = sqlite3PagerWrite(pParent->pDbPage);
      if( rc==SQLITE_OK && pParent->nFree<0 ){
        rc = btreeComputeFreeSpace(pParent);
8603
8604
8605
8606
8607
8608
8609
8610

8611
8612
8613
8614
8615
8616
8617
8618
8619
8454
8455
8456
8457
8458
8459
8460

8461


8462
8463
8464
8465
8466
8467
8468







-
+
-
-







  int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */
  int rc;                             /* Return code */
  MemPage *pPage = pCur->pPage;       /* Page being written */
  BtShared *pBt;                      /* Btree */
  Pgno ovflPgno;                      /* Next overflow page to write */
  u32 ovflPageSize;                   /* Size to write on overflow page */

  if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd
  if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){
   || pCur->info.pPayload < pPage->aData + pPage->cellOffset
  ){
    return SQLITE_CORRUPT_BKPT;
  }
  /* Overwrite the local portion first */
  rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX,
                             0, pCur->info.nLocal);
  if( rc ) return rc;
  if( pCur->info.nLocal==nTotal ) return SQLITE_OK;
8689
8690
8691
8692
8693
8694
8695
8696

8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715

8716
8717
8718
8719
8720
8721
8722
8538
8539
8540
8541
8542
8543
8544

8545

8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562

8563
8564
8565
8566
8567
8568
8569
8570







-
+
-

















-
+







  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_SAVEPOSITION|BTREE_APPEND))==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) );
  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 
8739
8740
8741
8742
8743
8744
8745

8746
8747
8748
8749
8750
8751
8752
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601







+







    /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing 
    ** to a row with the same key as the new entry being inserted.
    */
#ifdef SQLITE_DEBUG
    if( flags & BTREE_SAVEPOSITION ){
      assert( pCur->curFlags & BTCF_ValidNKey );
      assert( pX->nKey==pCur->info.nKey );
      assert( pCur->info.nSize!=0 );
      assert( loc==0 );
    }
#endif

    /* On the other hand, BTREE_SAVEPOSITION==0 does not imply
    ** that the cursor is not pointing to a row to be overwritten.
    ** So do a complete check.
8813
8814
8815
8816
8817
8818
8819
8820

8821
8822
8823
8824
8825

8826
8827
8828
8829
8830
8831

8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855

8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891

8892
8893
8894
8895
8896
8897
8898
8899
8900
8662
8663
8664
8665
8666
8667
8668

8669


8670
8671

8672
8673
8674




8675

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
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714




8715


8716
8717
8718
8719
8720
8721
8722







-
+
-
-


-
+


-
-
-
-
+
-









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
















-
-













-
-
-
-
+
-
-







        x2.nData = pX->nKey;
        x2.nZero = 0;
        return btreeOverwriteCell(pCur, &x2);
      }
    }

  }
  assert( pCur->eState==CURSOR_VALID 
  assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
       || (pCur->eState==CURSOR_INVALID && loc)
       || CORRUPT_DB );

  pPage = pCur->pPage;
  assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
  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);
    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);
  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 );
    rc = sqlite3PagerWrite(pPage->pDbPage);
    if( rc ){
      goto end_insert;
    }
    oldCell = findCell(pPage, idx);
    if( !pPage->leaf ){
      memcpy(newCell, oldCell, 4);
    }
    rc = clearCell(pPage, oldCell, &info);
    testcase( pCur->curFlags & BTCF_ValidOvfl );
    invalidateOverflowCache(pCur);
    if( info.nSize==szNew && info.nLocal==info.nPayload 
     && (!ISAUTOVACUUM || szNew<pPage->minLocal)
    ){
      /* Overwrite the old cell with the new if they are the same size.
      ** We could also try to do this if the old cell is smaller, then add
      ** the leftover space to the free list.  But experiments show that
      ** doing that is no faster then skipping this optimization and just
      ** calling dropCell() and insertCell(). 
      **
      ** This optimization cannot be used on an autovacuum database if the
      ** new entry uses overflow pages, as the insertCell() call below is
      ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry.  */
      assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
      if( oldCell < pPage->aData+pPage->hdrOffset+10 ){
        return SQLITE_CORRUPT_BKPT;
      }
      if( oldCell+szNew > pPage->aDataEnd ){
      if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
        return SQLITE_CORRUPT_BKPT;
      }
      memcpy(oldCell, newCell, szNew);
      return SQLITE_OK;
    }
    dropCell(pPage, idx, info.nSize, &rc);
    if( rc ) goto end_insert;
  }else if( loc<0 && pPage->nCell>0 ){
    assert( pPage->leaf );
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
8775
8776
8777
8778
8779
8780
8781












































































































8782
8783
8784
8785
8786
8787
8788







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







      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
9265
9266
9267
9268
9269
9270
9271
9272

9273
9274
9275
9276
9277
9278
9279
8979
8980
8981
8982
8983
8984
8985

8986
8987
8988
8989
8990
8991
8992
8993







-
+







** The type of type is determined by the flags parameter.  Only the
** following values of flags are currently in use.  Other values for
** flags might not work:
**
**     BTREE_INTKEY|BTREE_LEAFDATA     Used for SQL tables with rowid keys
**     BTREE_ZERODATA                  Used for SQL indices
*/
static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){
static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
  BtShared *pBt = p->pBt;
  MemPage *pRoot;
  Pgno pgnoRoot;
  int rc;
  int ptfFlags;          /* Page-type flage for the root page of new table */

  assert( sqlite3BtreeHoldsMutex(p) );
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317


9318
9319
9320
9321
9322
9323
9324
9012
9013
9014
9015
9016
9017
9018



9019
9020
9021
9022
9023
9024
9025
9026
9027

9028
9029
9030
9031
9032
9033
9034
9035
9036







-
-
-









-
+
+







    invalidateAllOverflowCache(pBt);

    /* Read the value of meta[3] from the database to determine where the
    ** root page of the new table should go. meta[3] is the largest root-page
    ** created so far, so the new root-page is (meta[3]+1).
    */
    sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
    if( pgnoRoot>btreePagecount(pBt) ){
      return SQLITE_CORRUPT_BKPT;
    }
    pgnoRoot++;

    /* The new root-page may not be allocated on a pointer-map page, or the
    ** PENDING_BYTE page.
    */
    while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
        pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
      pgnoRoot++;
    }
    assert( pgnoRoot>=3 );
    assert( pgnoRoot>=3 || CORRUPT_DB );
    testcase( pgnoRoot<3 );

    /* Allocate a page. The page that currently resides at pgnoRoot will
    ** be moved to the allocated page (unless the allocated page happens
    ** to reside at pgnoRoot).
    */
    rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT);
    if( rc!=SQLITE_OK ){
9407
9408
9409
9410
9411
9412
9413
9414

9415
9416
9417

9418
9419
9420
9421
9422
9423
9424
9119
9120
9121
9122
9123
9124
9125

9126
9127
9128

9129
9130
9131
9132
9133
9134
9135
9136







-
+


-
+







    ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF;
  }else{
    ptfFlags = PTF_ZERODATA | PTF_LEAF;
  }
  zeroPage(pRoot, ptfFlags);
  sqlite3PagerUnref(pRoot->pDbPage);
  assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 );
  *piTable = pgnoRoot;
  *piTable = (int)pgnoRoot;
  return SQLITE_OK;
}
int sqlite3BtreeCreateTable(Btree *p, Pgno *piTable, int flags){
int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
  int rc;
  sqlite3BtreeEnter(p);
  rc = btreeCreateTable(p, piTable, flags);
  sqlite3BtreeLeave(p);
  return rc;
}

9656
9657
9658
9659
9660
9661
9662
9663

9664
9665
9666
9667
9668

9669
9670
9671
9672
9673
9674
9675
9368
9369
9370
9371
9372
9373
9374

9375
9376
9377
9378
9379

9380
9381
9382
9383
9384
9385
9386
9387







-
+




-
+







** read it from this routine.
*/
void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
  BtShared *pBt = p->pBt;

  sqlite3BtreeEnter(p);
  assert( p->inTrans>TRANS_NONE );
  assert( SQLITE_OK==querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK) );
  assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) );
  assert( pBt->pPage1 );
  assert( idx>=0 && idx<=15 );

  if( idx==BTREE_DATA_VERSION ){
    *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iBDataVersion;
    *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion;
  }else{
    *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
  }

  /* If auto-vacuum is disabled in this build and this is an auto-vacuum
  ** database, mark the database as read-only.  */
#ifdef SQLITE_OMIT_AUTOVACUUM
9705
9706
9707
9708
9709
9710
9711

9712
9713
9714
9715
9716
9717
9718
9719
9720

9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733

9734
9735
9736
9737
9738
9739
9740
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432

9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445

9446
9447
9448
9449
9450
9451
9452
9453







+








-
+












-
+







    }
#endif
  }
  sqlite3BtreeLeave(p);
  return rc;
}

#ifndef SQLITE_OMIT_BTREECOUNT
/*
** The first argument, pCur, is a cursor opened on some b-tree. Count the
** number of entries in the b-tree and write the result to *pnEntry.
**
** SQLITE_OK is returned if the operation is successfully executed. 
** Otherwise, if an error is encountered (i.e. an IO error or database
** corruption) an SQLite error code is returned.
*/
int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
  i64 nEntry = 0;                      /* Value to return in *pnEntry */
  int rc;                              /* Return code */

  rc = moveToRoot(pCur);
  if( rc==SQLITE_EMPTY ){
    *pnEntry = 0;
    return SQLITE_OK;
  }

  /* Unless an error occurs, the following loop runs one iteration for each
  ** page in the B-Tree structure (not including overflow pages). 
  */
  while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){
  while( rc==SQLITE_OK ){
    int iIdx;                          /* Index of child node in parent */
    MemPage *pPage;                    /* Current page of the b-tree */

    /* If this is a leaf page or the tree is not an int-key tree, then 
    ** this page contains countable entries. Increment the entry counter
    ** accordingly.
    */
9777
9778
9779
9780
9781
9782
9783

9784
9785
9786
9787
9788
9789
9790
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504







+







      rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx)));
    }
  }

  /* An error has occurred. Return an error code. */
  return rc;
}
#endif

/*
** Return the pager associated with a BTree.  This routine is used for
** testing and debugging only.
*/
Pager *sqlite3BtreePager(Btree *p){
  return p->pBt->pPager;
9809
9810
9811
9812
9813
9814
9815
9816

9817
9818
9819
9820
9821
9822
9823
9523
9524
9525
9526
9527
9528
9529

9530
9531
9532
9533
9534
9535
9536
9537







-
+







  }
  if( pCheck->zPfx ){
    sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
  }
  sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap);
  va_end(ap);
  if( pCheck->errMsg.accError==SQLITE_NOMEM ){
    pCheck->bOomFault = 1;
    pCheck->mallocFailed = 1;
  }
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK

/*
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9565
9566
9567
9568
9569
9570
9571

9572
9573
9574
9575
9576
9577
9578







-







    checkAppendMsg(pCheck, "invalid page number %d", iPage);
    return 1;
  }
  if( getPageReferenced(pCheck, iPage) ){
    checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
    return 1;
  }
  if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1;
  setPageReferenced(pCheck, iPage);
  return 0;
}

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Check that the entry in the pointer-map for page iChild maps to 
9874
9875
9876
9877
9878
9879
9880
9881

9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901

9902
9903
9904
9905
9906
9907
9908
9587
9588
9589
9590
9591
9592
9593

9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613

9614
9615
9616
9617
9618
9619
9620
9621







-
+



















-
+







){
  int rc;
  u8 ePtrmapType;
  Pgno iPtrmapParent;

  rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->bOomFault = 1;
    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
    checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild);
    return;
  }

  if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
    checkAppendMsg(pCheck,
      "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", 
      iChild, eType, iParent, ePtrmapType, iPtrmapParent);
  }
}
#endif

/*
** Check the integrity of the freelist or of an overflow page list.
** Verify that the number of pages on the list is N.
*/
static void checkList(
  IntegrityCk *pCheck,  /* Integrity checking context */
  int isFreeList,       /* True for a freelist.  False for overflow page list */
  Pgno iPage,           /* Page number for first page in the list */
  int iPage,            /* Page number for first page in the list */
  u32 N                 /* Expected number of pages in the list */
){
  int i;
  u32 expected = N;
  int nErrAtStart = pCheck->nErr;
  while( iPage!=0 && pCheck->mxErr ){
    DbPage *pOvflPage;
10026
10027
10028
10029
10030
10031
10032
10033

10034
10035
10036
10037
10038
10039
10040
9739
9740
9741
9742
9743
9744
9745

9746
9747
9748
9749
9750
9751
9752
9753







-
+







**      2.  Make sure integer cell keys are in order.
**      3.  Check the integrity of overflow pages.
**      4.  Recursively call checkTreePage on all children.
**      5.  Verify that the depth of all children is the same.
*/
static int checkTreePage(
  IntegrityCk *pCheck,  /* Context for the sanity check */
  Pgno iPage,           /* Page number of the page to check */
  int iPage,            /* Page number of the page to check */
  i64 *piMinKey,        /* Write minimum integer primary key here */
  i64 maxKey            /* Error if integer primary key greater than this */
){
  MemPage *pPage = 0;      /* The page being analyzed */
  int i;                   /* Loop counter */
  int rc;                  /* Result code from subroutine call */
  int depth = -1, d2;      /* Depth of a subtree */
10062
10063
10064
10065
10066
10067
10068
10069

10070
10071

10072
10073
10074
10075
10076
10077
10078
9775
9776
9777
9778
9779
9780
9781

9782
9783

9784
9785
9786
9787
9788
9789
9790
9791







-
+

-
+








  /* Check that the page exists
  */
  pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage) ) return 0;
  pCheck->zPfx = "Page %u: ";
  pCheck->zPfx = "Page %d: ";
  pCheck->v1 = iPage;
  if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){
  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
    checkAppendMsg(pCheck,
       "unable to get the page. error code=%d", rc);
    goto end_of_check;
  }

  /* Clear MemPage.isInit to make sure the corruption detection code in
  ** btreeInitPage() is executed.  */
10089
10090
10091
10092
10093
10094
10095
10096

10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116

10117
10118
10119
10120
10121
10122
10123
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
9827
9828

9829
9830
9831
9832
9833
9834
9835
9836







-
+



















-
+







    checkAppendMsg(pCheck, "free space corruption", rc);
    goto end_of_check;
  }
  data = pPage->aData;
  hdr = pPage->hdrOffset;

  /* Set up for cell analysis */
  pCheck->zPfx = "On tree page %u cell %d: ";
  pCheck->zPfx = "On tree page %d cell %d: ";
  contentOffset = get2byteNotZero(&data[hdr+5]);
  assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */

  /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
  ** number of cells on the page. */
  nCell = get2byte(&data[hdr+3]);
  assert( pPage->nCell==nCell );

  /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
  ** immediately follows the b-tree page header. */
  cellStart = hdr + 12 - 4*pPage->leaf;
  assert( pPage->aCellIdx==&data[cellStart] );
  pCellIdx = &data[cellStart + 2*(nCell-1)];

  if( !pPage->leaf ){
    /* Analyze the right-child page of internal pages */
    pgno = get4byte(&data[hdr+8]);
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum ){
      pCheck->zPfx = "On page %u at right child: ";
      pCheck->zPfx = "On page %d at right child: ";
      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
    }
#endif
    depth = checkTreePage(pCheck, pgno, &maxKey, maxKey);
    keyCanBeEqual = 0;
  }else{
    /* For leaf pages, the coverage check will occur in the same loop
10250
10251
10252
10253
10254
10255
10256
10257

10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272

10273
10274
10275
10276
10277
10278
10279
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







-
+














-
+







    ** that gap is added to the fragmentation count.
    */
    nFrag = 0;
    prev = contentOffset - 1;   /* Implied first min-heap entry */
    while( btreeHeapPull(heap,&x) ){
      if( (prev&0xffff)>=(x>>16) ){
        checkAppendMsg(pCheck,
          "Multiple uses for byte %u of page %u", x>>16, iPage);
          "Multiple uses for byte %u of page %d", x>>16, iPage);
        break;
      }else{
        nFrag += (x>>16) - (prev&0xffff) - 1;
        prev = x;
      }
    }
    nFrag += usableSize - (prev&0xffff) - 1;
    /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
    ** is stored in the fifth field of the b-tree page header.
    ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
    ** number of fragmented free bytes within the cell content area.
    */
    if( heap[0]==0 && nFrag!=data[hdr+7] ){
      checkAppendMsg(pCheck,
          "Fragmentation of %d bytes reported as %d on page %u",
          "Fragmentation of %d bytes reported as %d on page %d",
          nFrag, data[hdr+7], iPage);
    }
  }

end_of_check:
  if( !doCoverageCheck ) pPage->isInit = savedIsInit;
  releasePage(pPage);
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313

10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345

10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359

10360
10361
10362
10363
10364

10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378





10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398















10399
10400
10401
10402
10403
10404
10405
10406
10407
10408

10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419

10420
10421
10422
10423



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
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
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087

10088
10089
10090
10091
10092
10093
10094
10095

10096
10097
10098
10099
10100
10101
10102
10103
10104
10105


10106
10107



10108
10109
10110
10111











10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123

10124
10125
10126
10127
10128
10129
10130

10131
10132
10133
10134
10135
10136
10137
10138







-
-
-
-
-
-
-
-
-


-

-
+









-
-

-
-
-
-
-
-
-
-





-





-
+













-
+




-
+








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



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








-
+









-
-
+

-
-
-
+
+
+

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

-







-
+







** A read-only or read-write transaction must be opened before calling
** this function.
**
** Write the number of error seen in *pnErr.  Except for some memory
** allocation errors,  an error message held in memory obtained from
** malloc is returned if *pnErr is non-zero.  If *pnErr==0 then NULL is
** returned.  If a memory allocation error occurs, NULL is returned.
**
** If the first entry in aRoot[] is 0, that indicates that the list of
** root pages is incomplete.  This is a "partial integrity-check".  This
** happens when performing an integrity check on a single table.  The
** zero is skipped, of course.  But in addition, the freelist checks
** and the checks to make sure every page is referenced are also skipped,
** since obviously it is not possible to know which pages are covered by
** the unverified btrees.  Except, if aRoot[1] is 1, then the freelist
** checks are still performed.
*/
char *sqlite3BtreeIntegrityCheck(
  sqlite3 *db,  /* Database connection that is running the check */
  Btree *p,     /* The btree to be checked */
  Pgno *aRoot,  /* An array of root pages numbers for individual trees */
  int *aRoot,   /* An array of root pages numbers for individual trees */
  int nRoot,    /* Number of entries in aRoot[] */
  int mxErr,    /* Stop reporting errors after this many */
  int *pnErr    /* Write number of errors seen to this variable */
){
  Pgno i;
  IntegrityCk sCheck;
  BtShared *pBt = p->pBt;
  u64 savedDbFlags = pBt->db->flags;
  char zErr[100];
  int bPartial = 0;            /* True if not checking all btrees */
  int bCkFreelist = 1;         /* True to scan the freelist */
  VVA_ONLY( int nRef );
  assert( nRoot>0 );

  /* aRoot[0]==0 means this is a partial check */
  if( aRoot[0]==0 ){
    assert( nRoot>1 );
    bPartial = 1;
    if( aRoot[1]!=1 ) bCkFreelist = 0;
  }

  sqlite3BtreeEnter(p);
  assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
  VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) );
  assert( nRef>=0 );
  sCheck.db = db;
  sCheck.pBt = pBt;
  sCheck.pPager = pBt->pPager;
  sCheck.nPage = btreePagecount(sCheck.pBt);
  sCheck.mxErr = mxErr;
  sCheck.nErr = 0;
  sCheck.bOomFault = 0;
  sCheck.mallocFailed = 0;
  sCheck.zPfx = 0;
  sCheck.v1 = 0;
  sCheck.v2 = 0;
  sCheck.aPgRef = 0;
  sCheck.heap = 0;
  sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
  sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
  if( sCheck.nPage==0 ){
    goto integrity_ck_cleanup;
  }

  sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
  if( !sCheck.aPgRef ){
    sCheck.bOomFault = 1;
    sCheck.mallocFailed = 1;
    goto integrity_ck_cleanup;
  }
  sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
  if( sCheck.heap==0 ){
    sCheck.bOomFault = 1;
    sCheck.mallocFailed = 1;
    goto integrity_ck_cleanup;
  }

  i = PENDING_BYTE_PAGE(pBt);
  if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);

  /* Check the integrity of the freelist
  */
  if( bCkFreelist ){
    sCheck.zPfx = "Main freelist: ";
    checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
              get4byte(&pBt->pPage1->aData[36]));
    sCheck.zPfx = 0;
  }
  sCheck.zPfx = "Main freelist: ";
  checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
            get4byte(&pBt->pPage1->aData[36]));
  sCheck.zPfx = 0;


  /* Check all the tables.
  */
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( !bPartial ){
    if( pBt->autoVacuum ){
      Pgno mx = 0;
      Pgno mxInHdr;
      for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i];
      mxInHdr = get4byte(&pBt->pPage1->aData[52]);
      if( mx!=mxInHdr ){
        checkAppendMsg(&sCheck,
          "max rootpage (%d) disagrees with header (%d)",
          mx, mxInHdr
        );
      }
    }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){
      checkAppendMsg(&sCheck,
        "incremental_vacuum enabled with a max rootpage of zero"
      );
  if( pBt->autoVacuum ){
    int mx = 0;
    int mxInHdr;
    for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i];
    mxInHdr = get4byte(&pBt->pPage1->aData[52]);
    if( mx!=mxInHdr ){
      checkAppendMsg(&sCheck,
        "max rootpage (%d) disagrees with header (%d)",
        mx, mxInHdr
      );
    }
  }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){
    checkAppendMsg(&sCheck,
      "incremental_vacuum enabled with a max rootpage of zero"
    );
    }
  }
#endif
  testcase( pBt->db->flags & SQLITE_CellSizeCk );
  pBt->db->flags &= ~(u64)SQLITE_CellSizeCk;
  for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
    i64 notUsed;
    if( aRoot[i]==0 ) continue;
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){
    if( pBt->autoVacuum && aRoot[i]>1 ){
      checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
    }
#endif
    checkTreePage(&sCheck, aRoot[i], &notUsed, LARGEST_INT64);
  }
  pBt->db->flags = savedDbFlags;

  /* Make sure every page in the file is referenced
  */
  if( !bPartial ){
    for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
  for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
#ifdef SQLITE_OMIT_AUTOVACUUM
      if( getPageReferenced(&sCheck, i)==0 ){
        checkAppendMsg(&sCheck, "Page %d is never used", i);
      }
    if( getPageReferenced(&sCheck, i)==0 ){
      checkAppendMsg(&sCheck, "Page %d is never used", i);
    }
#else
      /* If the database supports auto-vacuum, make sure no tables contain
      ** references to pointer-map pages.
      */
      if( getPageReferenced(&sCheck, i)==0 && 
         (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
        checkAppendMsg(&sCheck, "Page %d is never used", i);
      }
      if( getPageReferenced(&sCheck, i)!=0 && 
         (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
        checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
      }
    /* If the database supports auto-vacuum, make sure no tables contain
    ** references to pointer-map pages.
    */
    if( getPageReferenced(&sCheck, i)==0 && 
       (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
      checkAppendMsg(&sCheck, "Page %d is never used", i);
    }
    if( getPageReferenced(&sCheck, i)!=0 && 
       (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
      checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
    }
#endif
    }
  }

  /* Clean  up and report errors.
  */
integrity_ck_cleanup:
  sqlite3PageFree(sCheck.heap);
  sqlite3_free(sCheck.aPgRef);
  if( sCheck.bOomFault ){
  if( sCheck.mallocFailed ){
    sqlite3_str_reset(&sCheck.errMsg);
    sCheck.nErr++;
  }
  *pnErr = sCheck.nErr;
  if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg);
  /* Make sure this analysis did not leave any unref() pages. */
  assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
10477
10478
10479
10480
10481
10482
10483
10484

10485
10486
10487

10488
10489

10490
10491
10492
10493
10494
10495
10496
10163
10164
10165
10166
10167
10168
10169

10170

10171

10172
10173

10174
10175
10176
10177
10178
10179
10180
10181







-
+
-

-
+

-
+







*/
const char *sqlite3BtreeGetJournalname(Btree *p){
  assert( p->pBt->pPager!=0 );
  return sqlite3PagerJournalname(p->pBt->pPager);
}

/*
** Return one of SQLITE_TXN_NONE, SQLITE_TXN_READ, or SQLITE_TXN_WRITE
** Return non-zero if a transaction is active.
** to describe the current transaction state of Btree p.
*/
int sqlite3BtreeTxnState(Btree *p){
int sqlite3BtreeIsInTrans(Btree *p){
  assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
  return p ? p->inTrans : 0;
  return (p && (p->inTrans==TRANS_WRITE));
}

#ifndef SQLITE_OMIT_WAL
/*
** Run a checkpoint on the Btree passed as the first argument.
**
** Return SQLITE_LOCKED if this or any other connection has an open 
10511
10512
10513
10514
10515
10516
10517
10518

10519






10520
10521
10522
10523
10524
10525
10526
10196
10197
10198
10199
10200
10201
10202

10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217







-
+

+
+
+
+
+
+







    sqlite3BtreeLeave(p);
  }
  return rc;
}
#endif

/*
** Return true if there is currently a backup running on Btree p.
** Return non-zero if a read (or write) transaction is active.
*/
int sqlite3BtreeIsInReadTrans(Btree *p){
  assert( p );
  assert( sqlite3_mutex_held(p->db->mutex) );
  return p->inTrans!=TRANS_NONE;
}

int sqlite3BtreeIsInBackup(Btree *p){
  assert( p );
  assert( sqlite3_mutex_held(p->db->mutex) );
  return p->nBackup!=0;
}

/*
10553
10554
10555
10556
10557
10558
10559
10560

10561
10562
10563
10564
10565
10566

10567
10568
10569
10570
10571
10572
10573
10244
10245
10246
10247
10248
10249
10250

10251
10252
10253
10254
10255
10256

10257
10258
10259
10260
10261
10262
10263
10264







-
+





-
+







  sqlite3BtreeLeave(p);
  return pBt->pSchema;
}

/*
** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared 
** btree as the argument handle holds an exclusive lock on the 
** sqlite_schema table. Otherwise SQLITE_OK.
** sqlite_master table. Otherwise SQLITE_OK.
*/
int sqlite3BtreeSchemaLocked(Btree *p){
  int rc;
  assert( sqlite3_mutex_held(p->db->mutex) );
  sqlite3BtreeEnter(p);
  rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK);
  rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
  assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE );
  sqlite3BtreeLeave(p);
  return rc;
}


#ifndef SQLITE_OMIT_SHARED_CACHE

Changes to src/btree.h.

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







-
-
+
+

-
+




-
+




-
-
-
-
+
+
+
+





-
-
-


-
-
-
-
-







int sqlite3BtreeSetSpillSize(Btree*,int);
#if SQLITE_MAX_MMAP_SIZE>0
  int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
#endif
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
int sqlite3BtreeGetPageSize(Btree*);
Pgno sqlite3BtreeMaxPageCount(Btree*,Pgno);
Pgno sqlite3BtreeLastPage(Btree*);
int sqlite3BtreeMaxPageCount(Btree*,int);
u32 sqlite3BtreeLastPage(Btree*);
int sqlite3BtreeSecureDelete(Btree*,int);
int sqlite3BtreeGetRequestedReserve(Btree*);
int sqlite3BtreeGetOptimalReserve(Btree*);
int sqlite3BtreeGetReserveNoMutex(Btree *p);
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeBeginTrans(Btree*,int,int*);
int sqlite3BtreeCommitPhaseOne(Btree*, const char*);
int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
int sqlite3BtreeCommitPhaseTwo(Btree*, int);
int sqlite3BtreeCommit(Btree*);
int sqlite3BtreeRollback(Btree*,int,int);
int sqlite3BtreeBeginStmt(Btree*,int);
int sqlite3BtreeCreateTable(Btree*, Pgno*, int flags);
int sqlite3BtreeTxnState(Btree*);
int sqlite3BtreeIsInBackup(Btree*);

int sqlite3BtreeCreateTable(Btree*, int*, int flags);
int sqlite3BtreeIsInTrans(Btree*);
int sqlite3BtreeIsInReadTrans(Btree*);
int sqlite3BtreeIsInBackup(Btree*);
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
int sqlite3BtreeSchemaLocked(Btree *pBtree);
#ifndef SQLITE_OMIT_SHARED_CACHE
int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
#endif

/* Savepoints are named, nestable SQL transactions mostly implemented */ 
/* in vdbe.c and pager.c See https://sqlite.org/lang_savepoint.html */
int sqlite3BtreeSavepoint(Btree *, int, int);

/* "Checkpoint" only refers to WAL. See https://sqlite.org/wal.html#ckpt */
#ifndef SQLITE_OMIT_WAL
  int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);  
#endif

const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetJournalname(Btree *);
int sqlite3BtreeCopyFile(Btree *, Btree *);

int sqlite3BtreeIncrVacuum(Btree *);

/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235







-
+







** FORDELETE cursor may return a null row: 0x01 0x00.
*/
#define BTREE_WRCSR     0x00000004     /* read-write cursor */
#define BTREE_FORDELETE 0x00000008     /* Cursor is for seek/delete only */

int sqlite3BtreeCursor(
  Btree*,                              /* BTree containing table to open */
  Pgno iTable,                         /* Index of root page */
  int iTable,                          /* Index of root page */
  int wrFlag,                          /* 1 for writing.  0 for read-only */
  struct KeyInfo*,                     /* First argument to compare function */
  BtCursor *pCursor                    /* Space to write cursor structure */
);
BtCursor *sqlite3BtreeFakeValidCursor(void);
int sqlite3BtreeCursorSize(void);
void sqlite3BtreeCursorZero(BtCursor*);
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
250
251
252
253
254
255
256

257
258
259
260
261
262
263







-







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







-
-








-
+














-
-
-
-
-
-





+
-
+
+










-
-







                       int flags, int seekResult);
int sqlite3BtreeFirst(BtCursor*, int *pRes);
int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int flags);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int flags);
i64 sqlite3BtreeIntegerKey(BtCursor*);
void sqlite3BtreeCursorPin(BtCursor*);
void sqlite3BtreeCursorUnpin(BtCursor*);
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
i64 sqlite3BtreeOffset(BtCursor*);
#endif
int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
u32 sqlite3BtreePayloadSize(BtCursor*);
sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);

char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*);
char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
struct Pager *sqlite3BtreePager(Btree*);
i64 sqlite3BtreeRowCountEst(BtCursor*);

#ifndef SQLITE_OMIT_INCRBLOB
int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeIncrblobCursor(BtCursor *);
#endif
void sqlite3BtreeClearCursor(BtCursor *);
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
int sqlite3BtreeIsReadonly(Btree *pBt);
int sqlite3HeaderSizeBtree(void);

#ifdef SQLITE_DEBUG
sqlite3_uint64 sqlite3BtreeSeekCount(Btree*);
#else
# define sqlite3BtreeSeekCount(X) 0
#endif

#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
int sqlite3BtreeCursorIsValidNN(BtCursor*);

#ifndef SQLITE_OMIT_BTREECOUNT
int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
int sqlite3BtreeCount(BtCursor *, i64 *);
#endif

#ifdef SQLITE_TEST
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
  void sqlite3BtreeEnter(Btree*);

Changes to src/btreeInt.h.

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







-
+


-
-
-











-
-
-




-
-
-
-
-
-
-
-
-
-
-













-
+







  BtShared *pBt;     /* Sharable content of this btree */
  u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
  u8 sharable;       /* True if we can share pBt with another db */
  u8 locked;         /* True if db currently has pBt locked */
  u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */
  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
  int nBackup;       /* Number of backup operations reading this btree */
  u32 iBDataVersion; /* Combines with pBt->pPager->iDataVersion */
  u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
  Btree *pNext;      /* List of other sharable Btrees from the same db */
  Btree *pPrev;      /* Back pointer of the same list */
#ifdef SQLITE_DEBUG
  u64 nSeek;         /* Calls to sqlite3BtreeMovetoUnpacked() */
#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
  BtLock lock;       /* Object used to lock page 1 */
#endif
};

/*
** Btree.inTrans may take one of the following values.
**
** If the shared-data extension is enabled, there may be multiple users
** of the Btree structure. At most one of these may open a write transaction,
** but any number may have active read transactions.
**
** These values must match SQLITE_TXN_NONE, SQLITE_TXN_READ, and
** SQLITE_TXN_WRITE
*/
#define TRANS_NONE  0
#define TRANS_READ  1
#define TRANS_WRITE 2

#if TRANS_NONE!=SQLITE_TXN_NONE
# error wrong numeric code for no-transaction
#endif
#if TRANS_READ!=SQLITE_TXN_READ
# error wrong numeric code for read-transaction
#endif
#if TRANS_WRITE!=SQLITE_TXN_WRITE
# error wrong numeric code for write-transaction
#endif


/*
** An instance of this object represents a single database file.
** 
** A single database file can be in use at the same time by two
** or more database connections.  When two or more connections are
** sharing the same database file, each connection has it own
** private Btree object for the file and each of those Btrees points
** to this one BtShared object.  BtShared.nRef is the number of
** connections currently sharing this database file.
**
** Fields in this structure are accessed under the BtShared.mutex
** mutex, except for nRef and pNext which are accessed under the
** global SQLITE_MUTEX_STATIC_MAIN mutex.  The pPager field
** global SQLITE_MUTEX_STATIC_MASTER mutex.  The pPager field
** may not be modified once it is initially set as long as nRef>0.
** The pSchema field may be set once under BtShared.mutex and
** thereafter is unchanged as long as nRef>0.
**
** isPending:
**
**   If a BtShared client fails to obtain a write-lock on a database
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
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







+
-
+
+




















-







#ifndef SQLITE_OMIT_AUTOVACUUM
  u8 autoVacuum;        /* True if auto-vacuum is enabled */
  u8 incrVacuum;        /* True if incr-vacuum is enabled */
  u8 bDoTruncate;       /* True to truncate db on commit */
#endif
  u8 inTransaction;     /* Transaction state */
  u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
#ifdef SQLITE_HAS_CODEC
  u8 nReserveWanted;    /* Desired number of extra bytes per page */
  u8 optimalReserve;    /* Desired amount of reserved space per page */
#endif
  u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
  u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
  u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
  u16 maxLeaf;          /* Maximum local payload in a LEAFDATA table */
  u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
  u32 pageSize;         /* Total number of bytes on a page */
  u32 usableSize;       /* Number of usable bytes on each page */
  int nTransaction;     /* Number of open transactions (read + write) */
  u32 nPage;            /* Number of pages in the database */
  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
  sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */
  Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nRef;             /* Number of references to this structure */
  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
  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 */
  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 */
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
538
539
540
541
542
543
544

545
546
547
548
549
550
551







-







*/
#define BTCF_WriteFlag    0x01   /* True if a write cursor */
#define BTCF_ValidNKey    0x02   /* True if info.nKey is valid */
#define BTCF_ValidOvfl    0x04   /* True if aOverflow is valid */
#define BTCF_AtLast       0x08   /* Cursor is pointing ot the last entry */
#define BTCF_Incrblob     0x10   /* True if an incremental I/O handle */
#define BTCF_Multiple     0x20   /* Maybe another cursor on the same btree */
#define BTCF_Pinned       0x40   /* Cursor is busy and cannot be moved */

/*
** Potential values for BtCursor.eState.
**
** CURSOR_INVALID:
**   Cursor does not point to a valid entry. This can happen (for example) 
**   because the table is empty or because BtreeCursorFirst() has not been
693
694
695
696
697
698
699
700

701
702
703

704
705
706
707
708
709
710
711
712
713
676
677
678
679
680
681
682

683
684


685
686
687

688
689
690
691
692
693
694







-
+

-
-
+


-







struct IntegrityCk {
  BtShared *pBt;    /* The tree being checked out */
  Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
  u8 *aPgRef;       /* 1 bit per page in the db (see above) */
  Pgno nPage;       /* Number of pages in the database */
  int mxErr;        /* Stop accumulating errors when this reaches zero */
  int nErr;         /* Number of messages written to zErrMsg so far */
  int bOomFault;    /* A memory allocation error has occurred */
  int mallocFailed; /* A memory allocation error has occurred */
  const char *zPfx; /* Error message prefix */
  Pgno v1;          /* Value for first %u substitution in zPfx */
  int v2;           /* Value for second %d substitution in zPfx */
  int v1, v2;       /* Values for up to two %d fields in zPfx */
  StrAccum errMsg;  /* Accumulate the error message text here */
  u32 *heap;        /* Min-heap used for analyzing cell coverage */
  sqlite3 *db;      /* Database connection running the check */
};

/*
** Routines to read or write a two- and four-byte big-endian integer values.
*/
#define get2byte(x)   ((x)[0]<<8 | (x)[1])
#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))

Changes to src/build.c.

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







-
+

















-
+



-
+







-







#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** The TableLock structure is only used by the sqlite3TableLock() and
** codeTableLocks() functions.
*/
struct TableLock {
  int iDb;               /* The database containing the table to be locked */
  Pgno iTab;             /* The root page of the table to be locked */
  int iTab;              /* The root page of the table to be locked */
  u8 isWriteLock;        /* True for write lock.  False for a read lock */
  const char *zLockName; /* Name of the table */
};

/*
** Record the fact that we want to lock a table at run-time.  
**
** The table to be locked has root page iTab and is found in database iDb.
** A read or a write lock can be taken depending on isWritelock.
**
** This routine just records the fact that the lock is desired.  The
** code to make the lock occur is generated by a later call to
** codeTableLocks() which occurs during sqlite3FinishCoding().
*/
void sqlite3TableLock(
  Parse *pParse,     /* Parsing context */
  int iDb,           /* Index of the database containing the table to lock */
  Pgno iTab,         /* Root page number of the table to be locked */
  int iTab,          /* Root page number of the table to be locked */
  u8 isWriteLock,    /* True for a write lock */
  const char *zName  /* Name of the table to be locked */
){
  Parse *pToplevel;
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  int i;
  int nBytes;
  TableLock *p;
  assert( iDb>=0 );

  if( iDb==1 ) return;
  if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
  pToplevel = sqlite3ParseToplevel(pParse);
  for(i=0; i<pToplevel->nTableLock; i++){
    p = &pToplevel->aTableLock[i];
    if( p->iDb==iDb && p->iTab==iTab ){
      p->isWriteLock = (p->isWriteLock || isWriteLock);
      return;
    }
  }
87
88
89
90
91
92
93
94
95




96
97
98
99
100
101
102
86
87
88
89
90
91
92


93
94
95
96
97
98
99
100
101
102
103







-
-
+
+
+
+








/*
** Code an OP_TableLock instruction for each table locked by the
** statement (configured by calls to sqlite3TableLock()).
*/
static void codeTableLocks(Parse *pParse){
  int i;
  Vdbe *pVdbe = pParse->pVdbe; 
  assert( pVdbe!=0 );
  Vdbe *pVdbe; 

  pVdbe = sqlite3GetVdbe(pParse);
  assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */

  for(i=0; i<pParse->nTableLock; i++){
    TableLock *p = &pParse->aTableLock[i];
    int p1 = p->iDb;
    sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
                      p->zLockName, P4_STATIC);
  }
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
140
141
142
143
144
145
146







147


148
149
150


















151
152
153
154
155
156
157







-
-
-
-
-
-
-
+
-
-



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







    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);
  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");
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
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







-
+
-
-
-
-
-
-




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






+







      */
      codeTableLocks(pParse);

      /* Initialize any AUTOINCREMENT data structures required.
      */
      sqlite3AutoincrementBegin(pParse);

      /* Code constant expressions that where factored out of inner loops.
      /* Code constant expressions that where factored out of inner loops */
      **
      ** The pConstExpr list might also contain expressions that we simply
      ** want to keep around until the Parse object is deleted.  Such
      ** expressions have iConstExprReg==0.  Do not generate code for
      ** those expressions, of course.
      */
      if( pParse->pConstExpr ){
        ExprList *pEL = pParse->pConstExpr;
        pParse->okConstFactor = 0;
        for(i=0; i<pEL->nExpr; i++){
          int iReg = pEL->a[i].u.iConstExprReg;
          if( iReg>0 ){
            sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg);
          }
          sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
        }
        }
      }

      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 );
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254







-
+







** code for the SQL statement given onto the end of the pParse context
** currently under construction.  When the parser is run recursively
** this way, the final OP_Halt is not appended and other initialization
** and finalization steps are omitted because those are handling by the
** outermost parser.
**
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against the schema table.  Use
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  char *zErrMsg = 0;
  sqlite3 *db = pParse->db;
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
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







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







#if SQLITE_USER_AUTHENTICATION
  /* Only the admin user is allowed to know that the sqlite_user table
  ** exists */
  if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){
    return 0;
  }
#endif
  if( zDatabase ){
    for(i=0; i<db->nDb; i++){
      if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break;
  while(1){
    for(i=OMIT_TEMPDB; i<db->nDb; i++){
      int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
      if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
    }
    if( i>=db->nDb ){
      /* No match against the official names.  But always match "main"
      ** to schema 0 as a legacy fallback. */
      if( sqlite3StrICmp(zDatabase,"main")==0 ){
        i = 0;
      }else{
        return 0;
      }
    }
    p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
    if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
      if( i==1 ){
        if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0
         || sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0
         || sqlite3StrICmp(zName+7, &DFLT_SCHEMA_TABLE[7])==0
        ){
          p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, 
                              DFLT_TEMP_SCHEMA_TABLE);
        }
      }else{
        if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
          p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
                              DFLT_SCHEMA_TABLE);
        }
      }
    }
  }else{
    /* Match against TEMP first */
    p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, zName);
    if( p ) return p;
    /* The main database is second */
    p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, zName);
    if( p ) return p;
    /* Attached databases are in order of attachment */
    for(i=2; i<db->nDb; i++){
      assert( sqlite3SchemaMutexHeld(db, i, 0) );
      p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
      if( p ) break;
    }
    if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
      if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
        assert( sqlite3SchemaMutexHeld(db, j, 0) );
        p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
        if( p ) return p;
      }
    }
    /* Not found.  If the name we were looking for was temp.sqlite_master
    ** then change the name to sqlite_temp_master and try again. */
        p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, DFLT_SCHEMA_TABLE);
      }else if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0 ){
        p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, 
                            DFLT_TEMP_SCHEMA_TABLE);
      }
    if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break;
    if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
    zName = TEMP_MASTER_NAME;
  }
    }
  }
  return p;
  return 0;
}

/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
** database containing the table.  Return NULL if not found.  Also leave an
** error message in pParse->zErrMsg.
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413







-
+







** 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
  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{
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
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







-
+


















-
+







  int i;
  /* All mutexes are required for schema access.  Make sure we hold them. */
  assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
  for(i=OMIT_TEMPDB; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    Schema *pSchema = db->aDb[j].pSchema;
    assert( pSchema );
    if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
    assert( sqlite3SchemaMutexHeld(db, j, 0) );
    p = sqlite3HashFind(&pSchema->idxHash, zName);
    if( p ) break;
  }
  return p;
}

/*
** Reclaim the memory used by an index
*/
void sqlite3FreeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
  sqlite3DeleteIndexSamples(db, p);
#endif
  sqlite3ExprDelete(db, p->pPartIdxWhere);
  sqlite3ExprListDelete(db, p->aColExpr);
  sqlite3DbFree(db, p->zColAff);
  if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  sqlite3_free(p->aiRowEst);
#endif
  sqlite3DbFree(db, p);
}

/*
** For the index called zIdxName which is found in the database iDb,
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
586
587
588
589
590
591
592

593
594
595
596
597
598
599







-







*/
void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
  int i;
  Column *pCol;
  assert( pTable!=0 );
  if( (pCol = pTable->aCol)!=0 ){
    for(i=0; i<pTable->nCol; i++, pCol++){
      assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) );
      sqlite3DbFree(db, pCol->zName);
      sqlite3ExprDelete(db, pCol->pDflt);
      sqlite3DbFree(db, pCol->zColl);
    }
    sqlite3DbFree(db, pTable->aCol);
  }
}
690
691
692
693
694
695
696
697
698


699
700
701
702
703
704

705
706
707
708
709
710
711
614
615
616
617
618
619
620


621
622




623

624
625
626
627
628
629
630
631







-
-
+
+
-
-
-
-

-
+







** used by the Table object.
*/
static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
  Index *pIndex, *pNext;

#ifdef SQLITE_DEBUG
  /* Record the number of outstanding lookaside allocations in schema Tables
  ** prior to doing any free() operations. Since schema Tables do not use
  ** lookaside, this number should not change. 
  ** prior to doing any free() operations.  Since schema Tables do not use
  ** lookaside, this number should not change. */
  **
  ** If malloc has already failed, it may be that it failed while allocating
  ** a Table object that was going to be marked ephemeral. So do not check
  ** that no lookaside memory is used in this case either. */
  int nLookaside = 0;
  if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
  if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
    nLookaside = sqlite3LookasideUsed(db, 0);
  }
#endif

  /* Delete all indices associated with this table. */
  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
    pNext = pIndex->pNext;
788
789
790
791
792
793
794
795

796
797
798

799
800
801


802
803
804
805
806
807
808
708
709
710
711
712
713
714

715
716
717

718
719


720
721
722
723
724
725
726
727
728







-
+


-
+

-
-
+
+







  }else{
    zName = 0;
  }
  return zName;
}

/*
** Open the sqlite_schema table stored in database number iDb for
** Open the sqlite_master table stored in database number iDb for
** writing. The table is opened using cursor 0.
*/
void sqlite3OpenSchemaTable(Parse *p, int iDb){
void sqlite3OpenMasterTable(Parse *p, int iDb){
  Vdbe *v = sqlite3GetVdbe(p);
  sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, DFLT_SCHEMA_TABLE);
  sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
  sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME);
  sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
  if( p->nTab==0 ){
    p->nTab = 1;
  }
}

/*
** Parameter zName points to a nul-terminated buffer containing the name
901
902
903
904
905
906
907
908
909
910
911
912
913

914
915
916
917
918
919
920


921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936

937
938
939

940
941

942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961


962
963

964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
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







-
-
-
-

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














-
-
-
-
+
+

-
+







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








/*
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
** trigger). All names are legal except those that begin with the string
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
**
** When parsing the sqlite_schema table, this routine also checks to
** make sure the "type", "name", and "tbl_name" columns are consistent
** with the SQL.
*/
int sqlite3CheckObjectName(
int sqlite3CheckObjectName(Parse *pParse, const char *zName){
  Parse *pParse,            /* Parsing context */
  const char *zName,        /* Name of the object to check */
  const char *zType,        /* Type of this object */
  const char *zTblName      /* Parent table name for triggers and indexes */
){
  sqlite3 *db = pParse->db;
  if( sqlite3WritableSchema(db)
  if( !pParse->db->init.busy && pParse->nested==0 
          && sqlite3WritableSchema(pParse->db)==0
   || db->init.imposterTable
   || !sqlite3Config.bExtraSchemaChecks
  ){
    /* Skip these error checks for writable_schema=ON */
    return SQLITE_OK;
  }
  if( db->init.busy ){
    if( sqlite3_stricmp(zType, db->init.azInit[0])
     || sqlite3_stricmp(zName, db->init.azInit[1])
     || sqlite3_stricmp(zTblName, db->init.azInit[2])
    ){
      sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */
      return SQLITE_ERROR;
    }
  }else{
    if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7))
          && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
     || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName))
    ){
      sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s",
    sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
                      zName);
      return SQLITE_ERROR;
    return SQLITE_ERROR;
    }

  }
  return SQLITE_OK;
}

/*
** Return the PRIMARY KEY index of a table
*/
Index *sqlite3PrimaryKeyIndex(Table *pTab){
  Index *p;
  for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){}
  return p;
}

/*
** Convert an table column number into a index column number.  That is,
** for the column iCol in the table (as defined by the CREATE TABLE statement)
** find the (first) offset of that column in index pIdx.  Or return -1
** if column iCol is not used in index pIdx.
** Return the column of index pIdx that corresponds to table
** column iCol.  Return -1 if not found.
*/
i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){
i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
  int i;
  for(i=0; i<pIdx->nColumn; i++){
    if( iCol==pIdx->aiColumn[i] ) return i;
  }
  return -1;
}

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* Convert a storage column number into a table column number.
**
** The storage column number (0,1,2,....) is the index of the value
** as it appears in the record on disk.  The true column number
** is the index (0,1,2,...) of the column in the CREATE TABLE statement.
**
** The storage column number is less than the table column number if
** and only there are VIRTUAL columns to the left.
**
** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro.
*/
i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){
  if( pTab->tabFlags & TF_HasVirtual ){
    int i;
    for(i=0; i<=iCol; i++){
      if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++;
    }
  }
  return iCol;
}
#endif

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* Convert a table column number into a storage column number.
**
** The storage column number (0,1,2,....) is the index of the value
** as it appears in the record on disk.  Or, if the input column is
** the N-th virtual column (zero-based) then the storage number is
** the number of non-virtual columns in the table plus N.  
**
** The true column number is the index (0,1,2,...) of the column in
** the CREATE TABLE statement.
**
** If the input column is a VIRTUAL column, then it should not appear
** in storage.  But the value sometimes is cached in registers that
** follow the range of registers used to construct storage.  This
** avoids computing the same VIRTUAL column multiple times, and provides
** values for use by OP_Param opcodes in triggers.  Hence, if the
** input column is a VIRTUAL table, put it after all the other columns.
**
** In the following, N means "normal column", S means STORED, and
** V means VIRTUAL.  Suppose the CREATE TABLE has columns like this:
**
**        CREATE TABLE ex(N,S,V,N,S,V,N,S,V);
**                     -- 0 1 2 3 4 5 6 7 8
**
** Then the mapping from this function is as follows:
**
**    INPUTS:     0 1 2 3 4 5 6 7 8
**    OUTPUTS:    0 1 6 2 3 7 4 5 8
**
** So, in other words, this routine shifts all the virtual columns to
** the end.
**
** If SQLITE_OMIT_GENERATED_COLUMNS then there are no virtual columns and
** this routine is a no-op macro.  If the pTab does not have any virtual
** columns, then this routine is no-op that always return iCol.  If iCol
** is negative (indicating the ROWID column) then this routine return iCol.
*/
i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){
  int i;
  i16 n;
  assert( iCol<pTab->nCol );
  if( (pTab->tabFlags & TF_HasVirtual)==0 || iCol<0 ) return iCol;
  for(i=0, n=0; i<iCol; i++){
    if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++;
  }
  if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ){
    /* iCol is a virtual column itself */
    return pTab->nNVCol + i - n;
  }else{
    /* iCol is a normal or stored column */
    return n;
  }
}
#endif

/*
** Begin constructing a new table representation in memory.  This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement.  In particular, this routine is called
** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp
** flag is true if the table should be stored in the auxiliary database
** file instead of in the main database file.  This is normally the case
1075
1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
886
887
888
889
890
891
892

893
894
895
896
897
898
899
900







-
+







  char *zName = 0; /* The name of the new table */
  sqlite3 *db = pParse->db;
  Vdbe *v;
  int iDb;         /* Database number to create the table in */
  Token *pName;    /* Unqualified name of the table to create */

  if( db->init.busy && db->init.newTnum==1 ){
    /* Special case:  Parsing the sqlite_schema or sqlite_temp_schema schema */
    /* Special case:  Parsing the sqlite_master or sqlite_temp_master schema */
    iDb = db->init.iDb;
    zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb));
    pName = pName1;
  }else{
    /* The common case */
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ) return;
1097
1098
1099
1100
1101
1102
1103
1104

1105
1106
1107
1108
1109
1110
1111
908
909
910
911
912
913
914

915
916
917
918
919
920
921
922







-
+







    zName = sqlite3NameFromToken(db, pName);
    if( IN_RENAME_OBJECT ){
      sqlite3RenameTokenMap(pParse, (void*)zName, pName);
    }
  }
  pParse->sNameToken = *pName;
  if( zName==0 ) return;
  if( sqlite3CheckObjectName(pParse, zName, isView?"view":"table", zName) ){
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto begin_table_error;
  }
  if( db->init.iDb==1 ) isTemp = 1;
#ifndef SQLITE_OMIT_AUTHORIZATION
  assert( isTemp==0 || isTemp==1 );
  assert( isView==0 || isView==1 );
  {
1181
1182
1183
1184
1185
1186
1187
1188

1189
1190
1191
1192
1193
1194
1195
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
1006







-
+







  if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    pTable->pSchema->pSeqTab = pTable;
  }
#endif

  /* Begin generating the code that will insert the table record into
  ** the schema table.  Note in particular that we must go ahead
  ** the SQLITE_MASTER table.  Note in particular that we must go ahead
  ** and allocate the record number for the table entry now.  Before any
  ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
  ** indices to be created and the table record must come before the 
  ** indices.  Hence, the record number for the table must be allocated
  ** now.
  */
  if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
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
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







-
+














-
-
+


-
+







    addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
    fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
                  1 : SQLITE_MAX_FILE_FORMAT;
    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat);
    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db));
    sqlite3VdbeJumpHere(v, addr1);

    /* This just creates a place-holder record in the sqlite_schema table.
    /* This just creates a place-holder record in the sqlite_master table.
    ** The record created does not contain anything yet.  It will be replaced
    ** by the real entry in code generated at sqlite3EndTable().
    **
    ** The rowid for the new entry is left in register pParse->regRowid.
    ** The root page number of the new table is left in reg pParse->regRoot.
    ** The rowid and root page number values are needed by the code that
    ** sqlite3EndTable will generate.
    */
#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 =
      pParse->addrCrTab =
         sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
    }
    sqlite3OpenSchemaTable(pParse, iDb);
    sqlite3OpenMasterTable(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);
    sqlite3VdbeAddOp0(v, OP_Close);
  }

1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377

1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
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







-






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
















-
-











-

-
+

















-







/* 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 ){
    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 = 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;
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156







-







    memcpy(zType, pType->z, pType->n);
    zType[pType->n] = 0;
    sqlite3Dequote(zType);
    pCol->affinity = sqlite3AffinityType(zType, pCol);
    pCol->colFlags |= COLFLAG_HASTYPE;
  }
  p->nCol++;
  p->nNVCol++;
  pParse->constraintName.n = 0;
}

/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.  A "NOT NULL" constraint has
** been seen on a column.  This routine sets the notNull flag on
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564

1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1287
1288
1289
1290
1291
1292
1293

1294

1295
1296
1297






1298
1299
1300
1301
1302
1303
1304







-

-
+


-
-
-
-
-
-







  const char *zEnd         /* First character past end of defaut value text */
){
  Table *p;
  Column *pCol;
  sqlite3 *db = pParse->db;
  p = pParse->pNewTable;
  if( p!=0 ){
    int isInit = db->init.busy && db->init.iDb!=1;
    pCol = &(p->aCol[p->nCol-1]);
    if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){
    if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){
      sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
          pCol->zName);
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
    }else if( pCol->colFlags & COLFLAG_GENERATED ){
      testcase( pCol->colFlags & COLFLAG_VIRTUAL );
      testcase( pCol->colFlags & COLFLAG_STORED );
      sqlite3ErrorMsg(pParse, "cannot use DEFAULT on a generated column");
#endif
    }else{
      /* A copy of pExpr is used instead of the original, as pExpr contains
      ** tokens that point to volatile memory.
      */
      Expr x;
      sqlite3ExprDelete(db, pCol->pDflt);
      memset(&x, 0, sizeof(x));
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
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







-
+










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







**     CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
**     CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
**
** This is goofy.  But to preserve backwards compatibility we continue to
** accept it.  This routine does the necessary conversion.  It converts
** the expression given in its argument from a TK_STRING into a TK_ID
** if the expression is just a TK_STRING with an optional COLLATE clause.
** If the expression is anything other than TK_STRING, the expression is
** If the epxression is anything other than TK_STRING, the expression is
** unchanged.
*/
static void sqlite3StringToId(Expr *p){
  if( p->op==TK_STRING ){
    p->op = TK_ID;
  }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
    p->pLeft->op = TK_ID;
  }
}

/*
** Tag the given column as being part of the PRIMARY KEY
*/
static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){
  pCol->colFlags |= COLFLAG_PRIMKEY;
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  if( pCol->colFlags & COLFLAG_GENERATED ){
    testcase( pCol->colFlags & COLFLAG_VIRTUAL );
    testcase( pCol->colFlags & COLFLAG_STORED );
    sqlite3ErrorMsg(pParse,
      "generated columns cannot be part of the PRIMARY KEY");
  }
#endif          
}

/*
** Designate the PRIMARY KEY for the table.  pList is a list of names 
** of columns that form the primary key.  If pList is NULL, then the
** most recently added column of the table is the primary key.
**
** A table can have at most one primary key.  If the table already has
** a primary key (and this is the second primary key) then create an
1665
1666
1667
1668
1669
1670
1671
1672

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

1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705

1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728


1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766

1767
1768
1769
1770
1771
1772
1773
1375
1376
1377
1378
1379
1380
1381

1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394

1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414

1415

1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435


1436
1437


1438
1439
1440
1441
1442
1443
1444
1445
1446
1447







1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469
1470
1471
1472
1473







-
+












-
+



















-
+
-




















-
-
+
+
-
-










-
-
-
-
-
-
-


















-
+







      "table \"%s\" has more than one primary key", pTab->zName);
    goto primary_key_exit;
  }
  pTab->tabFlags |= TF_HasPrimaryKey;
  if( pList==0 ){
    iCol = pTab->nCol - 1;
    pCol = &pTab->aCol[iCol];
    makeColumnPartOfPrimaryKey(pParse, pCol);
    pCol->colFlags |= COLFLAG_PRIMKEY;
    nTerm = 1;
  }else{
    nTerm = pList->nExpr;
    for(i=0; i<nTerm; i++){
      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
      assert( pCExpr!=0 );
      sqlite3StringToId(pCExpr);
      if( pCExpr->op==TK_ID ){
        const char *zCName = pCExpr->u.zToken;
        for(iCol=0; iCol<pTab->nCol; iCol++){
          if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
            pCol = &pTab->aCol[iCol];
            makeColumnPartOfPrimaryKey(pParse, pCol);
            pCol->colFlags |= COLFLAG_PRIMKEY;
            break;
          }
        }
      }
    }
  }
  if( nTerm==1
   && pCol
   && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0
   && sortOrder!=SQLITE_SO_DESC
  ){
    if( IN_RENAME_OBJECT && pList ){
      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr);
    }
    pTab->iPKey = iCol;
    pTab->keyConf = (u8)onError;
    assert( autoInc==0 || autoInc==1 );
    pTab->tabFlags |= autoInc*TF_Autoincrement;
    if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags;
    if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
    (void)sqlite3HasExplicitNulls(pParse, pList);
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{
    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
                           0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY);
    pList = 0;
  }

primary_key_exit:
  sqlite3ExprListDelete(pParse->db, pList);
  return;
}

/*
** Add a new CHECK constraint to the table currently under construction.
*/
void sqlite3AddCheckConstraint(
  Parse *pParse,      /* Parsing context */
  Expr *pCheckExpr,   /* The check expression */
  Parse *pParse,    /* Parsing context */
  Expr *pCheckExpr  /* The check expression */
  const char *zStart, /* Opening "(" */
  const char *zEnd    /* Closing ")" */
){
#ifndef SQLITE_OMIT_CHECK
  Table *pTab = pParse->pNewTable;
  sqlite3 *db = pParse->db;
  if( pTab && !IN_DECLARE_VTAB
   && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt)
  ){
    pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr);
    if( pParse->constraintName.n ){
      sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1);
    }else{
      Token t;
      for(zStart++; sqlite3Isspace(zStart[0]); zStart++){}
      while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; }
      t.z = zStart;
      t.n = (int)(zEnd - t.z);
      sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1);    
    }
  }else
#endif
  {
    sqlite3ExprDelete(pParse->db, pCheckExpr);
  }
}

/*
** Set the collation function of the most recently parsed table column
** to the CollSeq given.
*/
void sqlite3AddCollateType(Parse *pParse, Token *pToken){
  Table *p;
  int i;
  char *zColl;              /* Dequoted name of collation sequence */
  sqlite3 *db;

  if( (p = pParse->pNewTable)==0 || IN_RENAME_OBJECT ) return;
  if( (p = pParse->pNewTable)==0 ) return;
  i = p->nCol-1;
  db = pParse->db;
  zColl = sqlite3NameFromToken(db, pToken);
  if( !zColl ) return;

  if( sqlite3LocateCollSeq(pParse, zColl) ){
    Index *pIdx;
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
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







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

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







      }
    }
  }else{
    sqlite3DbFree(db, zColl);
  }
}

/*
** This function returns the collation sequence for database native text
** encoding identified by the string zName, length nName.
**
** If the requested collation sequence is not available, or not available
** in the database native encoding, the collation factory is invoked to
** request it. If the collation factory does not supply such a sequence,
** and the sequence is available in another text encoding, then that is
** returned instead.
**
** If no versions of the requested collations sequence are available, or
** another error occurs, NULL is returned and an error message written into
/* Change the most recently parsed column to be a GENERATED ALWAYS AS
** column.
** pParse.
**
** This routine is a wrapper around sqlite3FindCollSeq().  This routine
** invokes the collation factory if the named collation cannot be found
** and generates an error message.
**
** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
*/
void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  u8 eType = COLFLAG_VIRTUAL;
  Table *pTab = pParse->pNewTable;
  Column *pCol;
  sqlite3 *db = pParse->db;
  u8 enc = ENC(db);
  u8 initbusy = db->init.busy;
  CollSeq *pColl;
  if( pTab==0 ){
    /* generated column in an CREATE TABLE IF NOT EXISTS that already exists */
    goto generated_done;
  }

  pCol = &(pTab->aCol[pTab->nCol-1]);
  if( IN_DECLARE_VTAB ){
    sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns");
  pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
    goto generated_done;
  }
  if( pCol->pDflt ) goto generated_error;
  if( pType ){
    if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){
  if( !initbusy && (!pColl || !pColl->xCmp) ){
    pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
      /* no-op */
    }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){
      eType = COLFLAG_STORED;
    }else{
      goto generated_error;
    }
  }
  }

  if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--;
  pCol->colFlags |= eType;
  assert( TF_HasVirtual==COLFLAG_VIRTUAL );
  assert( TF_HasStored==COLFLAG_STORED );
  pTab->tabFlags |= eType;
  if( pCol->colFlags & COLFLAG_PRIMKEY ){
    makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */
  }
  pCol->pDflt = pExpr;
  return pColl;
  pExpr = 0;
  goto generated_done;

}
generated_error:
  sqlite3ErrorMsg(pParse, "error in generated column \"%s\"",
                  pCol->zName);
generated_done:
  sqlite3ExprDelete(pParse->db, pExpr);
#else
  /* Throw and error for the GENERATED ALWAYS AS clause if the
  ** SQLITE_OMIT_GENERATED_COLUMNS compile-time option is used. */
  sqlite3ErrorMsg(pParse, "generated columns not supported");
  sqlite3ExprDelete(pParse->db, pExpr);
#endif
}


/*
** Generate code that will increment the schema cookie.
**
** The schema cookie is used to determine when the schema for the
** database changes.  After each schema change, the cookie value
** changes.  When a process first reads the schema it records the
1994
1995
1996
1997
1998
1999
2000
2001

2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
1677
1678
1679
1680
1681
1682
1683

1684
1685
1686
1687
1688
1689



1690
1691
1692
1693
1694
1695
1696







-
+





-
-
-







** on success and SQLITE_NOMEM on an OOM error.
*/
static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
  char *zExtra;
  int nByte;
  if( pIdx->nColumn>=N ) return SQLITE_OK;
  assert( pIdx->isResized==0 );
  nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N;
  nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
  zExtra = sqlite3DbMallocZero(db, nByte);
  if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
  memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
  pIdx->azColl = (const char**)zExtra;
  zExtra += sizeof(char*)*N;
  memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1));
  pIdx->aiRowLogEst = (LogEst*)zExtra;
  zExtra += sizeof(LogEst)*N;
  memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
  pIdx->aiColumn = (i16*)zExtra;
  zExtra += sizeof(i16)*N;
  memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn);
  pIdx->aSortOrder = (u8*)zExtra;
  pIdx->nColumn = N;
  pIdx->isResized = 1;
2042
2043
2044
2045
2046
2047
2048
2049

2050
2051
2052
2053
2054

2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121

2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141

2142
2143

2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179

2180
2181

2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197

2198
2199
2200
2201
2202
2203
2204

2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215

2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229

2230
2231

2232
2233
2234
2235
2236
2237

2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251

2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263

2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280

2281
2282
2283
2284
2285
2286



2287
2288
2289
2290
2291
2292
2293
2294
2295
2296








2297
2298
2299
2300



2301
2302
2303
2304
2305
2306
2307
2308
2309

2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330

2331
2332


2333
2334
2335
2336
2337
2338
2339

2340

2341
2342
2343
2344


2345
2346
2347
2348
2349
2350
2351
2352
2353
2354

2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367

2368
2369

2370
2371
2372
2373
2374
2375
2376
2377
2378
2379

2380
2381
2382


2383
2384

2385
2386
2387
2388
2389
2390
2391
1722
1723
1724
1725
1726
1727
1728

1729


1730
1731

1732







































1733
1734
1735
1736
1737
1738
1739
1740
1741
1742








1743
1744
1745
1746
1747
1748

1749
1750

1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770

1771
1772

1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788

1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800

1801
1802
1803
1804
1805


1806
1807

1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820




1821
1822

1823
1824
1825
1826

1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837

1838
1839
1840



1841
1842
1843
1844
1845
1846
1847
1848

1849
1850

1851
1852
1853
1854
1855
1856

1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869


1870


1871
1872
1873
1874
1875
1876
1877
1878


1879
1880
1881




1882
1883
1884
1885
1886
1887
1888
1889
1890


1891






1892
1893
1894










1895
1896
1897
1898
1899
1900
1901
1902




1903
1904
1905









1906









1907

1908
1909
1910
1911
1912
1913
1914
1915
1916

1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929

1930




1931
1932










1933
1934










1935

1936


1937
1938
1939
1940
1941
1942
1943
1944
1945
1946

1947
1948


1949
1950
1951

1952
1953
1954
1955
1956
1957
1958
1959







-
+
-
-


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










-
-
-
-
-
-
-
-






-


-
+



















-
+

-
+















-












-





-
-
+

-
+












-
-
-
-
+

-




-
+










-
+


-
-
-








-
+

-
+





-
+












-
-
+
-
-








-
-
+


-
-
-
-









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

-









-
+


+
+







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

-
-
-
-
-
-
-
-
-
-

-
+
-
-
+









-
+

-
-
+
+

-
+







    i16 x = pIdx->aiColumn[i];
    assert( x<pIdx->pTable->nCol );
    wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
  }
  pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
}

/* Return true if column number x is any of the first nCol entries of aiCol[].
/* Return true if value x is found any of the first nCol entries of aiCol[]
** This is used to determine if the column number x appears in any of the
** first nCol entries of an index.
*/
static int hasColumn(const i16 *aiCol, int nCol, int x){
  while( nCol-- > 0 ){
  while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
    assert( aiCol[0]>=0 );
    if( x==*(aiCol++) ){
      return 1;
    }
  }
  return 0;
}

/*
** Return true if any of the first nKey entries of index pIdx exactly
** match the iCol-th entry of pPk.  pPk is always a WITHOUT ROWID
** PRIMARY KEY index.  pIdx is an index on the same table.  pIdx may
** or may not be the same index as pPk.
**
** The first nKey entries of pIdx are guaranteed to be ordinary columns,
** not a rowid or expression.
**
** This routine differs from hasColumn() in that both the column and the
** collating sequence must match for this routine, but for hasColumn() only
** the column name must match.
*/
static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
  int i, j;
  assert( nKey<=pIdx->nColumn );
  assert( iCol<MAX(pPk->nColumn,pPk->nKeyCol) );
  assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
  assert( pPk->pTable->tabFlags & TF_WithoutRowid );
  assert( pPk->pTable==pIdx->pTable );
  testcase( pPk==pIdx );
  j = pPk->aiColumn[iCol];
  assert( j!=XN_ROWID && j!=XN_EXPR );
  for(i=0; i<nKey; i++){
    assert( pIdx->aiColumn[i]>=0 || j>=0 );
    if( pIdx->aiColumn[i]==j 
     && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
    ){
      return 1;
    }
  }
  return 0;
}

/* Recompute the colNotIdxed field of the Index.
**
** colNotIdxed is a bitmask that has a 0 bit representing each indexed
** columns that are within the first 63 columns of the table.  The
** high-order bit of colNotIdxed is always 1.  All unindexed columns
** of the table have a 1.
**
** 2019-10-24:  For the purpose of this computation, virtual columns are
** not considered to be covered by the index, even if they are in the
** index, because we do not trust the logic in whereIndexExprTrans() to be
** able to find all instances of a reference to the indexed table column
** and convert them into references to the index.  Hence we always want
** the actual table at hand in order to recompute the virtual column, if
** necessary.
**
** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask
** to determine if the index is covering index.
*/
static void recomputeColumnsNotIndexed(Index *pIdx){
  Bitmask m = 0;
  int j;
  Table *pTab = pIdx->pTable;
  for(j=pIdx->nColumn-1; j>=0; j--){
    int x = pIdx->aiColumn[j];
    if( x>=0 && (pTab->aCol[x].colFlags & COLFLAG_VIRTUAL)==0 ){
    if( x>=0 ){
      testcase( x==BMS-1 );
      testcase( x==BMS-2 );
      if( x<BMS-1 ) m |= MASKBIT(x);
    }
  }
  pIdx->colNotIdxed = ~m;
  assert( (pIdx->colNotIdxed>>63)==1 );
}

/*
** This routine runs at the end of parsing a CREATE TABLE statement that
** has a WITHOUT ROWID clause.  The job of this routine is to convert both
** internal schema data structures and the generated VDBE code so that they
** are appropriate for a WITHOUT ROWID table instead of a rowid table.
** Changes include:
**
**     (1)  Set all columns of the PRIMARY KEY schema object to be NOT NULL.
**     (2)  Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY 
**          into BTREE_BLOBKEY.
**     (3)  Bypass the creation of the sqlite_schema table entry
**     (3)  Bypass the creation of the sqlite_master table entry
**          for the PRIMARY KEY as the primary key index is now
**          identified by the sqlite_schema table entry of the table itself.
**          identified by the sqlite_master table entry of the table itself.
**     (4)  Set the Index.tnum of the PRIMARY KEY Index object in the
**          schema to the rootpage from the main table.
**     (5)  Add all table columns to the PRIMARY KEY Index object
**          so that the PRIMARY KEY is a covering index.  The surplus
**          columns are part of KeyInfo.nAllField and are not used for
**          sorting or lookup or uniqueness checks.
**     (6)  Replace the rowid tail on all automatically generated UNIQUE
**          indices with the PRIMARY KEY columns.
**
** For virtual tables, only (1) is performed.
*/
static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
  Index *pIdx;
  Index *pPk;
  int nPk;
  int nExtra;
  int i, j;
  sqlite3 *db = pParse->db;
  Vdbe *v = pParse->pVdbe;

  /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
  */
  if( !db->init.imposterTable ){
    for(i=0; i<pTab->nCol; i++){
      if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){
        pTab->aCol[i].notNull = OE_Abort;
      }
    }
    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 ){
  if( pParse->addrCrTab ){
    assert( v );
    sqlite3VdbeChangeP3(v, pParse->u1.addrCrTab, BTREE_BLOBKEY);
    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;
    Token ipkToken;
    sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
    pList = sqlite3ExprListAppend(pParse, 0, 
                  sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
    if( pList==0 ) return;
    if( IN_RENAME_OBJECT ){
      sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
    }
    pList->a[0].sortFlags = pParse->iPkSortOrder;
    pList->a[0].sortOrder = pParse->iPkSortOrder;
    assert( pParse->pNewTable==pTab );
    pTab->iPKey = -1;
    sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
                       SQLITE_IDXTYPE_PRIMARYKEY);
    if( db->mallocFailed || pParse->nErr ) return;
    pPk = sqlite3PrimaryKeyIndex(pTab);
    assert( pPk->nKeyCol==1 );
    pTab->iPKey = -1;
  }else{
    pPk = sqlite3PrimaryKeyIndex(pTab);
    assert( pPk!=0 );

    /*
    ** Remove all redundant columns from the PRIMARY KEY.  For example, change
    ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
    ** code assumes the PRIMARY KEY contains no repeated columns.
    */
    for(i=j=1; i<pPk->nKeyCol; i++){
      if( isDupColumn(pPk, j, pPk, i) ){
      if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
        pPk->nColumn--;
      }else{
        testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
        pPk->azColl[j] = pPk->azColl[i];
        pPk->aSortOrder[j] = pPk->aSortOrder[i];
        pPk->aiColumn[j++] = pPk->aiColumn[i];
      }
    }
    pPk->nKeyCol = j;
  }
  assert( pPk!=0 );
  pPk->isCovering = 1;
  if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
  nPk = pPk->nColumn = pPk->nKeyCol;
  nPk = pPk->nKeyCol;

  /* Bypass the creation of the PRIMARY KEY btree and the sqlite_schema
  /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
  ** table entry. This is only required if currently generating VDBE
  ** code for a CREATE TABLE (not when parsing one as part of reading
  ** a database schema).  */
  if( v && pPk->tnum>0 ){
    assert( db->init.busy==0 );
    sqlite3VdbeChangeOpcode(v, (int)pPk->tnum, OP_Goto);
    sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
  }

  /* The root page of the PRIMARY KEY is the table root page */
  pPk->tnum = pTab->tnum;

  /* Update the in-memory representation of all UNIQUE indices by converting
  ** the final rowid column into one or more columns of the PRIMARY KEY.
  */
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    int n;
    if( IsPrimaryKeyIndex(pIdx) ) continue;
    for(i=n=0; i<nPk; i++){
      if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
        testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
      if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
        n++;
      }
    }
    if( n==0 ){
      /* This index is a superset of the primary key */
      pIdx->nColumn = pIdx->nKeyCol;
      continue;
    }
    if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
    for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
      if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
        testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
      if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
        pIdx->aiColumn[j] = pPk->aiColumn[i];
        pIdx->azColl[j] = pPk->azColl[i];
        if( pPk->aSortOrder[i] ){
          /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */
          pIdx->bAscKeyBug = 1;
        }
        j++;
      }
    }
    assert( pIdx->nColumn>=pIdx->nKeyCol+n );
    assert( pIdx->nColumn>=j );
  }

  /* Add all table columns to the PRIMARY KEY index
  */
  nExtra = 0;
  for(i=0; i<pTab->nCol; i++){
  if( nPk<pTab->nCol ){
    if( !hasColumn(pPk->aiColumn, nPk, i)
     && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++;
  }
  if( resizeIndexObject(db, pPk, nPk+nExtra) ) return;
  for(i=0, j=nPk; i<pTab->nCol; i++){
    if( !hasColumn(pPk->aiColumn, j, i)
    if( resizeIndexObject(db, pPk, pTab->nCol) ) return;
    for(i=0, j=nPk; i<pTab->nCol; i++){
      if( !hasColumn(pPk->aiColumn, j, i) ){
     && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0
    ){
      assert( j<pPk->nColumn );
      pPk->aiColumn[j] = i;
      pPk->azColl[j] = sqlite3StrBINARY;
      j++;
    }
  }
  assert( pPk->nColumn==j );
  assert( pTab->nNVCol<=j );
        assert( j<pPk->nColumn );
        pPk->aiColumn[j] = i;
        pPk->azColl[j] = sqlite3StrBINARY;
        j++;
      }
    }
    assert( pPk->nColumn==j );
    assert( pTab->nCol==j );
  recomputeColumnsNotIndexed(pPk);
}


  }else{
    pPk->nColumn = pTab->nCol;
  }
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return true if pTab is a virtual table and zName is a shadow table name
** for that virtual table.
*/
int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){
  int nName;                    /* Length of zName */
  Module *pMod;                 /* Module for the virtual table */

  recomputeColumnsNotIndexed(pPk);
  if( !IsVirtual(pTab) ) return 0;
  nName = sqlite3Strlen30(pTab->zName);
  if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0;
  if( zName[nName]!='_' ) return 0;
  pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
  if( pMod==0 ) return 0;
  if( pMod->pModule->iVersion<3 ) return 0;
  if( pMod->pModule->xShadowName==0 ) return 0;
  return pMod->pModule->xShadowName(zName+nName+1);
}
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return true if zName is a shadow table name in the current database
** connection.
**
** zName is temporarily modified while this routine is running, but is
** restored to its original value prior to this routine returning.
*/
int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
static int isShadowTableName(sqlite3 *db, char *zName){
  char *zTail;                  /* Pointer to the last "_" in zName */
  Table *pTab;                  /* Table that zName is a shadow of */
  Module *pMod;                 /* Module for the virtual table */

  zTail = strrchr(zName, '_');
  if( zTail==0 ) return 0;
  *zTail = 0;
  pTab = sqlite3FindTable(db, zName, 0);
  *zTail = '_';
  if( pTab==0 ) return 0;
  if( !IsVirtual(pTab) ) return 0;
  pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
  return sqlite3IsShadowTableOf(db, pTab, zName);
  if( pMod==0 ) return 0;
}
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */


  if( pMod->pModule->iVersion<3 ) return 0;
  if( pMod->pModule->xShadowName==0 ) return 0;
#ifdef SQLITE_DEBUG
/*
** Mark all nodes of an expression as EP_Immutable, indicating that
** they should not be changed.  Expressions attached to a table or
** index definition are tagged this way to help ensure that we do
** not pass them into code generator routines by mistake.
*/
static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){
  ExprSetVVAProperty(pExpr, EP_Immutable);
  return WRC_Continue;
  return pMod->pModule->xShadowName(zTail+1);
}
static void markExprListImmutable(ExprList *pList){
  if( pList ){
    Walker w;
    memset(&w, 0, sizeof(w));
    w.xExprCallback = markImmutableExprStep;
    w.xSelectCallback = sqlite3SelectWalkNoop;
    w.xSelectCallback2 = 0;
    sqlite3WalkExprList(&w, pList);
  }
}
#else
#define markExprListImmutable(X)  /* no-op */
# define isShadowTableName(x,y) 0
#endif /* SQLITE_DEBUG */

#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */

/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have
** occurred.
**
** An entry for the table is made in the schema table on disk, unless
** An entry for the table is made in the master table on disk, unless
** this is a temporary table or db->init.busy==1.  When db->init.busy==1
** it means we are reading the sqlite_schema table because we just
** connected to the database or because the sqlite_schema table has
** it means we are reading the sqlite_master table because we just
** connected to the database or because the sqlite_master table has
** recently changed, so the entry for this table already exists in
** the sqlite_schema table.  We do not want to create it again.
** the sqlite_master table.  We do not want to create it again.
**
** If the pSelect argument is not NULL, it means that this routine
** was called to create a table generated from a 
** "CREATE TABLE ... AS SELECT ..." statement.  The column names of
** the new table will match the result set of the SELECT.
*/
void sqlite3EndTable(
2403
2404
2405
2406
2407
2408
2409
2410

2411
2412
2413
2414
2415

2416
2417
2418
2419
2420

2421
2422
2423
2424
2425
2426
2427
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







-
+




-
+




-
+







  if( pEnd==0 && pSelect==0 ){
    return;
  }
  assert( !db->mallocFailed );
  p = pParse->pNewTable;
  if( p==0 ) return;

  if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){
  if( pSelect==0 && isShadowTableName(db, p->zName) ){
    p->tabFlags |= TF_Shadow;
  }

  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_schema" or "sqlite_temp_schema" table on the disk.
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number
  ** should have been put there by the sqliteOpenCb routine.)
  **
  ** If the root page number is 1, that means this is the sqlite_schema
  ** If the root page number is 1, that means this is the sqlite_master
  ** table itself.  So mark it read-only.
  */
  if( db->init.busy ){
    if( pSelect ){
      sqlite3ErrorMsg(pParse, "");
      return;
    }
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450






2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465

2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507

2508
2509
2510
2511
2512
2513
2514
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







-
-
-
-
-
+
+
+
+
+
+







-
-
-
-
-
-
-
-
+
-

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








-
+







    if( (p->tabFlags & TF_Autoincrement) ){
      sqlite3ErrorMsg(pParse,
          "AUTOINCREMENT not allowed on WITHOUT ROWID tables");
      return;
    }
    if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
      sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
      return;
    }
    p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
    convertToWithoutRowidTable(pParse, p);
  }
    }else{
      p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
      convertToWithoutRowidTable(pParse, p);
    }
  }

  iDb = sqlite3SchemaToIndex(db, p->pSchema);

#ifndef SQLITE_OMIT_CHECK
  /* Resolve names in all CHECK constraint expressions.
  */
  if( p->pCheck ){
    sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
    if( pParse->nErr ){
      /* If errors are seen, delete the CHECK constraints now, else they might
      ** actually be used if PRAGMA writable_schema=ON is set. */
      sqlite3ExprListDelete(db, p->pCheck);
      p->pCheck = 0;
    }else{
      markExprListImmutable(p->pCheck);
    }
  }
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  if( p->tabFlags & TF_HasGenerated ){
    int ii, nNG = 0;
    testcase( p->tabFlags & TF_HasVirtual );
    testcase( p->tabFlags & TF_HasStored );
    for(ii=0; ii<p->nCol; ii++){
      u32 colFlags = p->aCol[ii].colFlags;
      if( (colFlags & COLFLAG_GENERATED)!=0 ){
        Expr *pX = p->aCol[ii].pDflt;
        testcase( colFlags & COLFLAG_VIRTUAL );
        testcase( colFlags & COLFLAG_STORED );
        if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){
          /* If there are errors in resolving the expression, change the
          ** expression to a NULL.  This prevents code generators that operate
          ** on the expression from inserting extra parts into the expression
          ** tree that have been allocated from lookaside memory, which is
          ** illegal in a schema and will lead to errors or heap corruption
          ** when the database connection closes. */
          sqlite3ExprDelete(db, pX);
          p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
        }
      }else{
        nNG++;
      }
    }
    if( nNG==0 ){
      sqlite3ErrorMsg(pParse, "must have at least one non-generated column");
      return;
    }
  }
#endif

  /* Estimate the average row size for the table and for all implied indices */
  estimateTableWidth(p);
  for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
    estimateIndexWidth(pIdx);
  }

  /* If not initializing, then create a record for the new table
  ** in the schema table of the database.
  ** in the SQLITE_MASTER table of the database.
  **
  ** If this is a TEMPORARY table, write the entry into the auxiliary
  ** file instead of into the main database file.
  */
  if( !db->init.busy ){
    int n;
    Vdbe *v;
2565
2566
2567
2568
2569
2570
2571
2572

2573
2574
2575

2576
2577
2578
2579
2580
2581
2582
2095
2096
2097
2098
2099
2100
2101

2102
2103
2104

2105
2106
2107
2108
2109
2110
2111
2112







-
+


-
+







      sqlite3MayAbort(pParse);
      sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
      sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
      pParse->nTab = 2;
      addrTop = sqlite3VdbeCurrentAddr(v) + 1;
      sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
      if( pParse->nErr ) return;
      pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB);
      pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
      if( pSelTab==0 ) return;
      assert( p->aCol==0 );
      p->nCol = p->nNVCol = pSelTab->nCol;
      p->nCol = pSelTab->nCol;
      p->aCol = pSelTab->aCol;
      pSelTab->nCol = 0;
      pSelTab->aCol = 0;
      sqlite3DeleteTable(db, pSelTab);
      sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
      sqlite3Select(pParse, pSelect, &dest);
      if( pParse->nErr ) return;
2602
2603
2604
2605
2606
2607
2608
2609

2610
2611
2612
2613
2614
2615
2616




2617
2618
2619
2620
2621
2622
2623
2132
2133
2134
2135
2136
2137
2138

2139
2140
2141
2142




2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153







-
+



-
-
-
-
+
+
+
+







      if( pEnd2->z[0]!=';' ) n += pEnd2->n;
      zStmt = sqlite3MPrintf(db, 
          "CREATE %s %.*s", zType2, n, pParse->sNameToken.z
      );
    }

    /* A slot for the record has already been allocated in the 
    ** schema table.  We just need to update that slot with all
    ** SQLITE_MASTER table.  We just need to update that slot with all
    ** the information we've collected.
    */
    sqlite3NestedParse(pParse,
      "UPDATE %Q." DFLT_SCHEMA_TABLE
      " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
      " WHERE rowid=#%d",
      db->aDb[iDb].zDbSName,
      "UPDATE %Q.%s "
         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
       "WHERE rowid=#%d",
      db->aDb[iDb].zDbSName, MASTER_NAME,
      zType,
      p->zName,
      p->zName,
      pParse->regRoot,
      zStmt,
      pParse->regRowid
    );
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
2168
2169
2170
2171
2172
2173
2174

2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192

2193

2194







2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213







-
+

+















-
+
-

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

+







        );
      }
    }
#endif

    /* Reparse everything to update our internal data structures */
    sqlite3VdbeAddParseSchemaOp(v, iDb,
           sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0);
           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( !pSelect && !p->pSelect ){
    assert( pCons && pEnd );
    if( pCons->z==0 ){
      pCons = pEnd;
    }
    p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z);
  }
    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(
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2242
2243
2244
2245
2246
2247
2248

2249
2250
2251
2252
2253
2254
2255







-







  if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail;

  /* Make a copy of the entire SELECT statement that defines the view.
  ** This will force all the Expr.token.z values to be dynamically
  ** allocated rather than point to the input string - which means that
  ** they will persist after the current sqlite3_exec() call returns.
  */
  pSelect->selFlags |= SF_View;
  if( IN_RENAME_OBJECT ){
    p->pSelect = pSelect;
    pSelect = 0;
  }else{
    p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
  }
  p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
2734
2735
2736
2737
2738
2739
2740
2741

2742
2743
2744
2745
2746
2747
2748
2267
2268
2269
2270
2271
2272
2273

2274
2275
2276
2277
2278
2279
2280
2281







-
+







  n = (int)(sEnd.z - pBegin->z);
  assert( n>0 );
  z = pBegin->z;
  while( sqlite3Isspace(z[n-1]) ){ n--; }
  sEnd.z = &z[n-1];
  sEnd.n = 1;

  /* Use sqlite3EndTable() to add the view to the schema table */
  /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
  sqlite3EndTable(pParse, 0, &sEnd, 0, 0);

create_view_fail:
  sqlite3SelectDelete(db, pSelect);
  if( IN_RENAME_OBJECT ){
    sqlite3RenameExprlistUnmap(pParse, pCNames);
  }
2815
2816
2817
2818
2819
2820
2821

2822
2823

2824
2825
2826
2827

2828
2829
2830
2831

2832
2833
2834

2835
2836
2837
2838
2839
2840

2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853

2854
2855
2856

2857
2858
2859
2860
2861
2862
2863
2864
2865
2866



2867
2868
2869
2870
2871


2872

2873
2874
2875
2876
2877
2878
2879
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361

2362
2363
2364
2365

2366
2367
2368

2369
2370
2371




2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384

2385

2386

2387
2388
2389
2390
2391
2392
2393

2394
2395
2396
2397
2398
2399
2400

2401
2402

2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413







+


+



-
+



-
+


-
+


-
-
-
-
+












-
+
-

-
+






-



+
+
+

-


-
+
+

+







  ** to the elements of the FROM clause.  But we do not want these changes
  ** to be permanent.  So the computation is done on a copy of the SELECT
  ** statement that defines the view.
  */
  assert( pTable->pSelect );
  pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
  if( pSel ){
#ifndef SQLITE_OMIT_ALTERTABLE
    u8 eParseMode = pParse->eParseMode;
    pParse->eParseMode = PARSE_MODE_NORMAL;
#endif
    n = pParse->nTab;
    sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
    pTable->nCol = -1;
    DisableLookaside;
    db->lookaside.bDisable++;
#ifndef SQLITE_OMIT_AUTHORIZATION
    xAuth = db->xAuth;
    db->xAuth = 0;
    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
    db->xAuth = xAuth;
#else
    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
#endif
    pParse->nTab = n;
    if( pSelTab==0 ){
      pTable->nCol = 0;
      nErr++;
    }else if( pTable->pCheck ){
    if( pTable->pCheck ){
      /* CREATE VIEW name(arglist) AS ...
      ** The names of the columns in the table are taken from
      ** arglist which is stored in pTable->pCheck.  The pCheck field
      ** normally holds CHECK constraints on an ordinary table, but for
      ** a VIEW it holds the list of column names.
      */
      sqlite3ColumnsFromExprList(pParse, pTable->pCheck, 
                                 &pTable->nCol, &pTable->aCol);
      if( db->mallocFailed==0 
       && pParse->nErr==0
       && pTable->nCol==pSel->pEList->nExpr
      ){
        sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
        sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
                                               SQLITE_AFF_NONE);
      }
    }else{
    }else if( pSelTab ){
      /* 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) );
    }else{
      pTable->nCol = 0;
      nErr++;
    }
    pTable->nNVCol = pTable->nCol;
    sqlite3DeleteTable(db, pSelTab);
    sqlite3SelectDelete(db, pSel);
    EnableLookaside;
    db->lookaside.bDisable--;
#ifndef SQLITE_OMIT_ALTERTABLE
    pParse->eParseMode = eParseMode;
#endif
  } else {
    nErr++;
  }
  pTable->pSchema->schemaFlags |= DB_UnresetViews;
  if( db->mallocFailed ){
    sqlite3DeleteColumnNames(db, pTable);
    pTable->aCol = 0;
2920
2921
2922
2923
2924
2925
2926
2927

2928
2929
2930
2931
2932
2933
2934
2454
2455
2456
2457
2458
2459
2460

2461
2462
2463
2464
2465
2466
2467
2468







-
+







** because the first match might be for one of the deleted indices
** or tables and not the table/index that is actually being moved.
** We must continue looping until all tables and indices with
** rootpage==iFrom have been converted to have a rootpage of iTo
** in order to be certain that we got the right one.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
void sqlite3RootPageMoved(sqlite3 *db, int iDb, Pgno iFrom, Pgno iTo){
void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){
  HashElem *pElem;
  Hash *pHash;
  Db *pDb;

  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  pDb = &db->aDb[iDb];
  pHash = &pDb->pSchema->tblHash;
2946
2947
2948
2949
2950
2951
2952
2953

2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966

2967
2968
2969
2970
2971
2972
2973
2974
2975
2976


2977
2978
2979
2980
2981
2982
2983

2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005


3006
3007
3008
3009

3010
3011
3012
3013
3014
3015

3016
3017
3018
3019
3020
3021
3022
2480
2481
2482
2483
2484
2485
2486

2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499

2500
2501
2502
2503
2504
2505
2506
2507



2508
2509
2510
2511
2512
2513
2514
2515

2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536


2537
2538
2539
2540
2541

2542
2543
2544
2545
2546
2547

2548
2549
2550
2551
2552
2553
2554
2555







-
+












-
+







-
-
-
+
+






-
+




















-
-
+
+



-
+





-
+







    }
  }
}
#endif

/*
** Write code to erase the table with root-page iTable from database iDb.
** Also write code to modify the sqlite_schema table and internal schema
** Also write code to modify the sqlite_master table and internal schema
** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
*/ 
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
  Vdbe *v = sqlite3GetVdbe(pParse);
  int r1 = sqlite3GetTempReg(pParse);
  if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
  sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
  sqlite3MayAbort(pParse);
#ifndef SQLITE_OMIT_AUTOVACUUM
  /* OP_Destroy stores an in integer r1. If this integer
  ** is non-zero, then it is the root page number of a table moved to
  ** location iTable. The following code modifies the sqlite_schema table to
  ** location iTable. The following code modifies the sqlite_master table to
  ** reflect this.
  **
  ** The "#NNN" in the SQL is a special constant that means whatever value
  ** is in register NNN.  See grammar rules associated with the TK_REGISTER
  ** token for additional information.
  */
  sqlite3NestedParse(pParse, 
     "UPDATE %Q." DFLT_SCHEMA_TABLE
     " SET rootpage=%d WHERE #%d AND rootpage=#%d",
     pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
     "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
     pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1);
#endif
  sqlite3ReleaseTempReg(pParse, r1);
}

/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** Code to update the sqlite_schema tables and internal schema definitions
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
*/
static void destroyTable(Parse *pParse, Table *pTab){
  /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
  ** is not defined), then it is important to call OP_Destroy on the
  ** table and index root-pages in order, starting with the numerically 
  ** largest root-page number. This guarantees that none of the root-pages
  ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the
  ** following were coded:
  **
  ** OP_Destroy 4 0
  ** ...
  ** OP_Destroy 5 0
  **
  ** and root page 5 happened to be the largest root-page number in the
  ** database, then root page 5 would be moved to page 4 by the 
  ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit
  ** a free-list page.
  */
  Pgno iTab = pTab->tnum;
  Pgno iDestroyed = 0;
  int iTab = pTab->tnum;
  int iDestroyed = 0;

  while( 1 ){
    Index *pIdx;
    Pgno iLargest = 0;
    int iLargest = 0;

    if( iDestroyed==0 || iTab<iDestroyed ){
      iLargest = iTab;
    }
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      Pgno iIdx = pIdx->tnum;
      int iIdx = pIdx->tnum;
      assert( pIdx->pSchema==pTab->pSchema );
      if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
        iLargest = iIdx;
      }
    }
    if( iLargest==0 ){
      return;
3069
3070
3071
3072
3073
3074
3075
3076
3077


3078
3079
3080
3081
3082
3083
3084
2602
2603
2604
2605
2606
2607
2608


2609
2610
2611
2612
2613
2614
2615
2616
2617







-
-
+
+







#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pTab) ){
    sqlite3VdbeAddOp0(v, OP_VBegin);
  }
#endif

  /* Drop all triggers associated with the table being dropped. Code
  ** is generated to remove entries from sqlite_schema and/or
  ** sqlite_temp_schema if required.
  ** is generated to remove entries from sqlite_master and/or
  ** sqlite_temp_master if required.
  */
  pTrigger = sqlite3TriggerList(pParse, pTab);
  while( pTrigger ){
    assert( pTrigger->pSchema==pTab->pSchema || 
        pTrigger->pSchema==db->aDb[1].pSchema );
    sqlite3DropTriggerPtr(pParse, pTrigger);
    pTrigger = pTrigger->pNext;
3094
3095
3096
3097
3098
3099
3100
3101
3102


3103
3104
3105
3106
3107
3108
3109
3110
3111


3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
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







-
-
+
+






-
-
-
+
+
















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







    sqlite3NestedParse(pParse,
      "DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
      pDb->zDbSName, pTab->zName
    );
  }
#endif

  /* Drop all entries in the schema table that refer to the
  ** table. The program name loops through the schema table and deletes
  /* Drop all SQLITE_MASTER table and index entries that refer to the
  ** table. The program name loops through the master table and deletes
  ** every row that refers to a table of the same name as the one being
  ** dropped. Triggers are handled separately because a trigger can be
  ** created in the temp database that refers to a table in another
  ** database.
  */
  sqlite3NestedParse(pParse, 
      "DELETE FROM %Q." DFLT_SCHEMA_TABLE
      " WHERE tbl_name=%Q and type!='trigger'",
      pDb->zDbSName, pTab->zName);
      "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
      pDb->zDbSName, MASTER_NAME, pTab->zName);
  if( !isView && !IsVirtual(pTab) ){
    destroyTable(pParse, pTab);
  }

  /* Remove the table entry from SQLite's internal schema and modify
  ** the schema cookie.
  */
  if( IsVirtual(pTab) ){
    sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
    sqlite3MayAbort(pParse);
  }
  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
  sqlite3ChangeCookie(pParse, iDb);
  sqliteViewResetAll(db, iDb);
}

/*
** Return TRUE if shadow tables should be read-only in the current
** context.
*/
int sqlite3ReadOnlyShadowTables(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( (db->flags & SQLITE_Defensive)!=0
   && db->pVtabCtx==0
   && db->nVdbeExec==0
  ){
    return 1;
  }
#endif
  return 0;
}

/*
** Return true if it is not allowed to drop the given table
*/
static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0;
    if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
    return 1;
  }
  if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
    return 1;
  }
  return 0;
}

/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
  Table *pTab;
  Vdbe *v;
3221
3222
3223
3224
3225
3226
3227
3228


3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247

3248
3249
3250
3251
3252
3253
3254
2722
2723
2724
2725
2726
2727
2728

2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748

2749
2750
2751
2752
2753
2754
2755
2756







-
+
+


















-
+







      goto exit_drop_table;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( tableMayNotBeDropped(db, pTab) ){
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 
    && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.
  */
  if( isView && pTab->pSelect==0 ){
    sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
    goto exit_drop_table;
  }
  if( !isView && pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
    goto exit_drop_table;
  }
#endif

  /* Generate code to remove the table from the schema table
  /* Generate code to remove the table from the master table
  ** on disk.
  */
  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3BeginWriteOperation(pParse, 1, iDb);
    if( !isView ){
      sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
3313
3314
3315
3316
3317
3318
3319
3320

3321
3322
3323
3324
3325
3326
3327
2815
2816
2817
2818
2819
2820
2821

2822
2823
2824
2825
2826
2827
2828
2829







-
+







    goto fk_end;
  }else{
    nCol = pFromCol->nExpr;
  }
  nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1;
  if( pToCol ){
    for(i=0; i<pToCol->nExpr; i++){
      nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1;
      nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1;
    }
  }
  pFKey = sqlite3DbMallocZero(db, nByte );
  if( pFKey==0 ){
    goto fk_end;
  }
  pFKey->pFrom = p;
3338
3339
3340
3341
3342
3343
3344
3345

3346
3347
3348
3349
3350
3351
3352
3353

3354
3355
3356
3357

3358
3359
3360
3361
3362
3363

3364
3365
3366

3367
3368

3369
3370
3371
3372
3373
3374
3375
2840
2841
2842
2843
2844
2845
2846

2847
2848
2849
2850
2851
2852
2853
2854

2855
2856
2857
2858

2859
2860
2861
2862
2863
2864

2865
2866
2867

2868
2869

2870
2871
2872
2873
2874
2875
2876
2877







-
+







-
+



-
+





-
+


-
+

-
+







  pFKey->nCol = nCol;
  if( pFromCol==0 ){
    pFKey->aCol[0].iFrom = p->nCol-1;
  }else{
    for(i=0; i<nCol; i++){
      int j;
      for(j=0; j<p->nCol; j++){
        if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zEName)==0 ){
        if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
          pFKey->aCol[i].iFrom = j;
          break;
        }
      }
      if( j>=p->nCol ){
        sqlite3ErrorMsg(pParse, 
          "unknown column \"%s\" in foreign key definition", 
          pFromCol->a[i].zEName);
          pFromCol->a[i].zName);
        goto fk_end;
      }
      if( IN_RENAME_OBJECT ){
        sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zEName);
        sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName);
      }
    }
  }
  if( pToCol ){
    for(i=0; i<nCol; i++){
      int n = sqlite3Strlen30(pToCol->a[i].zEName);
      int n = sqlite3Strlen30(pToCol->a[i].zName);
      pFKey->aCol[i].zCol = z;
      if( IN_RENAME_OBJECT ){
        sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zEName);
        sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName);
      }
      memcpy(z, pToCol->a[i].zEName, n);
      memcpy(z, pToCol->a[i].zName, n);
      z[n] = 0;
      z += n+1;
    }
  }
  pFKey->isDeferred = 0;
  pFKey->aAction[0] = (u8)(flags & 0xff);            /* ON DELETE action */
  pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff);    /* ON UPDATE action */
3431
3432
3433
3434
3435
3436
3437
3438

3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459

3460
3461
3462
3463
3464
3465
3466
2933
2934
2935
2936
2937
2938
2939

2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960

2961
2962
2963
2964
2965
2966
2967
2968







-
+




















-
+







static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
  Table *pTab = pIndex->pTable;  /* The table that is indexed */
  int iTab = pParse->nTab++;     /* Btree cursor used for pTab */
  int iIdx = pParse->nTab++;     /* Btree cursor used for pIndex */
  int iSorter;                   /* Cursor opened by OpenSorter (if in use) */
  int addr1;                     /* Address of top of loop */
  int addr2;                     /* Address to jump to for next iteration */
  Pgno tnum;                     /* Root page of index */
  int tnum;                      /* Root page of index */
  int iPartIdxLabel;             /* Jump to this label to skip a row */
  Vdbe *v;                       /* Generate code into this virtual machine */
  KeyInfo *pKey;                 /* KeyInfo for index */
  int regRecord;                 /* Register holding assembled index record */
  sqlite3 *db = pParse->db;      /* The database connection */
  int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);

#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
      db->aDb[iDb].zDbSName ) ){
    return;
  }
#endif

  /* Require a write-lock on the table to perform this operation */
  sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);

  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;
  if( memRootPage>=0 ){
    tnum = (Pgno)memRootPage;
    tnum = memRootPage;
  }else{
    tnum = pIndex->tnum;
  }
  pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
  assert( pKey!=0 || db->mallocFailed || pParse->nErr );

  /* Open the sorter cursor if we are to use one. */
3477
3478
3479
3480
3481
3482
3483
3484

3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517

3518
3519
3520
3521
3522
3523
3524
3525
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







-
+













-
-
-
-
-
-
-
-



-
-
-
-
-
-
-
-
-
+
-








  sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
  sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
  sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
  sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v);
  sqlite3VdbeJumpHere(v, addr1);
  if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
  sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, (int)tnum, iDb, 
  sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
                    (char *)pKey, P4_KEYINFO);
  sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));

  addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
  if( IsUniqueIndex(pIndex) ){
    int j2 = sqlite3VdbeGoto(v, 1);
    addr2 = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeVerifyAbortable(v, OE_Abort);
    sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
                         pIndex->nKeyCol); VdbeCoverage(v);
    sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
    sqlite3VdbeJumpHere(v, j2);
  }else{
    /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not
    ** abort. The exception is if one of the indexed expressions contains a
    ** user function that throws an exception when it is evaluated. But the
    ** overhead of adding a statement journal to a CREATE INDEX statement is
    ** very small (since most of the pages written do not contain content that
    ** needs to be restored if the statement aborts), so we call 
    ** sqlite3MayAbort() for all CREATE INDEX statements.  */
    sqlite3MayAbort(pParse);
    addr2 = sqlite3VdbeCurrentAddr(v);
  }
  sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
  if( !pIndex->bAscKeyBug ){
    /* This OP_SeekEnd opcode makes index insert for a REINDEX go much
    ** faster by avoiding unnecessary seeks.  But the optimization does
    ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables
    ** with DESC primary keys, since those indexes have there keys in
    ** a different order from the main table.
    ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf
    */
    sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
  sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
  }
  sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
  sqlite3VdbeJumpHere(v, addr1);

  sqlite3VdbeAddOp1(v, OP_Close, iTab);
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3043
3044
3045
3046
3047
3048
3049





















3050
3051
3052
3053
3054
3055
3056







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







    p->nColumn = nCol;
    p->nKeyCol = nCol - 1;
    *ppExtra = ((char*)p) + nByte;
  }
  return p;
}

/*
** If expression list pList contains an expression that was parsed with
** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in
** pParse and return non-zero. Otherwise, return zero.
*/
int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){
  if( pList ){
    int i;
    for(i=0; i<pList->nExpr; i++){
      if( pList->a[i].bNulls ){
        u8 sf = pList->a[i].sortFlags;
        sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", 
            (sf==0 || sf==3) ? "FIRST" : "LAST"
        );
        return 1;
      }
    }
  }
  return 0;
}

/*
** Create a new index for an SQL table.  pName1.pName2 is the name of the index 
** and pTblList is the name of the table that is to be indexed.  Both will 
** be NULL for a primary key or an index that is created to satisfy a
** UNIQUE constraint.  If pTable and pIndex are NULL, use pParse->pNewTable
** as the table to be indexed.  pParse->pNewTable is a table that is
** currently being constructed by a CREATE TABLE statement.
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3094
3095
3096
3097
3098
3099
3100



3101
3102
3103
3104
3105
3106
3107







-
-
-







  }
  if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
    goto exit_create_index;
  }
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto exit_create_index;
  }
  if( sqlite3HasExplicitNulls(pParse, pList) ){
    goto exit_create_index;
  }

  /*
  ** Find the table that is to be indexed.  Return early if not found.
  */
  if( pTblName!=0 ){

    /* Use the two-part index name to determine the database 
3694
3695
3696
3697
3698
3699
3700



3701

3702
3703
3704
3705
3706
3707
3708
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164

3165
3166
3167
3168
3169
3170
3171
3172







+
+
+
-
+







  assert( pParse->nErr==0 );
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 
       && db->init.busy==0
       && pTblName!=0
#if SQLITE_USER_AUTHENTICATION
       && sqlite3UserAuthTable(pTab->zName)==0
#endif
#ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX
       && sqlite3StrICmp(&pTab->zName[7],"master")!=0
#endif
  ){
 ){
    sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
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
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







-
+











-
+







#endif

  /*
  ** Find the name of the index.  Make sure there is not already another
  ** index or table with the same name.  
  **
  ** Exception:  If we are reading the names of permanent indices from the
  ** sqlite_schema table (because some other process changed the schema) and
  ** sqlite_master table (because some other process changed the schema) and
  ** one of the index names collides with the name of a temporary table or
  ** index, then we will continue to process this index.
  **
  ** If pName==0 it means that we are
  ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  ** own name.
  */
  if( pName ){
    zName = sqlite3NameFromToken(db, pName);
    if( zName==0 ) goto exit_create_index;
    assert( pName->z!=0 );
    if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){
    if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
      goto exit_create_index;
    }
    if( !IN_RENAME_OBJECT ){
      if( !db->init.busy ){
        if( sqlite3FindTable(db, zName, 0)!=0 ){
          sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
          goto exit_create_index;
3794
3795
3796
3797
3798
3799
3800
3801

3802
3803
3804
3805
3806
3807
3808
3258
3259
3260
3261
3262
3263
3264

3265
3266
3267
3268
3269
3270
3271
3272







-
+







    Column *pCol = &pTab->aCol[pTab->nCol-1];
    pCol->colFlags |= COLFLAG_UNIQUE;
    sqlite3TokenInit(&prevCol, pCol->zName);
    pList = sqlite3ExprListAppend(pParse, 0,
              sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
    if( pList==0 ) goto exit_create_index;
    assert( pList->nExpr==1 );
    sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED);
    sqlite3ExprListSetSortOrder(pList, sortOrder);
  }else{
    sqlite3ExprListCheckLength(pParse, pList, "index");
    if( pParse->nErr ) goto exit_create_index;
  }

  /* Figure out how many bytes of space are required to store explicitly
  ** specified collation sequence names.
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898


3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3353
3354
3355
3356
3357
3358
3359



3360
3361




3362
3363
3364
3365
3366
3367
3368







-
-
-
+
+
-
-
-
-







      pIndex->aiColumn[i] = XN_EXPR;
      pIndex->uniqNotNull = 0;
    }else{
      j = pCExpr->iColumn;
      assert( j<=0x7fff );
      if( j<0 ){
        j = pTab->iPKey;
      }else{
        if( pTab->aCol[j].notNull==0 ){
          pIndex->uniqNotNull = 0;
      }else if( pTab->aCol[j].notNull==0 ){
        pIndex->uniqNotNull = 0;
        }
        if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){
          pIndex->bHasVCol = 1;
        }
      }
      pIndex->aiColumn[i] = (i16)j;
    }
    zColl = 0;
    if( pListItem->pExpr->op==TK_COLLATE ){
      int nColl;
      zColl = pListItem->pExpr->u.zToken;
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
3376
3377
3378
3379
3380
3381
3382

3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394

3395
3396
3397

3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414

3415
3416
3417
3418
3419
3420

3421
3422
3423
3424
3425
3426
3427
3428







-
+











-
+


-

















-
+





-
+







      zColl = pTab->aCol[j].zColl;
    }
    if( !zColl ) zColl = sqlite3StrBINARY;
    if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
      goto exit_create_index;
    }
    pIndex->azColl[i] = zColl;
    requestedSortOrder = pListItem->sortFlags & sortOrderMask;
    requestedSortOrder = pListItem->sortOrder & sortOrderMask;
    pIndex->aSortOrder[i] = (u8)requestedSortOrder;
  }

  /* Append the table key to the end of the index.  For WITHOUT ROWID
  ** tables (when pPk!=0) this will be the declared PRIMARY KEY.  For
  ** normal tables (when pPk==0) this will be the rowid.
  */
  if( pPk ){
    for(j=0; j<pPk->nKeyCol; j++){
      int x = pPk->aiColumn[j];
      assert( x>=0 );
      if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
      if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
        pIndex->nColumn--; 
      }else{
        testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
        pIndex->aiColumn[i] = x;
        pIndex->azColl[i] = pPk->azColl[j];
        pIndex->aSortOrder[i] = pPk->aSortOrder[j];
        i++;
      }
    }
    assert( i==pIndex->nColumn );
  }else{
    pIndex->aiColumn[i] = XN_ROWID;
    pIndex->azColl[i] = sqlite3StrBINARY;
  }
  sqlite3DefaultRowEst(pIndex);
  if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);

  /* If this index contains every column of its table, then mark
  ** it as a covering index */
  assert( HasRowid(pTab) 
      || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 );
      || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
  recomputeColumnsNotIndexed(pIndex);
  if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
    pIndex->isCovering = 1;
    for(j=0; j<pTab->nCol; j++){
      if( j==pTab->iPKey ) continue;
      if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue;
      if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue;
      pIndex->isCovering = 0;
      break;
    }
  }

  if( pTab==pParse->pNewTable ){
    /* This routine has been called to create an automatic index as a
4060
4061
4062
4063
4064
4065
4066
4067
4068


4069
4070
4071
4072
4073
4074
4075
3518
3519
3520
3521
3522
3523
3524


3525
3526
3527
3528
3529
3530
3531
3532
3533







-
-
+
+







      }
      db->mDbFlags |= DBFLAG_SchemaChange;
    }

    /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
    ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
    ** emit code to allocate the index rootpage on disk and make an entry for
    ** the index in the sqlite_schema table and populate the index with
    ** content.  But, do not do this if we are simply reading the sqlite_schema
    ** the index in the sqlite_master table and populate the index with
    ** content.  But, do not do this if we are simply reading the sqlite_master
    ** table to parse the schema, or if this index is the PRIMARY KEY index
    ** of a WITHOUT ROWID table.
    **
    ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
    ** or UNIQUE index in a CREATE TABLE statement.  Since the table
    ** has just been created, it contains no data and the index initialization
    ** step can be skipped.
4086
4087
4088
4089
4090
4091
4092
4093

4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112

4113
4114
4115
4116


4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131

4132
4133
4134
4135

4136
4137







4138


4139
4140










4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
3544
3545
3546
3547
3548
3549
3550

3551
3552
3553
3554
3555
3556

3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568

3569
3570
3571


3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587

3588
3589
3590
3591

3592
3593
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







-
+





-












-
+


-
-
+
+














-
+



-
+


+
+
+
+
+
+
+

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











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








      /* Create the rootpage for the index using CreateIndex. But before
      ** doing so, code a Noop instruction and store its address in 
      ** Index.tnum. This is required in case this index is actually a 
      ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In 
      ** that case the convertToWithoutRowidTable() routine will replace
      ** the Noop with a Goto to jump over the VDBE code generated below. */
      pIndex->tnum = (Pgno)sqlite3VdbeAddOp0(v, OP_Noop);
      pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
      sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY);

      /* Gather the complete text of the CREATE INDEX statement into
      ** the zStmt variable
      */
      assert( pName!=0 || pStart==0 );
      if( pStart ){
        int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
        if( pName->z[n-1]==';' ) n--;
        /* A named index with an explicit CREATE INDEX statement */
        zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
            onError==OE_None ? "" : " UNIQUE", n, pName->z);
      }else{
        /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
        /* zStmt = sqlite3MPrintf(""); */
        zStmt = 0;
      }

      /* Add an entry in sqlite_schema for this index
      /* Add an entry in sqlite_master for this index
      */
      sqlite3NestedParse(pParse, 
          "INSERT INTO %Q." DFLT_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
          db->aDb[iDb].zDbSName,
          "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
          db->aDb[iDb].zDbSName, MASTER_NAME,
          pIndex->zName,
          pTab->zName,
          iMem,
          zStmt
          );
      sqlite3DbFree(db, zStmt);

      /* 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);
            sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
        sqlite3VdbeAddOp2(v, OP_Expire, 0, 1);
      }

      sqlite3VdbeJumpHere(v, (int)pIndex->tnum);
      sqlite3VdbeJumpHere(v, pIndex->tnum);
    }
  }

  /* When adding an index to the list of indices for a table, make
  ** sure all indices labeled OE_Replace come after all those labeled
  ** OE_Ignore.  This is necessary for the correct constraint check
  ** processing (in sqlite3GenerateConstraintChecks()) as part of
  ** UPDATE and INSERT statements.  
  */
  if( db->init.busy || pTblName==0 ){
    if( onError!=OE_Replace || pTab->pIndex==0
         || pTab->pIndex->onError==OE_Replace){
    pIndex->pNext = pTab->pIndex;
    pTab->pIndex = pIndex;
      pIndex->pNext = pTab->pIndex;
      pTab->pIndex = pIndex;
    }else{
      Index *pOther = pTab->pIndex;
      while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
        pOther = pOther->pNext;
      }
      pIndex->pNext = pOther->pNext;
      pOther->pNext = pIndex;
    }
    pIndex = 0;
  }
  else if( IN_RENAME_OBJECT ){
    assert( pParse->pNewIndex==0 );
    pParse->pNewIndex = pIndex;
    pIndex = 0;
  }

  /* Clean up before exiting */
exit_create_index:
  if( pIndex ) sqlite3FreeIndex(db, pIndex);
  if( pTab ){
    /* Ensure all REPLACE indexes on pTab are at the end of the pIndex list.
    ** The list was already ordered when this routine was entered, so at this
    ** point at most a single index (the newly added index) will be out of
    ** order.  So we have to reorder at most one index. */
    Index **ppFrom = &pTab->pIndex;
    Index *pThis;
    for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){
      Index *pNext;
      if( pThis->onError!=OE_Replace ) continue;
      while( (pNext = pThis->pNext)!=0 && pNext->onError!=OE_Replace ){
        *ppFrom = pNext;
        pThis->pNext = pNext->pNext;
        pNext->pNext = pThis;
        ppFrom = &pNext->pNext;
      }
      break;
    }
#ifdef SQLITE_DEBUG
    /* Verify that all REPLACE indexes really are now at the end
    ** of the index list.  In other words, no other index type ever
    ** comes after a REPLACE index on the list. */
    for(pThis = pTab->pIndex; pThis; pThis=pThis->pNext){
      assert( pThis->onError!=OE_Replace
           || pThis->pNext==0
           || pThis->pNext->onError==OE_Replace );
    }
#endif
  }
  sqlite3ExprDelete(db, pPIWhere);
  sqlite3ExprListDelete(db, pList);
  sqlite3SrcListDelete(db, pTblName);
  sqlite3DbFree(db, zName);
}

/*
4199
4200
4201
4202
4203
4204
4205
4206
4207


4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218

4219
4220
4221
4222
4223
4224
4225
4226

4227
4228
4229
4230
4231
4232


4233
4234
4235
4236
4237
4238
4239
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







-
-
+
+

-








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







**           aiRowEst[N]>=1
**
** Apart from that, we have little to go on besides intuition as to
** how aiRowEst[] should be initialized.  The numbers generated here
** are based on typical values found in actual indices.
*/
void sqlite3DefaultRowEst(Index *pIdx){
               /*                10,  9,  8,  7,  6 */
  static const LogEst aVal[] = { 33, 32, 30, 28, 26 };
  /*                10,  9,  8,  7,  6 */
  LogEst aVal[] = { 33, 32, 30, 28, 26 };
  LogEst *a = pIdx->aiRowLogEst;
  LogEst x;
  int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
  int i;

  /* Indexes with default row estimates should not have stat1 data */
  assert( !pIdx->hasStat1 );

  /* Set the first entry (number of rows in the index) to the estimated 
  ** number of rows in the table, or half the number of rows in the table
  ** for a partial index.
  ** for a partial index.   But do not let the estimate drop below 10. */
  **
  ** 2020-05-27:  If some of the stat data is coming from the sqlite_stat1
  ** table but other parts we are having to guess at, then do not let the
  ** estimated number of rows in the table be less than 1000 (LogEst 99).
  ** Failure to do this can cause the indexes for which we do not have
  ** stat1 data to be ignored by the query planner.
  */
  x = pIdx->pTable->nRowLogEst;
  a[0] = pIdx->pTable->nRowLogEst;
  assert( 99==sqlite3LogEst(1000) );
  if( x<99 ){
    pIdx->pTable->nRowLogEst = x = 99;
  }
  if( pIdx->pPartIdxWhere!=0 ) x -= 10;  assert( 10==sqlite3LogEst(2) );
  a[0] = x;
  if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10;  assert( 10==sqlite3LogEst(2) );
  if( a[0]<33 ) a[0] = 33;                  assert( 33==sqlite3LogEst(10) );

  /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
  ** 6 and each subsequent value (if any) is 5.  */
  memcpy(&a[1], aVal, nCopy*sizeof(LogEst));
  for(i=nCopy+1; i<=pIdx->nKeyCol; i++){
    a[i] = 23;                    assert( 23==sqlite3LogEst(5) );
  }
4288
4289
4290
4291
4292
4293
4294
4295

4296
4297
4298
4299
4300
4301


4302
4303
4304
4305
4306
4307
4308
3721
3722
3723
3724
3725
3726
3727

3728
3729
3730
3731
3732


3733
3734
3735
3736
3737
3738
3739
3740
3741







-
+




-
-
+
+







    if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX;
    if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
      goto exit_drop_index;
    }
  }
#endif

  /* Generate code to remove the index and from the schema table */
  /* Generate code to remove the index and from the master table */
  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3BeginWriteOperation(pParse, 1, iDb);
    sqlite3NestedParse(pParse,
       "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
       db->aDb[iDb].zDbSName, pIndex->zName
       "DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
       db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName
    );
    sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
    sqlite3ChangeCookie(pParse, iDb);
    destroyRootPage(pParse, pIndex->tnum, iDb);
    sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0);
  }

4531
4532
4533
4534
4535
4536
4537
4538

4539
4540
4541
4542
4543
4544
4545
3964
3965
3966
3967
3968
3969
3970

3971
3972
3973
3974
3975
3976
3977
3978







-
+







*/
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;
  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) );
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
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







-
+



-
+













-
+


-
+

-
+



-
-
-
+
+
+







}

/*
** Assign VdbeCursor index numbers to all tables in a SrcList
*/
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
  int i;
  SrcItem *pItem;
  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;
      if( pItem->iCursor>=0 ) break;
      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;
  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->zDatabase);
    sqlite3DbFree(db, pItem->zName);
    if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
    sqlite3DbFree(db, pItem->zAlias);
    if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
    if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
    sqlite3DeleteTable(db, pItem->pTab);
    if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
    if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn);
    if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing);
    sqlite3SelectDelete(db, pItem->pSelect);
    sqlite3ExprDelete(db, pItem->pOn);
    sqlite3IdListDelete(db, pItem->pUsing);
  }
  sqlite3DbFreeNN(db, pList);
}

/*
** This routine is called by the parser to add a new term to the
** end of a growing FROM clause.  The "p" parameter is the part of
4632
4633
4634
4635
4636
4637
4638
4639

4640
4641
4642
4643
4644
4645
4646
4065
4066
4067
4068
4069
4070
4071

4072
4073
4074
4075
4076
4077
4078
4079







-
+







  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;
  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;
  }
4676
4677
4678
4679
4680
4681
4682
4683

4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726

4727
4728
4729
4730
4731
4732
4733
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







-
+
















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






-
+







/*
** 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;
    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 
      ** construct "indexed_opt" for details. */
      pItem->fg.notIndexed = 1;
    }else{
      pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
      pItem->fg.isIndexedBy = 1;
    }
  }
}

/*
** Append the contents of SrcList p2 to SrcList p1 and return the resulting
** SrcList. Or, if an error occurs, return NULL. In all cases, p1 and p2
** are deleted by this function.
*/ 
SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){
  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];
    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);
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789

4790
4791
4792
4793
4794
4795
4796
4186
4187
4188
4189
4190
4191
4192










4193
4194
4195
4196
4197
4198
4199
4200







-
-
-
-
-
-
-
-
-
-
+







  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
    return;
  }
  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  if( type!=TK_DEFERRED ){
    for(i=0; i<db->nDb; i++){
      int eTxnType;
      Btree *pBt = db->aDb[i].pBt;
      if( pBt && sqlite3BtreeIsReadonly(pBt) ){
        eTxnType = 0;  /* Read txn */
      }else if( type==TK_EXCLUSIVE ){
        eTxnType = 2;  /* Exclusive txn */
      }else{
        eTxnType = 1;  /* Write txn */
      }
      sqlite3VdbeAddOp2(v, OP_Transaction, i, eTxnType);
      sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
      sqlite3VdbeUsesBtree(v, i);
    }
  }
  sqlite3VdbeAddOp0(v, OP_AutoCommit);
}

/*
4857
4858
4859
4860
4861
4862
4863
4864

4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882







4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
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
4293
4294
4295




4296
4297
4298
4299
4300
4301
4302







-
+













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







-
-
-
-







      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
        "file for storing temporary tables");
      pParse->rc = rc;
      return 1;
    }
    db->aDb[1].pBt = pBt;
    assert( db->aDb[1].pSchema );
    if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){
    if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
      sqlite3OomFault(db);
      return 1;
    }
  }
  return 0;
}

/*
** Record the fact that the schema cookie will need to be verified
** 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) );
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);

  assert( iDb>=0 && iDb<pParse->db->nDb );
  assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
  assert( iDb<SQLITE_MAX_ATTACHED+2 );
  assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
  if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
    DbMaskSet(pToplevel->cookieMask, iDb);
    if( !OMIT_TEMPDB && iDb==1 ){
      sqlite3OpenTempDatabase(pToplevel);
    }
  }
}
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  sqlite3CodeVerifySchemaAtToplevel(sqlite3ParseToplevel(pParse), iDb);
}


/*
** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each 
** attached database. Otherwise, invoke it for the database named zDb only.
*/
void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
  sqlite3 *db = pParse->db;
4918
4919
4920
4921
4922
4923
4924
4925

4926
4927
4928
4929
4930
4931
4932
4320
4321
4322
4323
4324
4325
4326

4327
4328
4329
4330
4331
4332
4333
4334







-
+







** the way through and which will need to undo some writes without having to
** rollback the whole transaction.  For operations where all constraints
** can be checked before any changes are made to the database, it is never
** necessary to undo a write and the checkpoint should not be set.
*/
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  sqlite3CodeVerifySchemaAtToplevel(pToplevel, iDb);
  sqlite3CodeVerifySchema(pParse, iDb);
  DbMaskSet(pToplevel->writeMask, iDb);
  pToplevel->isMultiWrite |= setStatement;
}

/*
** Indicate that the statement currently under construction might write
** more than one entry (example: deleting one row then inserting another,
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979


4980
4981
4982
4983
4984
4985
4986
4371
4372
4373
4374
4375
4376
4377




4378
4379
4380
4381
4382
4383
4384
4385
4386







-
-
-
-
+
+







  Parse *pParse,    /* Parsing context */
  int errCode,      /* extended error code */
  int onError,      /* Constraint type */
  char *p4,         /* Error message */
  i8 p4type,        /* P4_STATIC or P4_TRANSIENT */
  u8 p5Errmsg       /* P5_ErrMsg type */
){
  Vdbe *v;
  assert( pParse->pVdbe!=0 );
  v = sqlite3GetVdbe(pParse);
  assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
  Vdbe *v = sqlite3GetVdbe(pParse);
  assert( (errCode&0xff)==SQLITE_CONSTRAINT );
  if( onError==OE_Abort ){
    sqlite3MayAbort(pParse);
  }
  sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
  sqlite3VdbeChangeP5(v, p5Errmsg);
}

5192
5193
5194
5195
5196
5197
5198
5199

5200
5201
5202
5203
5204
5205
5206
5207
4592
4593
4594
4595
4596
4597
4598

4599

4600
4601
4602
4603
4604
4605
4606







-
+
-







  }
  if( pKey ){
    assert( sqlite3KeyInfoIsWriteable(pKey) );
    for(i=0; i<nCol; i++){
      const char *zColl = pIdx->azColl[i];
      pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
                        sqlite3LocateCollSeq(pParse, zColl);
      pKey->aSortFlags[i] = pIdx->aSortOrder[i];
      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
      assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) );
    }
    if( pParse->nErr ){
      assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
      if( pIdx->bNoQuery==0 ){
        /* Deactivate the index because it contains an unknown collating
        ** sequence.  The only way to reactive the index is to reload the
        ** schema.  Adding the missing collating sequence later does not
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
5322
5323
5324
5325
5326
5327
5328




5329
5330
5331
5332
5333
4615
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
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







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

-
+
-
-




-
+
+
+





-
-
-
-


-
+


















+
-
+
+


+
+
+
-
-
+
+












-
+
+
+
+





      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
** WITH clause. 
** 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 */
  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;

  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;
  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);
    sqlite3CteDelete(db, pCte);
    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++] = *pCte;
    sqlite3DbFree(db, pCte);
    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++){
      cteClear(db, &pWith->a[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) */

Changes to src/callback.c.

60
61
62
63
64
65
66













































67
68
69
70
71
72
73
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







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







      memcpy(pColl, pColl2, sizeof(CollSeq));
      pColl->xDel = 0;         /* Do not copy the destructor */
      return SQLITE_OK;
    }
  }
  return SQLITE_ERROR;
}

/*
** This function is responsible for invoking the collation factory callback
** or substituting a collation sequence of a different encoding when the
** requested collation sequence is not available in the desired encoding.
** 
** If it is not NULL, then pColl must point to the database native encoding 
** collation sequence with name zName, length nName.
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.  If no collation is found, leave an error message.
**
** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
CollSeq *sqlite3GetCollSeq(
  Parse *pParse,        /* Parsing context */
  u8 enc,               /* The desired encoding for the collating sequence */
  CollSeq *pColl,       /* Collating sequence with native encoding, or NULL */
  const char *zName     /* Collating sequence name */
){
  CollSeq *p;
  sqlite3 *db = pParse->db;

  p = pColl;
  if( !p ){
    p = sqlite3FindCollSeq(db, enc, zName, 0);
  }
  if( !p || !p->xCmp ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(db, enc, zName);
    p = sqlite3FindCollSeq(db, enc, zName, 0);
  }
  if( p && !p->xCmp && synthCollSeq(db, p) ){
    p = 0;
  }
  assert( !p || p->xCmp );
  if( p==0 ){
    sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
    pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ;
  }
  return p;
}

/*
** This routine is called on a collation sequence before it is used to
** check that it is defined. An undefined collation sequence exists when
** a database is loaded that contains references to collation sequences
** that have not been defined by sqlite3_create_collation() etc.
**
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
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







-
-
-
-
+
+
+
+


-
-


-



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







** this routine.  sqlite3LocateCollSeq() invokes the collation factory
** if necessary and generates an error message if the collating sequence
** cannot be found.
**
** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
*/
CollSeq *sqlite3FindCollSeq(
  sqlite3 *db,          /* Database connection to search */
  u8 enc,               /* Desired text encoding */
  const char *zName,    /* Name of the collating sequence.  Might be NULL */
  int create            /* True to create CollSeq if doesn't already exist */
  sqlite3 *db,
  u8 enc,
  const char *zName,
  int create
){
  CollSeq *pColl;
  assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
  assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
  if( zName ){
    pColl = findCollSeqEntry(db, zName, create);
    if( pColl ) pColl += enc-1;
  }else{
    pColl = db->pDfltColl;
  }
  return pColl;
}

  assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
/*
** Change the text encoding for a database connection. This means that
** the pDfltColl must change as well.
*/
void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){
  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
  db->enc = enc;
  /* EVIDENCE-OF: R-08308-17224 The default collating function for all
  ** strings is BINARY. 
  */
  db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0);
}

  assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
/*
** This function is responsible for invoking the collation factory callback
** or substituting a collation sequence of a different encoding when the
** requested collation sequence is not available in the desired encoding.
** 
** If it is not NULL, then pColl must point to the database native encoding 
** collation sequence with name zName, length nName.
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.  If no collation is found, leave an error message.
**
** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
CollSeq *sqlite3GetCollSeq(
  Parse *pParse,        /* Parsing context */
  u8 enc,               /* The desired encoding for the collating sequence */
  CollSeq *pColl,       /* Collating sequence with native encoding, or NULL */
  const char *zName     /* Collating sequence name */
){
  CollSeq *p;
  sqlite3 *db = pParse->db;

  if( pColl ) pColl += enc-1;
  p = pColl;
  if( !p ){
    p = sqlite3FindCollSeq(db, enc, zName, 0);
  }
  if( !p || !p->xCmp ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(db, enc, zName);
    p = sqlite3FindCollSeq(db, enc, zName, 0);
  }
  if( p && !p->xCmp && synthCollSeq(db, p) ){
    p = 0;
  }
  assert( !p || p->xCmp );
  if( p==0 ){
    sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
    pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ;
  }
  return p;
}

/*
** This function returns the collation sequence for database native text
** encoding identified by the string zName.
**
** If the requested collation sequence is not available, or not available
** in the database native encoding, the collation factory is invoked to
** request it. If the collation factory does not supply such a sequence,
** and the sequence is available in another text encoding, then that is
** returned instead.
**
** If no versions of the requested collations sequence are available, or
** another error occurs, NULL is returned and an error message written into
** pParse.
**
** This routine is a wrapper around sqlite3FindCollSeq().  This routine
** invokes the collation factory if the named collation cannot be found
** and generates an error message.
**
** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
*/
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
  sqlite3 *db = pParse->db;
  u8 enc = ENC(db);
  u8 initbusy = db->init.busy;
  CollSeq *pColl;

  pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
  if( !initbusy && (!pColl || !pColl->xCmp) ){
    pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
  }

  return pColl;
}

/* During the search for the best function definition, this procedure
** is called to test how well the function passed as the first argument
** matches the request for a function with nArg arguments in a system
** that uses encoding enc. The value returned indicates how well the
297
298
299
300
301
302
303
304
305
306
307
308


309
310



311
312
313
314
315
316
317
250
251
252
253
254
255
256

257



258
259


260
261
262
263
264
265
266
267
268
269







-

-
-
-
+
+
-
-
+
+
+







#define FUNC_PERFECT_MATCH 6  /* The score for a perfect match */
static int matchQuality(
  FuncDef *p,     /* The function we are evaluating for match quality */
  int nArg,       /* Desired number of arguments.  (-1)==any */
  u8 enc          /* Desired text encoding */
){
  int match;
  assert( p->nArg>=-1 );

  /* Wrong number of arguments means "no match" */
  if( p->nArg!=nArg ){
    if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH;
  /* nArg of -2 is a special case */
  if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH;
    if( p->nArg>=0 ) return 0;
  }

  /* Wrong number of arguments means "no match" */
  if( p->nArg!=nArg && p->nArg>=0 ) return 0;

  /* Give a better score to a function with a specific number of arguments
  ** than to function that accepts any number of arguments. */
  if( p->nArg==nArg ){
    match = 4;
  }else{
    match = 1;

Changes to src/ctime.c.

10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







**
*************************************************************************
**
** This file implements routines used to report what compile-time options
** SQLite was built with.
*/

#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* IMP: R-16824-07538 */
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
*/
#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H)
#include "config.h"
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
189
190
191
192
193
194
195



196
197
198
199
200
201
202







-
-
-







#endif
#if SQLITE_ENABLE_ATOMIC_WRITE
  "ENABLE_ATOMIC_WRITE",
#endif
#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
  "ENABLE_BATCH_ATOMIC_WRITE",
#endif
#if SQLITE_ENABLE_BYTECODE_VTAB
  "ENABLE_BYTECODE_VTAB",
#endif
#if SQLITE_ENABLE_CEROD
  "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
#endif
#if SQLITE_ENABLE_COLUMN_METADATA
  "ENABLE_COLUMN_METADATA",
#endif
#if SQLITE_ENABLE_COLUMN_USED_MASK
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
252
253
254
255
256
257
258



259
260
261
262
263
264
265







-
-
-







#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
#if SQLITE_ENABLE_MEMSYS5
308
309
310
311
312
313
314


315
316
317
318
319
320
321
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317







+
+







  "ENABLE_SORTER_REFERENCES",
#endif
#if SQLITE_ENABLE_SQLLOG
  "ENABLE_SQLLOG",
#endif
#if defined(SQLITE_ENABLE_STAT4)
  "ENABLE_STAT4",
#elif defined(SQLITE_ENABLE_STAT3)
  "ENABLE_STAT3",
#endif
#if SQLITE_ENABLE_STMTVTAB
  "ENABLE_STMTVTAB",
#endif
#if SQLITE_ENABLE_STMT_SCANSTATUS
  "ENABLE_STMT_SCANSTATUS",
#endif
356
357
358
359
360
361
362



363
364
365
366
367
368
369
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368







+
+
+







  "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH),
#endif
#if SQLITE_FTS5_ENABLE_TEST_MI
  "FTS5_ENABLE_TEST_MI",
#endif
#if SQLITE_FTS5_NO_WITHOUT_ROWID
  "FTS5_NO_WITHOUT_ROWID",
#endif
#if SQLITE_HAS_CODEC
  "HAS_CODEC",
#endif
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
  "HAVE_ISNAN",
#endif
#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  "HOMEGROWN_RECURSIVE_MUTEX",
#endif
512
513
514
515
516
517
518



519
520
521
522
523
524
525
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527







+
+
+







  "OMIT_AUTOVACUUM",
#endif
#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
  "OMIT_BETWEEN_OPTIMIZATION",
#endif
#if SQLITE_OMIT_BLOB_LITERAL
  "OMIT_BLOB_LITERAL",
#endif
#if SQLITE_OMIT_BTREECOUNT
  "OMIT_BTREECOUNT",
#endif
#if SQLITE_OMIT_CAST
  "OMIT_CAST",
#endif
#if SQLITE_OMIT_CHECK
  "OMIT_CHECK",
#endif

Changes to src/date.c.

384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398







-
+







  double r;
  if( parseYyyyMmDd(zDate,p)==0 ){
    return 0;
  }else if( parseHhMmSs(zDate, p)==0 ){
    return 0;
  }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
    return setDateTimeToCurrent(context, p);
  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
    setRawDateNumber(p, r);
    return 0;
  }
  return 1;
}

/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999.
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525







-
+







** local time.
*/
static int osLocaltime(time_t *t, struct tm *pTm){
  int rc;
#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
  struct tm *pX;
#if SQLITE_THREADSAFE>0
  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
  sqlite3_mutex_enter(mutex);
  pX = localtime(t);
#ifndef SQLITE_UNTESTABLE
  if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
#endif
  if( pX ) *pTm = *pX;
617
618
619
620
621
622
623
624
625
626
627
628
629






630
631
632
633
634
635
636
617
618
619
620
621
622
623






624
625
626
627
628
629
630
631
632
633
634
635
636







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







static const struct {
  u8 eType;           /* Transformation type code */
  u8 nName;           /* Length of th name */
  char *zName;        /* Name of the transformation */
  double rLimit;      /* Maximum NNN value for this transform */
  double rXform;      /* Constant used for this transform */
} aXformType[] = {
  { 0, 6, "second", 464269060800.0, 1000.0         },
  { 0, 6, "minute", 7737817680.0,   60000.0        },
  { 0, 4, "hour",   128963628.0,    3600000.0      },
  { 0, 3, "day",    5373485.0,      86400000.0     },
  { 1, 5, "month",  176546.0,       2592000000.0   },
  { 2, 4, "year",   14713.0,        31536000000.0  },
  { 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) },
  { 0, 6, "minute", 7737817680.0,   86400000.0/(24.0*60.0)      },
  { 0, 4, "hour",   128963628.0,    86400000.0/24.0             },
  { 0, 3, "day",    5373485.0,      86400000.0                  },
  { 1, 5, "month",  176546.0,       30.0*86400000.0             },
  { 2, 4, "year",   14713.0,        365.0*86400000.0            },
};

/*
** Process a modifier to a date-time stamp.  The modifiers are
** as follows:
**
**     NNN days
684
685
686
687
688
689
690
691

692
693
694
695
696
697
698
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698







-
+







      ** Treat the current value of p->s as the number of
      ** seconds since 1970.  Convert to a real julian day number.
      */
      if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
        r = p->s*1000.0 + 210866760000000.0;
        if( r>=0.0 && r<464269060800000.0 ){
          clearYMD_HMS_TZ(p);
          p->iJD = (sqlite3_int64)(r + 0.5);
          p->iJD = (sqlite3_int64)r;
          p->validJD = 1;
          p->rawS = 0;
          rc = 0;
        }
      }
#ifndef SQLITE_OMIT_LOCALTIME
      else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
718
719
720
721
722
723
724
725

726
727
728
729
730
731
732
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732







-
+







      **    weekday N
      **
      ** Move the date to the same time on the next occurrence of
      ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
      ** date is already on the appropriate weekday, this is a no-op.
      */
      if( sqlite3_strnicmp(z, "weekday ", 8)==0
               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
               && (n=(int)r)==r && n>=0 && r<7 ){
        sqlite3_int64 Z;
        computeYMD_HMS(p);
        p->validTZ = 0;
        p->validJD = 0;
        computeJD(p);
        Z = ((p->iJD + 129600000)/86400000) % 7;
777
778
779
780
781
782
783
784

785
786
787
788
789
790
791
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791







-
+







    case '6':
    case '7':
    case '8':
    case '9': {
      double rRounder;
      int i;
      for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
      if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
      if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
        rc = 1;
        break;
      }
      if( z[n]==':' ){
        /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
        ** specified number of hours, minutes, seconds, and fractional seconds
        ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
877
878
879
880
881
882
883

884
885
886
887
888
889
890







-







  DateTime *p
){
  int i, n;
  const unsigned char *z;
  int eType;
  memset(p, 0, sizeof(*p));
  if( argc==0 ){
    if( !sqlite3NotPureFunc(context) ) return 1;
    return setDateTimeToCurrent(context, p);
  }
  if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
                   || eType==SQLITE_INTEGER ){
    setRawDateNumber(p, sqlite3_value_double(argv[0]));
  }else{
    z = sqlite3_value_text(argv[0]);
1109
1110
1111
1112
1113
1114
1115

1116

1117
1118
1119
1120
1121
1122
1123
1124
1108
1109
1110
1111
1112
1113
1114
1115

1116

1117
1118
1119
1120
1121
1122
1123







+
-
+
-







          sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
          j+=sqlite3Strlen30(&z[j]);
          break;
        }
        case 'm':  sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
        case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
        case 's': {
          sqlite3_snprintf(30,&z[j],"%lld",
          i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000);
                           (i64)(x.iJD/1000 - 21086676*(i64)10000));
          sqlite3Int64ToText(iS, &z[j]);
          j += sqlite3Strlen30(&z[j]);
          break;
        }
        case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
        case 'w': {
          z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
          break;
1208
1209
1210
1211
1212
1213
1214
1215

1216
1217
1218

1219
1220
1221
1222
1223
1224
1225
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216

1217
1218
1219
1220
1221
1222
1223
1224







-
+


-
+








  iT = sqlite3StmtCurrentTime(context);
  if( iT<=0 ) return;
  t = iT/1000 - 10000*(sqlite3_int64)21086676;
#if HAVE_GMTIME_R
  pTm = gmtime_r(&t, &sNow);
#else
  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN));
  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  pTm = gmtime(&t);
  if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN));
  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
#endif
  if( pTm ){
    strftime(zBuf, 20, zFormat, &sNow);
    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  }
}
#endif

Changes to src/dbpage.c.

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
69
70
71
72
73
74
75

76
77
78
79
80
81
82







-







  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErr
){
  DbpageTable *pTab = 0;
  int rc = SQLITE_OK;

  sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
  rc = sqlite3_declare_vtab(db, 
          "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
  if( rc==SQLITE_OK ){
    pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
    if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
  }

Changes to src/dbstat.c.

8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains an implementation of the "dbstat" virtual table.
**
** The dbstat virtual table is used to extract low-level storage
** The dbstat virtual table is used to extract low-level formatting
** information from an SQLite database in order to implement the
** "sqlite3_analyzer" utility.  See the ../tool/spaceanal.tcl script
** for an example implementation.
**
** Additional information is available on the "dbstat.html" page of the
** official SQLite documentation.
*/
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
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







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

-





-









-

-
-
-
+
+
+









-
+


-

-
+

-
+
-


-
+



-


+

-

-
-
-
+
+
+

-
+


-

-
-
+
+








-
+







**
**   If the paths are sorted using the BINARY collation sequence, then
**   the overflow pages associated with a cell will appear earlier in the
**   sort-order than its child page:
**
**      '/1c2/000/'               // Left-most child of 451st child of root
*/
static const char zDbstatSchema[] = 
  "CREATE TABLE x("
  " name       TEXT,"          /*  0 Name of table or index */
  " path       TEXT,"          /*  1 Path to page from root (NULL for agg) */
  " pageno     INTEGER,"       /*  2 Page number (page count for aggregates) */
  " pagetype   TEXT,"          /*  3 'internal', 'leaf', 'overflow', or NULL */
  " ncell      INTEGER,"       /*  4 Cells on page (0 for overflow) */
  " payload    INTEGER,"       /*  5 Bytes of payload on this page */
  " unused     INTEGER,"       /*  6 Bytes of unused space on this page */
  " mx_payload INTEGER,"       /*  7 Largest payload size of all cells */
  " pgoffset   INTEGER,"       /*  8 Offset of page in file (NULL for agg) */
  " pgsize     INTEGER,"       /*  9 Size of the page (sum for aggregate) */
  " schema     TEXT HIDDEN,"   /* 10 Database schema being analyzed */
#define VTAB_SCHEMA                                                         \
  "CREATE TABLE xx( "                                                       \
  "  name       TEXT,             /* Name of table or index */"             \
  "  path       TEXT,             /* Path to page from root */"             \
  "  pageno     INTEGER,          /* Page number */"                        \
  "  pagetype   TEXT,             /* 'internal', 'leaf' or 'overflow' */"   \
  "  ncell      INTEGER,          /* Cells on page (0 for overflow) */"     \
  "  payload    INTEGER,          /* Bytes of payload on this page */"      \
  "  unused     INTEGER,          /* Bytes of unused space on this page */" \
  "  mx_payload INTEGER,          /* Largest payload size of all cells */"  \
  "  pgoffset   INTEGER,          /* Offset of page in file */"             \
  "  pgsize     INTEGER,          /* Size of the page */"                   \
  "  schema     TEXT HIDDEN       /* Database schema being analyzed */"     \
  " aggregate  BOOLEAN HIDDEN" /* 11 aggregate info for each table */
  ")"
;
  ");"


/* Forward reference to data structured used in this module */
typedef struct StatTable StatTable;
typedef struct StatCursor StatCursor;
typedef struct StatPage StatPage;
typedef struct StatCell StatCell;

/* Size information for a single cell within a btree page */
struct StatCell {
  int nLocal;                     /* Bytes of local payload */
  u32 iChildPg;                   /* Child node (or 0 if this is a leaf) */
  int nOvfl;                      /* Entries in aOvfl[] */
  u32 *aOvfl;                     /* Array of overflow page numbers */
  int nLastOvfl;                  /* Bytes of payload on final overflow page */
  int iOvfl;                      /* Iterates through aOvfl[] */
};

/* Size information for a single btree page */
struct StatPage {
  u32 iPgno;                      /* Page number */
  DbPage *pPg;                    /* Page content */
  int iCell;                      /* Current cell */
  u32 iPgno;
  DbPage *pPg;
  int iCell;

  char *zPath;                    /* Path to this page */

  /* Variables populated by statDecodePage(): */
  u8 flags;                       /* Copy of flags byte */
  int nCell;                      /* Number of cells on page */
  int nUnused;                    /* Number of unused bytes on page */
  StatCell *aCell;                /* Array of parsed cells */
  u32 iRightChildPg;              /* Right-child page number (or 0) */
  int nMxPayload;                 /* Largest payload of any cell on the page */
  int nMxPayload;                 /* Largest payload of any cell on this page */
};

/* The cursor for scanning the dbstat virtual table */
struct StatCursor {
  sqlite3_vtab_cursor base;       /* base class.  MUST BE FIRST! */
  sqlite3_vtab_cursor base;
  sqlite3_stmt *pStmt;            /* Iterates through set of root pages */
  u8 isEof;                       /* After pStmt has returned SQLITE_DONE */
  int isEof;                      /* After pStmt has returned SQLITE_DONE */
  u8 isAgg;                       /* Aggregate results for each table */
  int iDb;                        /* Schema used for this query */

  StatPage aPage[32];             /* Pages in path to current page */
  StatPage aPage[32];
  int iPage;                      /* Current entry in aPage[] */

  /* Values to return. */
  u32 iPageno;                    /* Value of 'pageno' column */
  char *zName;                    /* Value of 'name' column */
  char *zPath;                    /* Value of 'path' column */
  u32 iPageno;                    /* Value of 'pageno' column */
  char *zPagetype;                /* Value of 'pagetype' column */
  int nPage;                      /* Number of pages in current btree */
  int nCell;                      /* Value of 'ncell' column */
  int nMxPayload;                 /* Value of 'mx_payload' column */
  i64 nUnused;                    /* Value of 'unused' column */
  i64 nPayload;                   /* Value of 'payload' column */
  int nPayload;                   /* Value of 'payload' column */
  int nUnused;                    /* Value of 'unused' column */
  int nMxPayload;                 /* Value of 'mx_payload' column */
  i64 iOffset;                    /* Value of 'pgOffset' column */
  i64 szPage;                     /* Value of 'pgSize' column */
  int szPage;                     /* Value of 'pgSize' column */
};

/* An instance of the DBSTAT virtual table */
struct StatTable {
  sqlite3_vtab base;              /* base class.  MUST BE FIRST! */
  sqlite3 *db;                    /* Database connection that owns this vtab */
  sqlite3_vtab base;
  sqlite3 *db;
  int iDb;                        /* Index of database to analyze */
};

#ifndef get2byte
# define get2byte(x)   ((x)[0]<<8 | (x)[1])
#endif

/*
** Connect to or create a new DBSTAT virtual table.
** Connect to or create a statvfs virtual table.
*/
static int statConnect(
  sqlite3 *db,
  void *pAux,
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErr
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
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







-
-
+

















-
+







-
+
+
+

-
+
-
-
-
-
-



-
-
-







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

-
-
-
-
+
-

















-






-
+







    if( iDb<0 ){
      *pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
      return SQLITE_ERROR;
    }
  }else{
    iDb = 0;
  }
  sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
  rc = sqlite3_declare_vtab(db, zDbstatSchema);
  rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
  if( rc==SQLITE_OK ){
    pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
    if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
  }

  assert( rc==SQLITE_OK || pTab==0 );
  if( rc==SQLITE_OK ){
    memset(pTab, 0, sizeof(StatTable));
    pTab->db = db;
    pTab->iDb = iDb;
  }

  *ppVtab = (sqlite3_vtab*)pTab;
  return rc;
}

/*
** Disconnect from or destroy the DBSTAT virtual table.
** Disconnect from or destroy a statvfs virtual table.
*/
static int statDisconnect(sqlite3_vtab *pVtab){
  sqlite3_free(pVtab);
  return SQLITE_OK;
}

/*
** Compute the best query strategy and return the result in idxNum.
** There is no "best-index". This virtual table always does a linear
** scan.  However, a schema=? constraint should cause this table to
** operate on a different database schema, so check for it.
**
**   idxNum-Bit        Meaning
** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
**   ----------        ----------------------------------------------
**      0x01           There is a schema=? term in the WHERE clause
**      0x02           There is a name=? term in the WHERE clause
**      0x04           There is an aggregate=? term in the WHERE clause
**      0x08           Output should be ordered by name and path
*/
static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  int i;
  int iSchema = -1;
  int iName = -1;
  int iAgg = -1;

  /* Look for a valid schema=? constraint.  If found, change the idxNum to
  ** 1 and request the value of that constraint be sent to xFilter.  And
  ** lower the cost estimate to encourage the constrained version to be
  ** used.
  */
  for(i=0; i<pIdxInfo->nConstraint; i++){
    if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
    if( pIdxInfo->aConstraint[i].usable==0 ){
    if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
    if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT;
      /* Force DBSTAT table should always be the right-most table in a join */
      return SQLITE_CONSTRAINT;
    }
    switch( pIdxInfo->aConstraint[i].iColumn ){
    if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
      case 0: {    /* name */
        iName = i;
        break;
      }
      case 10: {   /* schema */
        iSchema = i;
        break;
      }
      case 11: {   /* aggregate */
        iAgg = i;
        break;
      }
    }
  }
  i = 0;
    pIdxInfo->idxNum = 1;
  if( iSchema>=0 ){
    pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i;
    pIdxInfo->aConstraintUsage[iSchema].omit = 1;
    pIdxInfo->estimatedCost = 1.0;
    pIdxInfo->aConstraintUsage[i].argvIndex = 1;
    pIdxInfo->idxNum |= 0x01;
  }
  if( iName>=0 ){
    pIdxInfo->aConstraintUsage[iName].argvIndex = ++i;
    pIdxInfo->aConstraintUsage[i].omit = 1;
    pIdxInfo->idxNum |= 0x02;
    break;
  }
  if( iAgg>=0 ){
    pIdxInfo->aConstraintUsage[iAgg].argvIndex = ++i;
    pIdxInfo->idxNum |= 0x04;
  }

  pIdxInfo->estimatedCost = 1.0;

  /* Records are always returned in ascending order of (name, path). 
  ** If this will satisfy the client, set the orderByConsumed flag so that 
  ** SQLite does not do an external sort.
  */
  if( ( pIdxInfo->nOrderBy==1
     && pIdxInfo->aOrderBy[0].iColumn==0
     && pIdxInfo->aOrderBy[0].desc==0
     ) ||
      ( pIdxInfo->nOrderBy==2
     && pIdxInfo->aOrderBy[0].iColumn==0
     && pIdxInfo->aOrderBy[0].desc==0
     && pIdxInfo->aOrderBy[1].iColumn==1
     && pIdxInfo->aOrderBy[1].desc==0
     )
  ){
    pIdxInfo->orderByConsumed = 1;
    pIdxInfo->idxNum |= 0x08;
  }

  return SQLITE_OK;
}

/*
** Open a new DBSTAT cursor.
** Open a new statvfs cursor.
*/
static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
  StatTable *pTab = (StatTable *)pVTab;
  StatCursor *pCsr;

  pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
  if( pCsr==0 ){
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
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







-
-
-
-
-
-
-
-
-
-

-
+









-
-
-
-
-
-
+


-
+
+















-
+


-
-
-







  }
  pCsr->iPage = 0;
  sqlite3_free(pCsr->zPath);
  pCsr->zPath = 0;
  pCsr->isEof = 0;
}

/* Resize the space-used counters inside of the cursor */
static void statResetCounts(StatCursor *pCsr){
  pCsr->nCell = 0;
  pCsr->nMxPayload = 0;
  pCsr->nUnused = 0;
  pCsr->nPayload = 0;
  pCsr->szPage = 0;
  pCsr->nPage = 0;
}

/*
** Close a DBSTAT cursor.
** Close a statvfs cursor.
*/
static int statClose(sqlite3_vtab_cursor *pCursor){
  StatCursor *pCsr = (StatCursor *)pCursor;
  statResetCsr(pCsr);
  sqlite3_finalize(pCsr->pStmt);
  sqlite3_free(pCsr);
  return SQLITE_OK;
}

/*
** For a single cell on a btree page, compute the number of bytes of
** content (payload) stored on that page.  That is to say, compute the
** number of bytes of content not found on overflow pages.
*/
static int getLocalPayload(
static void getLocalPayload(
  int nUsable,                    /* Usable bytes per page */
  u8 flags,                       /* Page flags */
  int nTotal                      /* Total record (payload) size */
  int nTotal,                     /* Total record (payload) size */
  int *pnLocal                    /* OUT: Bytes stored locally */
){
  int nLocal;
  int nMinLocal;
  int nMaxLocal;
 
  if( flags==0x0D ){              /* Table leaf node */
    nMinLocal = (nUsable - 12) * 32 / 255 - 23;
    nMaxLocal = nUsable - 35;
  }else{                          /* Index interior and leaf nodes */
    nMinLocal = (nUsable - 12) * 32 / 255 - 23;
    nMaxLocal = (nUsable - 12) * 64 / 255 - 23;
  }

  nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4);
  if( nLocal>nMaxLocal ) nLocal = nMinLocal;
  return nLocal;
  *pnLocal = nLocal;
}

/* Populate the StatPage object with information about the all
** cells found on the page currently under analysis.
*/
static int statDecodePage(Btree *pBt, StatPage *p){
  int nUnused;
  int iOff;
  int nHdr;
  int isLeaf;
  int szPage;

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
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397


398

399
400
401
402
403
404
405







-
+







-
-
+
-







        int nLocal;               /* Bytes of payload stored locally */
        iOff += getVarint32(&aData[iOff], nPayload);
        if( p->flags==0x0D ){
          u64 dummy;
          iOff += sqlite3GetVarint(&aData[iOff], &dummy);
        }
        if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
        nLocal = getLocalPayload(nUsable, p->flags, nPayload);
        getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
        if( nLocal<0 ) goto statPageIsCorrupt;
        pCell->nLocal = nLocal;
        assert( nPayload>=(u32)nLocal );
        assert( nLocal<=(nUsable-35) );
        if( nPayload>(u32)nLocal ){
          int j;
          int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
          if( iOff+nLocal>nUsable || nPayload>0x7fffffff ){
            goto statPageIsCorrupt;
          if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
          }
          pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
          pCell->nOvfl = nOvfl;
          pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
          if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
          pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
          for(j=1; j<nOvfl; j++){
            int rc;
493
494
495
496
497
498
499




500
501


502
503
504
505
506
507

508
509
510
511
512
513
514
515
516

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

550
551
552
553

554
555
556
557
558
559


560
561

562
563
564
565


566
567
568
569



570
571





572

573

574
575
576


577
578
579
580

581
582
583
584
585
586
587

588
589
590
591
592
593
594
595
596
597


598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621

622
623
624

625
626
627
628
629
630
631
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







+
+
+
+
-
-
+
+





-
+
-
-
-
-




-
+
-
-















-
-












-
-
+
-
-

-
+





-
+
+

-
+


-
-
+
+




+
+
+
-
-
+
+
+
+
+

+
-
+

-
-
+
+

-

-
+
-
-
-
-
-
-
-
+
-







-
-
+
+
-
-
-
-
-















-

-
-
+
-
-

+







static void statSizeAndOffset(StatCursor *pCsr){
  StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
  Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
  Pager *pPager = sqlite3BtreePager(pBt);
  sqlite3_file *fd;
  sqlite3_int64 x[2];

  /* The default page size and offset */
  pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
  pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);

  /* If connected to a ZIPVFS backend, find the page size and
  ** offset from ZIPVFS.
  /* If connected to a ZIPVFS backend, override the page size and
  ** offset with actual values obtained from ZIPVFS.
  */
  fd = sqlite3PagerFile(pPager);
  x[0] = pCsr->iPageno;
  if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
    pCsr->iOffset = x[0];
    pCsr->szPage += x[1];
    pCsr->szPage = (int)x[1];
  }else{
    /* Not ZIPVFS: The default page size and offset */
    pCsr->szPage += sqlite3BtreeGetPageSize(pBt);
    pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
  }
}

/*
** Move a DBSTAT cursor to the next entry.  Normally, the next
** Move a statvfs cursor to the next entry in the file.
** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0),
** the next entry is the next btree.
*/
static int statNext(sqlite3_vtab_cursor *pCursor){
  int rc;
  int nPayload;
  char *z;
  StatCursor *pCsr = (StatCursor *)pCursor;
  StatTable *pTab = (StatTable *)pCursor->pVtab;
  Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
  Pager *pPager = sqlite3BtreePager(pBt);

  sqlite3_free(pCsr->zPath);
  pCsr->zPath = 0;

statNextRestart:
  if( pCsr->aPage[0].pPg==0 ){
    /* Start measuring space on the next btree */
    statResetCounts(pCsr);
    rc = sqlite3_step(pCsr->pStmt);
    if( rc==SQLITE_ROW ){
      int nPage;
      u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
      sqlite3PagerPagecount(pPager, &nPage);
      if( nPage==0 ){
        pCsr->isEof = 1;
        return sqlite3_reset(pCsr->pStmt);
      }
      rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0);
      pCsr->aPage[0].iPgno = iRoot;
      pCsr->aPage[0].iCell = 0;
      if( !pCsr->isAgg ){
        pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
      pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
        if( z==0 ) rc = SQLITE_NOMEM_BKPT;
      }
      pCsr->iPage = 0;
      pCsr->nPage = 1;
      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
    }else{
      pCsr->isEof = 1;
      return sqlite3_reset(pCsr->pStmt);
    }
  }else{
    /* Continue analyzing the btree previously started */

    /* Page p itself has already been visited. */
    StatPage *p = &pCsr->aPage[pCsr->iPage];
    if( !pCsr->isAgg ) statResetCounts(pCsr);

    while( p->iCell<p->nCell ){
      StatCell *pCell = &p->aCell[p->iCell];
      while( pCell->iOvfl<pCell->nOvfl ){
        int nUsable, iOvfl;
      if( pCell->iOvfl<pCell->nOvfl ){
        int nUsable;
        sqlite3BtreeEnter(pBt);
        nUsable = sqlite3BtreeGetPageSize(pBt) - 
                        sqlite3BtreeGetReserveNoMutex(pBt);
        sqlite3BtreeLeave(pBt);
        pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
        pCsr->iPageno = pCell->aOvfl[pCell->iOvfl];
        pCsr->zPagetype = "overflow";
        pCsr->nPage++;
        statSizeAndOffset(pCsr);
        pCsr->nCell = 0;
        pCsr->nMxPayload = 0;
        pCsr->zPath = z = sqlite3_mprintf(
            "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
        );
        if( pCell->iOvfl<pCell->nOvfl-1 ){
          pCsr->nUnused = 0;
          pCsr->nPayload += nUsable - 4;
          pCsr->nPayload = nUsable - 4;
        }else{
          pCsr->nPayload += pCell->nLastOvfl;
          pCsr->nUnused += nUsable - 4 - pCell->nLastOvfl;
          pCsr->nPayload = pCell->nLastOvfl;
          pCsr->nUnused = nUsable - 4 - pCsr->nPayload;
        }
        iOvfl = pCell->iOvfl;
        pCell->iOvfl++;
        if( !pCsr->isAgg ){
        statSizeAndOffset(pCsr);
          pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
          pCsr->iPageno = pCell->aOvfl[iOvfl];
          pCsr->zPagetype = "overflow";
          pCsr->zPath = z = sqlite3_mprintf(
              "%s%.3x+%.6x", p->zPath, p->iCell, iOvfl
          );
          return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
        return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
        }
      }
      if( p->iRightChildPg ) break;
      p->iCell++;
    }

    if( !p->iRightChildPg || p->iCell>p->nCell ){
      statClearPage(p);
      if( pCsr->iPage>0 ){
        pCsr->iPage--;
      if( pCsr->iPage==0 ) return statNext(pCursor);
      pCsr->iPage--;
      }else if( pCsr->isAgg ){
        /* label-statNext-done:  When computing aggregate space usage over
        ** an entire btree, this is the exit point from this function */
        return SQLITE_OK;
      }
      goto statNextRestart; /* Tail recursion */
    }
    pCsr->iPage++;
    if( pCsr->iPage>=ArraySize(pCsr->aPage) ){
      statResetCsr(pCsr);
      return SQLITE_CORRUPT_BKPT;
    }
    assert( p==&pCsr->aPage[pCsr->iPage-1] );

    if( p->iCell==p->nCell ){
      p[1].iPgno = p->iRightChildPg;
    }else{
      p[1].iPgno = p->aCell[p->iCell].iChildPg;
    }
    rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0);
    pCsr->nPage++;
    p[1].iCell = 0;
    if( !pCsr->isAgg ){
      p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
    p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
    }
    p->iCell++;
    if( z==0 ) rc = SQLITE_NOMEM_BKPT;
  }


  /* Populate the StatCursor fields with the values to be returned
  ** by the xColumn() and xRowid() methods.
  */
  if( rc==SQLITE_OK ){
647
648
649
650
651
652
653
654
655
656



657
658
659


660
661
662
663
664
665

666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694

695
696

697
698
699
700
701
702

703
704

705
706
707
708
709



710
711
712
713
714
715
716


717
718
719
720
721
722

723
724

725
726
727
728
729
730
731





732
733
734
735
736
737
738
739
740
741
742
743
744
745
572
573
574
575
576
577
578



579
580
581



582
583

584
585
586
587

588





589
590
591
592
593
594
595
596
597
598
599




600
601
602
603
604
605
606


607


608

609




610


611
612
613



614
615
616
617
618
619
620



621
622






623


624







625
626
627
628
629







630
631
632
633
634
635
636







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




-
+
-
-
-
-
-











-
-
-
-







-
-
+
-
-
+
-

-
-
-
-
+
-
-
+


-
-
-
+
+
+




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







        case 0x0A:             /* index leaf */
          pCsr->zPagetype = "leaf";
          break;
        default:
          pCsr->zPagetype = "corrupted";
          break;
      }
      pCsr->nCell += p->nCell;
      pCsr->nUnused += p->nUnused;
      if( p->nMxPayload>pCsr->nMxPayload ) pCsr->nMxPayload = p->nMxPayload;
      pCsr->nCell = p->nCell;
      pCsr->nUnused = p->nUnused;
      pCsr->nMxPayload = p->nMxPayload;
      if( !pCsr->isAgg ){
        pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
        if( z==0 ) rc = SQLITE_NOMEM_BKPT;
      pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
      }
      nPayload = 0;
      for(i=0; i<p->nCell; i++){
        nPayload += p->aCell[i].nLocal;
      }
      pCsr->nPayload += nPayload;
      pCsr->nPayload = nPayload;

      /* If computing aggregate space usage by btree, continue with the
      ** next page.  The loop will exit via the return at label-statNext-done
      */
      if( pCsr->isAgg ) goto statNextRestart;
    }
  }

  return rc;
}

static int statEof(sqlite3_vtab_cursor *pCursor){
  StatCursor *pCsr = (StatCursor *)pCursor;
  return pCsr->isEof;
}

/* Initialize a cursor according to the query plan idxNum using the
** arguments in argv[0].  See statBestIndex() for a description of the
** meaning of the bits in idxNum.
*/
static int statFilter(
  sqlite3_vtab_cursor *pCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  StatCursor *pCsr = (StatCursor *)pCursor;
  StatTable *pTab = (StatTable*)(pCursor->pVtab);
  sqlite3_str *pSql;      /* Query of btrees to analyze */
  char *zSql;             /* String value of pSql */
  char *zSql;
  int iArg = 0;           /* Count of argv[] parameters used so far */
  int rc = SQLITE_OK;     /* Result of this operation */
  int rc = SQLITE_OK;
  const char *zName = 0;  /* Only provide analysis of this table */

  statResetCsr(pCsr);
  sqlite3_finalize(pCsr->pStmt);
  pCsr->pStmt = 0;
  if( idxNum & 0x01 ){
  if( idxNum==1 ){
    /* schema=? constraint is present.  Get its value */
    const char *zDbase = (const char*)sqlite3_value_text(argv[iArg++]);
    const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
    pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase);
    if( pCsr->iDb<0 ){
      pCsr->iDb = 0;
      pCsr->isEof = 1;
      return SQLITE_OK;
      sqlite3_free(pCursor->pVtab->zErrMsg);
      pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
      return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM_BKPT;
    }
  }else{
    pCsr->iDb = pTab->iDb;
  }
  if( idxNum & 0x02 ){
    /* name=? constraint is present */
    zName = (const char*)sqlite3_value_text(argv[iArg++]);
  statResetCsr(pCsr);
  sqlite3_finalize(pCsr->pStmt);
  }
  if( idxNum & 0x04 ){
    /* aggregate=? constraint is present */
    pCsr->isAgg = sqlite3_value_double(argv[iArg++])!=0.0;
  }else{
    pCsr->isAgg = 0;
  pCsr->pStmt = 0;
  }
  pSql = sqlite3_str_new(pTab->db);
  zSql = sqlite3_mprintf(
  sqlite3_str_appendf(pSql,
      "SELECT * FROM ("
        "SELECT 'sqlite_schema' AS name,1 AS rootpage,'table' AS type"
        " UNION ALL "
        "SELECT name,rootpage,type"
        " FROM \"%w\".sqlite_schema WHERE rootpage!=0)",
      pTab->db->aDb[pCsr->iDb].zDbSName);
      "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
      "  UNION ALL  "
      "SELECT name, rootpage, type"
      "  FROM \"%w\".sqlite_master WHERE rootpage!=0"
      "  ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName);
  if( zName ){
    sqlite3_str_appendf(pSql, "WHERE name=%Q", zName);
  }
  if( idxNum & 0x08 ){
    sqlite3_str_appendf(pSql, " ORDER BY name");
  }
  zSql = sqlite3_str_finish(pSql);
  if( zSql==0 ){
    return SQLITE_NOMEM_BKPT;
  }else{
    rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
    sqlite3_free(zSql);
  }

756
757
758
759
760
761
762
763
764

765
766
767
768
769
770
771

772
773
774
775
776

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

794
795
796
797
798
799

800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
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







-
-
+
-


-
-
-
-
+
-


-
-
+
-














-
-
+
-




-
+





-
-
-
-







){
  StatCursor *pCsr = (StatCursor *)pCursor;
  switch( i ){
    case 0:            /* name */
      sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
      break;
    case 1:            /* path */
      if( !pCsr->isAgg ){
        sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
      sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
      }
      break;
    case 2:            /* pageno */
      if( pCsr->isAgg ){
        sqlite3_result_int64(ctx, pCsr->nPage);
      }else{
        sqlite3_result_int64(ctx, pCsr->iPageno);
      sqlite3_result_int64(ctx, pCsr->iPageno);
      }
      break;
    case 3:            /* pagetype */
      if( !pCsr->isAgg ){
        sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
      sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
      }
      break;
    case 4:            /* ncell */
      sqlite3_result_int(ctx, pCsr->nCell);
      break;
    case 5:            /* payload */
      sqlite3_result_int(ctx, pCsr->nPayload);
      break;
    case 6:            /* unused */
      sqlite3_result_int(ctx, pCsr->nUnused);
      break;
    case 7:            /* mx_payload */
      sqlite3_result_int(ctx, pCsr->nMxPayload);
      break;
    case 8:            /* pgoffset */
      if( !pCsr->isAgg ){
        sqlite3_result_int64(ctx, pCsr->iOffset);
      sqlite3_result_int64(ctx, pCsr->iOffset);
      }
      break;
    case 9:            /* pgsize */
      sqlite3_result_int(ctx, pCsr->szPage);
      break;
    case 10: {         /* schema */
    default: {          /* schema */
      sqlite3 *db = sqlite3_context_db_handle(ctx);
      int iDb = pCsr->iDb;
      sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC);
      break;
    }
    default: {         /* aggregate */
      sqlite3_result_int(ctx, pCsr->isAgg);
      break;
    }
  }
  return SQLITE_OK;
}

static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
  StatCursor *pCsr = (StatCursor *)pCursor;
  *pRowid = pCsr->iPageno;

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







-
+

-
+





+
-
-
+
+
-











-
+


















-
+
+
+
+
+







** 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;
  struct SrcList_item *pItem = pSrc->a;
  Table *pTab;
  assert( pItem && pSrc->nSrc>=1 );
  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;
  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:
**
**   1) It is a virtual table and no implementation of the xUpdate method
**      has been provided
**
**   2) It is a system table (i.e. sqlite_schema), this call is not
**   2) It is a system table (i.e. sqlite_master), this call is not
**      part of a nested parse and writable_schema pragma has not 
**      been specified
**
**   3) The table is a shadow table, the database connection is in
**      defensive mode, and the current sqlite3_prepare()
**      is for a top-level SQL statement.
*/
static int tabIsReadOnly(Parse *pParse, Table *pTab){
  sqlite3 *db;
  if( IsVirtual(pTab) ){
    return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
  }
  if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
  db = pParse->db;
  if( (pTab->tabFlags & TF_Readonly)!=0 ){
    return sqlite3WritableSchema(db)==0 && pParse->nested==0;
  }
  assert( pTab->tabFlags & TF_Shadow );
  return sqlite3ReadOnlyShadowTables(db);
  return (db->flags & SQLITE_Defensive)!=0 
#ifndef SQLITE_OMIT_VIRTUALTABLE
          && db->pVtabCtx==0
#endif
          && db->nVdbeExec==0;
}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
203
204
205
206
207
208
209
210

211
212
213

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

214
215


216





217
218
219
220
221
222
223







-
+

-
-
+
-
-
-
-
-







      }
    }
  }

  /* 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);
  pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
  pSrc->a[0].pTab = pTab;
  if( pSrc->a[0].fg.isIndexedBy ){
    pSrc->a[0].u2.pIBIndex = 0;
  pSrc->a[0].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 */
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
387
388
389
390
391
392
393

394
395
396
397
398
399
400







-








  /* 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.
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439







-
+







    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pIdx->pSchema==pTab->pSchema );
      sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
    }
  }else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
  {
    u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
    u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE;
    if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
    wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
    if( HasRowid(pTab) ){
      /* For a rowid table, initialize the RowSet to an empty set */
      pPk = 0;
      nPk = 1;
      iRowSet = ++pParse->nMem;
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
461
462
463
464
465
466
467



468
469
470
471
472
473
474







-
-
-







    */
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
    if( pWInfo==0 ) goto delete_from_cleanup;
    eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
    assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
    assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
    if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
    if( sqlite3WhereUsesDeferredSeek(pWInfo) ){
      sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur);
    }
  
    /* Keep track of the number of rows to be deleted */
    if( memCnt ){
      sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
    }
  
    /* Extract the rowid or primary key for the current row */
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
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







-













+
+
+
+
+
+
+


















-
+
-
-







        goto delete_from_cleanup;
      }
      memset(aToOpen, 1, nIdx+1);
      aToOpen[nIdx+1] = 0;
      if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
      if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
      if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
      addrBypass = sqlite3VdbeMakeLabel(pParse);
    }else{
      if( pPk ){
        /* Add the PK key for this row to the temporary table */
        iKey = ++pParse->nMem;
        nKey = 0;   /* Zero tells OP_Found to use a composite key */
        sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
            sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
        sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk);
      }else{
        /* Add the rowid of the row to be deleted to the RowSet */
        nKey = 1;  /* OP_DeferredSeek always uses a single rowid */
        sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
      }
    }
  
    /* If this DELETE cannot use the ONEPASS strategy, this is the 
    ** end of the WHERE loop */
    if( eOnePass!=ONEPASS_OFF ){
      addrBypass = sqlite3VdbeMakeLabel(pParse);
    }else{
      sqlite3WhereEnd(pWInfo);
    }
  
    /* Unless this is a view, open cursors for the table we are 
    ** deleting from and all its indices. If this is a view, then the
    ** only effect this statement has is to fire the INSTEAD OF 
    ** triggers.
    */
    if( !isView ){
      int iAddrOnce = 0;
      if( eOnePass==ONEPASS_MULTI ){
        iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
      }
      testcase( IsVirtual(pTab) );
      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
                                 iTabCur, aToOpen, &iDataCur, &iIdxCur);
      assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
      assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
      if( eOnePass==ONEPASS_MULTI ){
      if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
        sqlite3VdbeJumpHereOrPopInst(v, iAddrOnce);
      }
    }
  
    /* Set up a loop over the rowids/primary-keys that were found in the
    ** where-clause loop above.
    */
    if( eOnePass!=ONEPASS_OFF ){
      assert( nKey==nPk );  /* OP_Found will use an unpacked key */
611
612
613
614
615
616
617
618

619
620
621
622
623
624
625
609
610
611
612
613
614
615

616
617
618
619
620
621
622
623







-
+







  }

  /* 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);
    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);
735
736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
733
734
735
736
737
738
739


740
741
742
743
744
745
746
747







-
-
+







    /* Populate the OLD.* pseudo-table register array. These values will be 
    ** used by any BEFORE and AFTER triggers that exist.  */
    sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
    for(iCol=0; iCol<pTab->nCol; iCol++){
      testcase( mask!=0xffffffff && iCol==31 );
      testcase( mask!=0xffffffff && iCol==32 );
      if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){
        int kk = sqlite3TableColumnToStorage(pTab, iCol);
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+kk+1);
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
      }
    }

    /* Invoke BEFORE DELETE trigger programs. */
    addrStart = sqlite3VdbeCurrentAddr(v);
    sqlite3CodeRowTrigger(pParse, pTrigger, 
        TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
855
856
857
858
859
860
861

862
863
864
865
866
867
868







-







    if( pIdx==pPk ) continue;
    if( iIdxCur+i==iIdxNoSeek ) continue;
    VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
        &iPartIdxLabel, pPrior, r1);
    sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
        pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
    sqlite3VdbeChangeP5(v, 1);  /* Cause IdxDelete to error if no entry found */
    sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
    pPrior = pIdx;
  }
}

/*
** Generate code that will assemble an index key and stores it in register
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
913
914
915
916
917
918
919


920
921
922
923
924
925
926







-
-







  if( piPartIdxLabel ){
    if( pIdx->pPartIdxWhere ){
      *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse);
      pParse->iSelfTab = iDataCur + 1;
      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
                            SQLITE_JUMPIFNULL);
      pParse->iSelfTab = 0;
      pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02;
                  ** pPartIdxWhere may have corrupted regPrior registers */
    }else{
      *piPartIdxLabel = 0;
    }
  }
  nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
  regBase = sqlite3GetTempRange(pParse, nCol);
  if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
945
946
947
948
949
950
951




952
953
954
955
956
957
958
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956







+
+
+
+







    ** But we are getting ready to store this value back into an index, where
    ** it should be converted by to INTEGER again.  So omit the OP_RealAffinity
    ** opcode if it is present */
    sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);
  }
  if( regOut ){
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
    if( pIdx->pTable->pSelect ){
      const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx);
      sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
    }
  }
  sqlite3ReleaseTempRange(pParse, regBase, nCol);
  return regBase;
}

/*
** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label

Changes to src/expr.c.

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







-
+

-
-
-
-
-
-
+
+
-



-
-
-


















-
-
-
-
+
















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

















-
+
+



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







** have an affinity:
**
** CREATE TABLE t1(a);
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
char sqlite3ExprAffinity(const Expr *pExpr){
char sqlite3ExprAffinity(Expr *pExpr){
  int op;
  while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
    assert( pExpr->op==TK_COLLATE
         || pExpr->op==TK_IF_NULL_ROW
         || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
    pExpr = pExpr->pLeft;
    assert( pExpr!=0 );
  pExpr = sqlite3ExprSkipCollate(pExpr);
  if( pExpr->flags & EP_Generic ) return 0;
  }
  op = pExpr->op;
  if( op==TK_SELECT ){
    assert( pExpr->flags&EP_xIsSelect );
    assert( pExpr->x.pSelect!=0 );
    assert( pExpr->x.pSelect->pEList!=0 );
    assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
    return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
  }
  if( op==TK_REGISTER ) op = pExpr->op2;
#ifndef SQLITE_OMIT_CAST
  if( op==TK_CAST ){
    assert( !ExprHasProperty(pExpr, EP_IntValue) );
    return sqlite3AffinityType(pExpr->u.zToken, 0);
  }
#endif
  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
    return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
  }
  if( op==TK_SELECT_COLUMN ){
    assert( pExpr->pLeft->flags&EP_xIsSelect );
    return sqlite3ExprAffinity(
        pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
    );
  }
  if( op==TK_VECTOR ){
    return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
  }
  return pExpr->affExpr;
  return pExpr->affinity;
}

/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken.   Return a pointer to a new Expr node that
** implements the COLLATE operator.
**
** If a memory allocation error occurs, that fact is recorded in pParse->db
** and the pExpr parameter is returned unchanged.
*/
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 ){
  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;
    }
  }
  return pExpr;
}
Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
  Token s;
  assert( zC!=0 );
  sqlite3TokenInit(&s, (char*)zC);
  return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}

/*
** Skip over any TK_COLLATE operators.
** Skip over any TK_COLLATE operators and any unlikely()
** or likelihood() function at the root of an expression.
*/
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
  while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
    assert( pExpr->op==TK_COLLATE );
    pExpr = pExpr->pLeft;
  }   
  return pExpr;
}

/*
** Skip over any TK_COLLATE operators and/or any unlikely()
** or likelihood() or likely() functions at the root of an
** expression.
*/
Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
  while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
    if( ExprHasProperty(pExpr, EP_Unlikely) ){
      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
      assert( pExpr->x.pList->nExpr>0 );
      assert( pExpr->op==TK_FUNCTION );
      pExpr = pExpr->x.pList->a[0].pExpr;
    }else{
      assert( pExpr->op==TK_COLLATE );
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
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







-
+


-
+


+

















-
-
-
-











+
-
+
-
-
+
+
-







** default collation if pExpr has no defined collation.
**
** The collating sequence might be determined by a COLLATE operator
** or by the presence of a column with a defined collating sequence.
** COLLATE operators take first precedence.  Left operands take
** precedence over right operands.
*/
CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
  sqlite3 *db = pParse->db;
  CollSeq *pColl = 0;
  const Expr *p = pExpr;
  Expr *p = pExpr;
  while( p ){
    int op = p->op;
    if( p->flags & EP_Generic ) break;
    if( op==TK_REGISTER ) op = p->op2;
    if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
     && p->y.pTab!=0
    ){
      /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
      ** a TK_COLUMN but was previously evaluated and cached in a register */
      int j = p->iColumn;
      if( j>=0 ){
        const char *zColl = p->y.pTab->aCol[j].zColl;
        pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
      }
      break;
    }
    if( op==TK_CAST || op==TK_UPLUS ){
      p = p->pLeft;
      continue;
    }
    if( op==TK_VECTOR ){
      p = p->x.pList->a[0].pExpr;
      continue;
    }
    if( op==TK_COLLATE ){
      pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
      break;
    }
    if( p->flags & EP_Collate ){
      if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
        p = p->pLeft;
      }else{
        Expr *pNext  = p->pRight;
        /* The Expr.x union is never used at the same time as Expr.pRight */
        assert( p->x.pList==0 || p->pRight==0 );
        /* p->flags holds EP_Collate and p->pLeft->flags does not.  And
        if( p->x.pList!=0 
        ** p->x.pSelect cannot.  So if p->x.pLeft exists, it must hold at
         && !db->mallocFailed
         && ALWAYS(!ExprHasProperty(p, EP_xIsSelect))
        ** least one EP_Collate. Thus the following two ALWAYS. */
        if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
        ){
          int i;
          for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
            if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
              pNext = p->x.pList->a[i].pExpr;
              break;
            }
          }
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
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







-
+









-
+










-
+

-
+








+
+
+
+
+


-
-
+
+







-
+







** defautl collation sequence.
**
** See also: sqlite3ExprCollSeq()
**
** The sqlite3ExprCollSeq() routine works the same except that it
** returns NULL if there is no defined collation.
*/
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
  CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
  if( p==0 ) p = pParse->db->pDfltColl;
  assert( p!=0 );
  return p;
}

/*
** Return TRUE if the two expressions have equivalent collating sequences.
*/
int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){
int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
  CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
  CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
  return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
}

/*
** pExpr is an operand of a comparison operator.  aff2 is the
** type affinity of the other operand.  This routine returns the
** type affinity that should be used for the comparison operator.
*/
char sqlite3CompareAffinity(const Expr *pExpr, char aff2){
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
  char aff1 = sqlite3ExprAffinity(pExpr);
  if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
  if( aff1 && aff2 ){
    /* Both sides of the comparison are columns. If one has numeric
    ** affinity, use that. Otherwise use no affinity.
    */
    if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
      return SQLITE_AFF_NUMERIC;
    }else{
      return SQLITE_AFF_BLOB;
    }
  }else if( !aff1 && !aff2 ){
    /* Neither side of the comparison is a column.  Compare the
    ** results directly.
    */
    return SQLITE_AFF_BLOB;
  }else{
    /* One side is a column, the other is not. Use the columns affinity. */
    assert( aff1<=SQLITE_AFF_NONE || aff2<=SQLITE_AFF_NONE );
    return (aff1<=SQLITE_AFF_NONE ? aff2 : aff1) | SQLITE_AFF_NONE;
    assert( aff1==0 || aff2==0 );
    return (aff1 + aff2);
  }
}

/*
** pExpr is a comparison operator.  Return the type affinity that should
** be applied to both operands prior to doing the comparison.
*/
static char comparisonAffinity(const Expr *pExpr){
static char comparisonAffinity(Expr *pExpr){
  char aff;
  assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
          pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
          pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
  assert( pExpr->pLeft );
  aff = sqlite3ExprAffinity(pExpr->pLeft);
  if( pExpr->pRight ){
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
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







-
+

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






-
+
-
-
-
-



















-
-
+
+
















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










-
+
-





-
-
-
-
-
+
-








/*
** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
** idx_affinity is the affinity of an indexed column. Return true
** if the index with affinity idx_affinity may be used to implement
** the comparison in pExpr.
*/
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity){
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
  char aff = comparisonAffinity(pExpr);
  switch( aff ){
  if( aff<SQLITE_AFF_TEXT ){
    return 1;
    case SQLITE_AFF_BLOB:
      return 1;
  }
  if( aff==SQLITE_AFF_TEXT ){
    return idx_affinity==SQLITE_AFF_TEXT;
    case SQLITE_AFF_TEXT:
      return idx_affinity==SQLITE_AFF_TEXT;
  }
  return sqlite3IsNumericAffinity(idx_affinity);
    default:
      return sqlite3IsNumericAffinity(idx_affinity);
  }
}

/*
** Return the P5 value that should be used for a binary comparison
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
*/
static u8 binaryCompareP5(
static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
  const Expr *pExpr1,   /* Left operand */
  const Expr *pExpr2,   /* Right operand */
  int jumpIfNull        /* Extra flags added to P5 */
){
  u8 aff = (char)sqlite3ExprAffinity(pExpr2);
  aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull;
  return aff;
}

/*
** Return a pointer to the collation sequence that should be used by
** a binary comparison operator comparing pLeft and pRight.
**
** If the left hand expression has a collating sequence type, then it is
** used. Otherwise the collation sequence for the right hand expression
** is used, or the default (BINARY) if neither expression has a collating
** type.
**
** Argument pRight (but not pLeft) may be a null pointer. In this case,
** it is not considered.
*/
CollSeq *sqlite3BinaryCompareCollSeq(
  Parse *pParse, 
  const Expr *pLeft, 
  const Expr *pRight
  Expr *pLeft, 
  Expr *pRight
){
  CollSeq *pColl;
  assert( pLeft );
  if( pLeft->flags & EP_Collate ){
    pColl = sqlite3ExprCollSeq(pParse, pLeft);
  }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
    pColl = sqlite3ExprCollSeq(pParse, pRight);
  }else{
    pColl = sqlite3ExprCollSeq(pParse, pLeft);
    if( !pColl ){
      pColl = sqlite3ExprCollSeq(pParse, pRight);
    }
  }
  return pColl;
}

/* Expresssion p is a comparison operator.  Return a collation sequence
** appropriate for the comparison operator.
**
** This is normally just a wrapper around sqlite3BinaryCompareCollSeq().
** However, if the OP_Commuted flag is set, then the order of the operands
** is reversed in the sqlite3BinaryCompareCollSeq() call so that the
** correct collating sequence is found.
*/
CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, const Expr *p){
  if( ExprHasProperty(p, EP_Commuted) ){
    return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft);
  }else{
    return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight);
  }
}

/*
** Generate code for a comparison operator.
*/
static int codeCompare(
  Parse *pParse,    /* The parsing (and code generating) context */
  Expr *pLeft,      /* The left operand */
  Expr *pRight,     /* The right operand */
  int opcode,       /* The comparison opcode */
  int in1, int in2, /* Register holding operands */
  int dest,         /* Jump here if true.  */
  int jumpIfNull,   /* If true, jump if either operand is NULL */
  int jumpIfNull    /* If true, jump if either operand is NULL */
  int isCommuted    /* The comparison has been commuted */
){
  int p5;
  int addr;
  CollSeq *p4;

  if( pParse->nErr ) return 0;
  if( isCommuted ){
    p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft);
  }else{
    p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
  p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
  }
  p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
  addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
                           (void*)p4, P4_COLLSEQ);
  sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5);
  return addr;
}

608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
551
552
553
554
555
556
557

558


559
560
561
562
563
564
565







-

-
-







  Expr *pRight = pExpr->pRight;
  int nLeft = sqlite3ExprVectorSize(pLeft);
  int i;
  int regLeft = 0;
  int regRight = 0;
  u8 opx = op;
  int addrDone = sqlite3VdbeMakeLabel(pParse);
  int isCommuted = ExprHasProperty(pExpr,EP_Commuted);

  assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
  if( pParse->nErr ) return;
  if( nLeft!=sqlite3ExprVectorSize(pRight) ){
    sqlite3ErrorMsg(pParse, "row value misused");
    return;
  }
  assert( pExpr->op==TK_EQ || pExpr->op==TK_NE 
       || pExpr->op==TK_IS || pExpr->op==TK_ISNOT 
       || pExpr->op==TK_LT || pExpr->op==TK_GT 
640
641
642
643
644
645
646
647

648
649
650
651
652
653
654
580
581
582
583
584
585
586

587
588
589
590
591
592
593
594







-
+







  for(i=0; 1 /*Loop exits by "break"*/; i++){
    int regFree1 = 0, regFree2 = 0;
    Expr *pL, *pR; 
    int r1, r2;
    assert( i>=0 && i<nLeft );
    r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, &regFree1);
    r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
    codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5, isCommuted);
    codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5);
    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);
    testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
    testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
    testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
    sqlite3ReleaseTempReg(pParse, regFree1);
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
717
718
719
720
721
722
723

724
725
726
727
728
729
730







-







}
#else /* ABOVE:  Height enforcement enabled.  BELOW: Height enforcement off */
/*
** Propagate all EP_Propagate flags from the Expr.x.pList into
** Expr.flags. 
*/
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
  if( pParse->nErr ) return;
  if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
    p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
  }
}
#define exprSetHeight(y)
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */

830
831
832
833
834
835
836
837

838
839
840
841
842
843
844
769
770
771
772
773
774
775

776
777
778
779
780
781
782
783







-
+







  pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
  if( pNew ){
    memset(pNew, 0, sizeof(Expr));
    pNew->op = (u8)op;
    pNew->iAgg = -1;
    if( pToken ){
      if( nExtra==0 ){
        pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
        pNew->flags |= EP_IntValue|EP_Leaf;
        pNew->u.iValue = iValue;
      }else{
        pNew->u.zToken = (char*)&pNew[1];
        assert( pToken->z!=0 || pToken->n==0 );
        if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
        pNew->u.zToken[pToken->n] = 0;
        if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
907
908
909
910
911
912
913




914
915
916
917
918






919


920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942



























943
944
945
946
947
948
949
950
951
952

953
954

955
956
957
958

959
960
961
962
963



964


965

966
967
968
969
970
971
972
846
847
848
849
850
851
852
853
854
855
856





857
858
859
860
861
862
863
864
865
866



867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921

922


923
924
925
926

927





928
929
930
931
932
933

934
935
936
937
938
939
940
941







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

+
+

-
-
-



















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









-
+
-
-
+



-
+
-
-
-
-
-
+
+
+

+
+
-
+







Expr *sqlite3PExpr(
  Parse *pParse,          /* Parsing context */
  int op,                 /* Expression opcode */
  Expr *pLeft,            /* Left operand */
  Expr *pRight            /* Right operand */
){
  Expr *p;
  if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){
    /* Take advantage of short-circuit false optimization for AND */
    p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
  }else{
  p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
  if( p ){
    memset(p, 0, sizeof(Expr));
    p->op = op & 0xff;
    p->iAgg = -1;
    p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
    if( p ){
      memset(p, 0, sizeof(Expr));
      p->op = op & 0xff;
      p->iAgg = -1;
    }
    sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
  }
  if( p ) {
    sqlite3ExprCheckHeight(pParse, p->nHeight);
  }else{
    sqlite3ExprDelete(pParse->db, pLeft);
    sqlite3ExprDelete(pParse->db, pRight);
  }
  return p;
}

/*
** Add pSelect to the Expr.x.pSelect field.  Or, if pExpr is NULL (due
** do a memory allocation failure) then delete the pSelect object.
*/
void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
  if( pExpr ){
    pExpr->x.pSelect = pSelect;
    ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
    sqlite3ExprSetHeightAndFlags(pParse, pExpr);
  }else{
    assert( pParse->db->mallocFailed );
    sqlite3SelectDelete(pParse->db, pSelect);
  }
}


/*
** If the expression is always either TRUE or FALSE (respectively),
** then return 1.  If one cannot determine the truth value of the
** expression at compile-time return 0.
**
** This is an optimization.  If is OK to return 0 here even if
** the expression really is always false or false (a false negative).
** But it is a bug to return 1 if the expression might have different
** boolean values in different circumstances (a false positive.)
**
** Note that if the expression is part of conditional for a
** LEFT JOIN, then we cannot determine at compile-time whether or not
** is it true or false, so always return 0.
*/
static int exprAlwaysTrue(Expr *p){
  int v = 0;
  if( ExprHasProperty(p, EP_FromJoin) ) return 0;
  if( !sqlite3ExprIsInteger(p, &v) ) return 0;
  return v!=0;
}
static int exprAlwaysFalse(Expr *p){
  int v = 0;
  if( ExprHasProperty(p, EP_FromJoin) ) return 0;
  if( !sqlite3ExprIsInteger(p, &v) ) return 0;
  return v==0;
}

/*
** Join two expressions using an AND operator.  If either expression is
** NULL, then just return the other expression.
**
** If one side or the other of the AND is known to be false, then instead
** of returning an AND expression, just return a constant expression with
** a value of false.
*/
Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
  sqlite3 *db = pParse->db;
  if( pLeft==0  ){
  if( pLeft==0 ){
    return pRight;
  }else if( pRight==0 ){
    return pLeft;
  }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight)) 
  }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
         && !IN_RENAME_OBJECT
  ){
    sqlite3ExprDeferredDelete(pParse, pLeft);
    sqlite3ExprDeferredDelete(pParse, pRight);
    return sqlite3Expr(db, TK_INTEGER, "0");
    sqlite3ExprDelete(db, pLeft);
    sqlite3ExprDelete(db, pRight);
    return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
  }else{
    Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
    sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
    return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
    return pNew;
  }
}

/*
** Construct a new expression node for a function with multiple
** arguments.
*/
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
960
961
962
963
964
965
966


































967
968
969
970
971
972
973







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







  ExprSetProperty(pNew, EP_HasFunc);
  assert( !ExprHasProperty(pNew, EP_xIsSelect) );
  sqlite3ExprSetHeightAndFlags(pParse, pNew);
  if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
  return pNew;
}

/*
** Check to see if a function is usable according to current access
** rules:
**
**    SQLITE_FUNC_DIRECT    -     Only usable from top-level SQL
**
**    SQLITE_FUNC_UNSAFE    -     Usable if TRUSTED_SCHEMA or from
**                                top-level SQL
**
** If the function is not usable, create an error.
*/
void sqlite3ExprFunctionUsable(
  Parse *pParse,         /* Parsing and code generating context */
  Expr *pExpr,           /* The function invocation */
  FuncDef *pDef          /* The function being invoked */
){
  assert( !IN_RENAME_OBJECT );
  assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 );
  if( ExprHasProperty(pExpr, EP_FromDDL) ){
    if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
     || (pParse->db->flags & SQLITE_TrustedSchema)==0
    ){
      /* Functions prohibited in triggers and views if:
      **     (1) tagged with SQLITE_DIRECTONLY
      **     (2) not tagged with SQLITE_INNOCUOUS (which means it
      **         is tagged with SQLITE_FUNC_UNSAFE) and 
      **         SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
      **         that the schema is possibly tainted).
      */
      sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
    }
  }
}

/*
** Assign a variable number to an expression that encodes a wildcard
** in the original SQL statement.  
**
** Wildcards consisting of a single "?" are assigned the next sequential
** variable number.
**
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
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







-


-



-
-
-
+
+
+
+
-
-











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










+
+
+
+
+
+
+
+
+
+







  }
#endif
  if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
    /* The Expr.x union is never used at the same time as Expr.pRight */
    assert( p->x.pList==0 || p->pRight==0 );
    if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
    if( p->pRight ){
      assert( !ExprHasProperty(p, EP_WinFunc) );
      sqlite3ExprDeleteNN(db, p->pRight);
    }else if( ExprHasProperty(p, EP_xIsSelect) ){
      assert( !ExprHasProperty(p, EP_WinFunc) );
      sqlite3SelectDelete(db, p->x.pSelect);
    }else{
      sqlite3ExprListDelete(db, p->x.pList);
#ifndef SQLITE_OMIT_WINDOWFUNC
      if( ExprHasProperty(p, EP_WinFunc) ){
        sqlite3WindowDelete(db, p->y.pWin);
    }
    if( ExprHasProperty(p, EP_WinFunc) ){
      assert( p->op==TK_FUNCTION );
      sqlite3WindowDelete(db, p->y.pWin);
      }
#endif
    }
  }
  if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
  if( !ExprHasProperty(p, EP_Static) ){
    sqlite3DbFreeNN(db, p);
  }
}
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
  if( p ) sqlite3ExprDeleteNN(db, p);
}


/*
** Arrange to cause pExpr to be deleted when the pParse is deleted.
** This is similar to sqlite3ExprDelete() except that the delete is
** deferred untilthe pParse is deleted.
**
** The pExpr might be deleted immediately on an OOM error.
**
** The deferred delete is (currently) implemented by adding the
** pExpr to the pParse->pConstExpr list with a register number of 0.
*/
void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
  pParse->pConstExpr = 
      sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
}

/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
** expression.
*/
void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
  if( p ){
    if( IN_RENAME_OBJECT ){
      sqlite3RenameExprUnmap(pParse, p);
    }
    sqlite3ExprDeleteNN(pParse->db, p);
  }
}

/*
** Return the number of bytes allocated for the expression structure 
** passed as the first argument. This is always one of EXPR_FULLSIZE,
** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
*/
static int exprStructSize(Expr *p){
  if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
  if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
  return EXPR_FULLSIZE;
}

/*
** Copy the complete content of an Expr node, taking care not to read
** past the end of the structure for a reduced-size version of the source
** Expr.
*/
static void exprNodeCopy(Expr *pDest, Expr *pSrc){
  memset(pDest, 0, sizeof(Expr));
  memcpy(pDest, pSrc, exprStructSize(pSrc));
}

/*
** The dupedExpr*Size() routines each return the number of bytes required
** to store a copy of an expression or expression tree.  They differ in
** how much of the tree is measured.
**
**     dupedExprStructSize()     Size of only the Expr structure 
1240
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1154
1155
1156
1157
1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1168







-
+







#endif
  ){
    nSize = EXPR_FULLSIZE;
  }else{
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    assert( !ExprHasProperty(p, EP_FromJoin) ); 
    assert( !ExprHasProperty(p, EP_MemToken) );
    assert( !ExprHasVVAProperty(p, EP_NoReduce) );
    assert( !ExprHasProperty(p, EP_NoReduce) );
    if( p->pLeft || p->x.pList ){
      nSize = EXPR_REDUCEDSIZE | EP_Reduced;
    }else{
      assert( p->pRight==0 );
      nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
    }
  }
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1259
1260
1261
1262
1263
1264
1265




1266
1267
1268
1269
1270
1271
1272







-
-
-
-







      }
    }

    /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
    pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
    pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
    pNew->flags |= staticFlag;
    ExprClearVVAProperties(pNew);
    if( dupFlags ){
      ExprSetVVAProperty(pNew, EP_Immutable);
    }

    /* Copy the p->u.zToken string, if any. */
    if( nToken ){
      char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
      memcpy(zToken, p->u.zToken, nToken);
    }

1434
1435
1436
1437
1438
1439
1440
1441
1442
1443




1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1344
1345
1346
1347
1348
1349
1350



1351
1352
1353
1354




1355
1356
1357
1358
1359
1360
1361







-
-
-
+
+
+
+
-
-
-
-







/*
** The gatherSelectWindows() procedure and its helper routine
** gatherSelectWindowsCallback() are used to scan all the expressions
** an a newly duplicated SELECT statement and gather all of the Window
** objects found there, assembling them onto the linked list at Select->pWin.
*/
static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_WinFunc) ){
    Select *pSelect = pWalker->u.pSelect;
    Window *pWin = pExpr->y.pWin;
  if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){
    assert( ExprHasProperty(pExpr, EP_WinFunc) );
    pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin;
    pWalker->u.pSelect->pWin = pExpr->y.pWin;
    assert( pWin );
    assert( IsWindowFunc(pExpr) );
    assert( pWin->ppThis==0 );
    sqlite3WindowLink(pSelect, pWin);
  }
  return WRC_Continue;
}
static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){
  return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune;
}
static void gatherSelectWindows(Select *p){
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521



1522
1523

1524
1525
1526
1527
1528
1529
1530
1419
1420
1421
1422
1423
1424
1425



1426
1427
1428
1429

1430
1431
1432
1433
1434
1435
1436
1437







-
-
-
+
+
+

-
+







        assert( i>0 );
        assert( pItem[-1].pExpr!=0 );
        assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 );
        assert( pPriorSelectCol==pItem[-1].pExpr->pLeft );
        pNewExpr->pLeft = pPriorSelectCol;
      }
    }
    pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
    pItem->sortFlags = pOldItem->sortFlags;
    pItem->eEName = pOldItem->eEName;
    pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
    pItem->sortOrder = pOldItem->sortOrder;
    pItem->done = 0;
    pItem->bNulls = pOldItem->bNulls;
    pItem->bSpanIsTab = pOldItem->bSpanIsTab;
    pItem->bSorterRef = pOldItem->bSorterRef;
    pItem->u = pOldItem->u;
  }
  return pNew;
}

/*
1542
1543
1544
1545
1546
1547
1548
1549
1550


1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563

1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
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







-
-
+
+












-
+
-
-
-







  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];
    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->u2 = pOldItem->u2;
    pNewItem->pIBIndex = pOldItem->pIBIndex;
    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++;
1629
1630
1631
1632
1633
1634
1635
1636

1637
1638
1639
1640
1641
1642
1643
1533
1534
1535
1536
1537
1538
1539

1540
1541
1542
1543
1544
1545
1546
1547







-
+







    pNew->addrOpenEphm[0] = -1;
    pNew->addrOpenEphm[1] = -1;
    pNew->nSelectRow = p->nSelectRow;
    pNew->pWith = withDup(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
    pNew->pWin = 0;
    pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
    if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew);
    if( p->pWin ) gatherSelectWindows(pNew);
#endif
    pNew->selId = p->selId;
    *pp = pNew;
    pp = &pNew->pPrior;
    pNext = pNew;
  }

1686
1687
1688
1689
1690
1691
1692
1693

1694
1695

1696
1697
1698
1699
1700
1701
1702
1590
1591
1592
1593
1594
1595
1596

1597
1598

1599
1600
1601
1602
1603
1604
1605
1606







-
+

-
+







         sizeof(*pList)+(2*(sqlite3_int64)pList->nExpr-1)*sizeof(pList->a[0]));
    if( pNew==0 ){
      goto no_mem;
    }
    pList = pNew;
  }
  pItem = &pList->a[pList->nExpr++];
  assert( offsetof(struct ExprList_item,zEName)==sizeof(pItem->pExpr) );
  assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) );
  assert( offsetof(struct ExprList_item,pExpr)==0 );
  memset(&pItem->zEName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zEName));
  memset(&pItem->zName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zName));
  pItem->pExpr = pExpr;
  return pList;

no_mem:     
  /* Avoid leaking memory if malloc has failed. */
  sqlite3ExprDelete(db, pExpr);
  sqlite3ExprListDelete(db, pList);
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752

1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772

1773



1774
1775
1776
1777
1778
1779
1780
1781

1782
1783
1784
1785
1786
1787
1788
1789




1790
1791
1792
1793
1794
1795

1796
1797
1798
1799
1800
1801
1802


1803
1804
1805
1806
1807

1808
1809
1810
1811
1812

1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831

1832
1833
1834


1835
1836
1837
1838
1839
1840


1841
1842
1843
1844
1845
1846
1847
1848
1642
1643
1644
1645
1646
1647
1648




1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681
1682
1683

1684

1685






1686
1687
1688
1689






1690




1691


1692
1693





1694



1695

1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709

1710
1711
1712
1713

1714



1715
1716






1717
1718

1719
1720
1721
1722
1723
1724
1725







-
-
-
-



-
+




















+
-
+
+
+







-
+
-

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

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

-
+













-




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







    sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
                    pColumns->nId, n);
    goto vector_append_error;
  }

  for(i=0; i<pColumns->nId; i++){
    Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i);
    assert( pSubExpr!=0 || db->mallocFailed );
    assert( pSubExpr==0 || pSubExpr->iTable==0 );
    if( pSubExpr==0 ) continue;
    pSubExpr->iTable = pColumns->nId;
    pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
    if( pList ){
      assert( pList->nExpr==iFirst+i+1 );
      pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName;
      pList->a[pList->nExpr-1].zName = pColumns->a[i].zName;
      pColumns->a[i].zName = 0;
    }
  }

  if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
    Expr *pFirst = pList->a[iFirst].pExpr;
    assert( pFirst!=0 );
    assert( pFirst->op==TK_SELECT_COLUMN );
     
    /* Store the SELECT statement in pRight so it will be deleted when
    ** sqlite3ExprListDelete() is called */
    pFirst->pRight = pExpr;
    pExpr = 0;

    /* Remember the size of the LHS in iTable so that we can check that
    ** the RHS and LHS sizes match during code generation. */
    pFirst->iTable = pColumns->nId;
  }

vector_append_error:
  if( IN_RENAME_OBJECT ){
  sqlite3ExprUnmapAndDelete(pParse, pExpr);
    sqlite3RenameExprUnmap(pParse, pExpr);
  }
  sqlite3ExprDelete(db, pExpr);
  sqlite3IdListDelete(db, pColumns);
  return pList;
}

/*
** Set the sort order for the last element on the given ExprList.
*/
void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){
void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
  struct ExprList_item *pItem;
  if( p==0 ) return;
  assert( p->nExpr>0 );

  assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 );
  assert( iSortOrder==SQLITE_SO_UNDEFINED 
       || iSortOrder==SQLITE_SO_ASC 
       || iSortOrder==SQLITE_SO_DESC 
  assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
  assert( p->nExpr>0 );
  if( iSortOrder<0 ){
    assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
  );
  assert( eNulls==SQLITE_SO_UNDEFINED 
       || eNulls==SQLITE_SO_ASC 
       || eNulls==SQLITE_SO_DESC 
  );

    return;
  pItem = &p->a[p->nExpr-1];
  assert( pItem->bNulls==0 );
  if( iSortOrder==SQLITE_SO_UNDEFINED ){
    iSortOrder = SQLITE_SO_ASC;
  }
  pItem->sortFlags = (u8)iSortOrder;

  p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
}
  if( eNulls!=SQLITE_SO_UNDEFINED ){
    pItem->bNulls = 1;
    if( iSortOrder!=eNulls ){
      pItem->sortFlags |= KEYINFO_ORDER_BIGNULL;
    }

  }
}

/*
** Set the ExprList.a[].zEName element of the most recently added item
** Set the ExprList.a[].zName element of the most recently added item
** on the expression list.
**
** pList might be NULL following an OOM error.  But pName should never be
** NULL.  If a memory allocation fails, the pParse->db->mallocFailed flag
** is set.
*/
void sqlite3ExprListSetName(
  Parse *pParse,          /* Parsing context */
  ExprList *pList,        /* List to which to add the span. */
  Token *pName,           /* Name to be added */
  int dequote             /* True to cause the name to be dequoted */
){
  assert( pList!=0 || pParse->db->mallocFailed!=0 );
  assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 );
  if( pList ){
    struct ExprList_item *pItem;
    assert( pList->nExpr>0 );
    pItem = &pList->a[pList->nExpr-1];
    assert( pItem->zEName==0 );
    assert( pItem->zName==0 );
    assert( pItem->eEName==ENAME_NAME );
    pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
    if( dequote ){
    pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
    if( dequote ) sqlite3Dequote(pItem->zName);
      /* If dequote==0, then pName->z does not point to part of a DDL
      ** statement handled by the parser. And so no token need be added
      ** to the token-map.  */
      sqlite3Dequote(pItem->zEName);
      if( IN_RENAME_OBJECT ){
        sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
    if( IN_RENAME_OBJECT ){
      sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName);
      }
    }
  }
}

/*
** Set the ExprList.a[].zSpan element of the most recently added item
** on the expression list.
1858
1859
1860
1861
1862
1863
1864
1865
1866


1867
1868
1869
1870
1871
1872
1873
1874
1875
1735
1736
1737
1738
1739
1740
1741


1742
1743


1744
1745
1746
1747
1748
1749
1750







-
-
+
+
-
-







  const char *zEnd        /* End of the span */
){
  sqlite3 *db = pParse->db;
  assert( pList!=0 || db->mallocFailed!=0 );
  if( pList ){
    struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
    assert( pList->nExpr>0 );
    if( pItem->zEName==0 ){
      pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd);
    sqlite3DbFree(db, pItem->zSpan);
    pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd);
      pItem->eEName = ENAME_SPAN;
    }
  }
}

/*
** If the expression list pEList contains more than iLimit elements,
** leave an error message in pParse.
*/
1891
1892
1893
1894
1895
1896
1897
1898


1899
1900
1901
1902
1903
1904
1905
1766
1767
1768
1769
1770
1771
1772

1773
1774
1775
1776
1777
1778
1779
1780
1781







-
+
+







*/
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
  int i = pList->nExpr;
  struct ExprList_item *pItem =  pList->a;
  assert( pList->nExpr>0 );
  do{
    sqlite3ExprDelete(db, pItem->pExpr);
    sqlite3DbFree(db, pItem->zEName);
    sqlite3DbFree(db, pItem->zName);
    sqlite3DbFree(db, pItem->zSpan);
    pItem++;
  }while( --i>0 );
  sqlite3DbFreeNN(db, pList);
}
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
  if( pList ) exprListDeleteNN(db, pList);
}
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
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







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







-


+
-
+


-










-






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

















-
-
+
+
-
-
-
-
+
+
+



















-
+
-
-
-











-
+













-
+


-


-






-
+







-
+







** This callback is used by multiple expression walkers.
*/
int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  pWalker->eCode = 0;
  return WRC_Abort;
}

/*
** Check the input string to see if it is "true" or "false" (in any case).
**
**       If the string is....           Return
**         "true"                         EP_IsTrue
**         "false"                        EP_IsFalse
**         anything else                  0
*/
u32 sqlite3IsTrueOrFalse(const char *zIn){
  if( sqlite3StrICmp(zIn, "true")==0  ) return EP_IsTrue;
  if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse;
  return 0;
}


/*
** If the input expression is an ID with the name "true" or "false"
** then convert it into an TK_TRUEFALSE term.  Return non-zero if
** the conversion happened, and zero if the expression is unaltered.
*/
int sqlite3ExprIdToTrueFalse(Expr *pExpr){
  u32 v;
  assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
  if( !ExprHasProperty(pExpr, EP_Quoted)
   && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
   && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0
       || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
  ){
    pExpr->op = TK_TRUEFALSE;
    ExprSetProperty(pExpr, v);
    return 1;
  }
  return 0;
}

/*
** The argument must be a TK_TRUEFALSE Expr node.  Return 1 if it is TRUE
** and 0 if it is FALSE.
*/
int sqlite3ExprTruthValue(const Expr *pExpr){
  pExpr = sqlite3ExprSkipCollate((Expr*)pExpr);
  assert( pExpr->op==TK_TRUEFALSE );
  assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
       || sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
  return pExpr->u.zToken[4]==0;
}

/*
** If pExpr is an AND or OR expression, try to simplify it by eliminating
** terms that are always true or false.  Return the simplified expression.
** Or return the original expression if no simplification is possible.
**
** Examples:
**
**     (x<10) AND true                =>   (x<10)
**     (x<10) AND false               =>   false
**     (x<10) AND (y=22 OR false)     =>   (x<10) AND (y=22)
**     (x<10) AND (y=22 OR true)      =>   (x<10)
**     (y=22) OR true                 =>   true
*/
Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
  assert( pExpr!=0 );
  if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
    Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
    Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
    if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
      pExpr = pExpr->op==TK_AND ? pRight : pLeft;
    }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
      pExpr = pExpr->op==TK_AND ? pLeft : pRight;
    }
  }
  return pExpr;
}


/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant.  The
** Walker.eCode value determines the type of "constant" we are looking
** for.
**
** These callback routines are used to implement the following:
**
**     sqlite3ExprIsConstant()                  pWalker->eCode==1
**     sqlite3ExprIsConstantNotJoin()           pWalker->eCode==2
**     sqlite3ExprIsTableConstant()             pWalker->eCode==3
**     sqlite3ExprIsConstantOrFunction()        pWalker->eCode==4 or 5
**
** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
** is found to not be a constant.
**
** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT
** expressions in a CREATE TABLE statement.  The Walker.eCode value is 5
** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
** in a CREATE TABLE statement.  The Walker.eCode value is 5 when parsing
** when parsing an existing schema out of the sqlite_schema table and 4
** when processing a new CREATE TABLE statement.  A bound parameter raises
** an error for new statements, but is silently converted
** to NULL for existing schemas.  This allows sqlite_schema tables that 
** an existing schema and 4 when processing a new statement.  A bound
** parameter raises an error for new statements, but is silently converted
** to NULL for existing schemas.  This allows sqlite_master tables that 
** contain a bound parameter because they were generated by older versions
** of SQLite to be parsed by newer versions of SQLite without raising a
** malformed schema error.
*/
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){

  /* If pWalker->eCode is 2 then any term of the expression that comes from
  ** the ON or USING clauses of a left join disqualifies the expression
  ** from being considered constant. */
  if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
    pWalker->eCode = 0;
    return WRC_Abort;
  }

  switch( pExpr->op ){
    /* Consider functions to be constant if all their arguments are constant
    ** and either pWalker->eCode==4 or 5 or the function has the
    ** SQLITE_FUNC_CONST flag. */
    case TK_FUNCTION:
      if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc))
      if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
       && !ExprHasProperty(pExpr, EP_WinFunc)
      ){
        if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL);
        return WRC_Continue;
      }else{
        pWalker->eCode = 0;
        return WRC_Abort;
      }
    case TK_ID:
      /* Convert "true" or "false" in a DEFAULT clause into the
      ** appropriate TK_TRUEFALSE operator */
      if( sqlite3ExprIdToTrueFalse(pExpr) ){
        return WRC_Prune;
      }
      /* no break */ deliberate_fall_through
      /* Fall thru */
    case TK_COLUMN:
    case TK_AGG_FUNCTION:
    case TK_AGG_COLUMN:
      testcase( pExpr->op==TK_ID );
      testcase( pExpr->op==TK_COLUMN );
      testcase( pExpr->op==TK_AGG_FUNCTION );
      testcase( pExpr->op==TK_AGG_COLUMN );
      if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){
        return WRC_Continue;
      }
      if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
        return WRC_Continue;
      }
      /* no break */ deliberate_fall_through
      /* Fall through */
    case TK_IF_NULL_ROW:
    case TK_REGISTER:
    case TK_DOT:
      testcase( pExpr->op==TK_REGISTER );
      testcase( pExpr->op==TK_IF_NULL_ROW );
      testcase( pExpr->op==TK_DOT );
      pWalker->eCode = 0;
      return WRC_Abort;
    case TK_VARIABLE:
      if( pWalker->eCode==5 ){
        /* Silently convert bound parameters that appear inside of CREATE
        ** statements into a NULL when parsing the CREATE statement text out
        ** of the sqlite_schema table */
        ** of the sqlite_master table */
        pExpr->op = TK_NULL;
      }else if( pWalker->eCode==4 ){
        /* A bound parameter in a CREATE statement that originates from
        ** sqlite3_prepare() causes an error */
        pWalker->eCode = 0;
        return WRC_Abort;
      }
      /* no break */ deliberate_fall_through
      /* Fall through */
    default:
      testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */
      testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */
      return WRC_Continue;
  }
}
static int exprIsConst(Expr *p, int initFlag, int iCur){
2136
2137
2138
2139
2140
2141
2142
2143

2144
2145
2146
2147
2148
2149
2150
1962
1963
1964
1965
1966
1967
1968

1969
1970
1971
1972
1973
1974
1975
1976







-
+







**   (2) the expression does originate in the ON or USING clause
**       of a LEFT JOIN, and
**   (3) the expression does not contain any EP_FixedCol TK_COLUMN
**       operands created by the constant propagation optimization.
**
** When this routine returns true, it indicates that the expression
** can be added to the pParse->pConstExpr list and evaluated once when
** the prepared statement starts up.  See sqlite3ExprCodeRunJustOnce().
** the prepared statement starts up.  See sqlite3ExprCodeAtInit().
*/
int sqlite3ExprIsConstantNotJoin(Expr *p){
  return exprIsConst(p, 2, 0);
}

/*
** Walk an expression tree.  Return non-zero if the expression is constant
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
2038
2039
2040
2041
2042
2043
2044


2045



2046
2047










2048
2049
2050
2051
2052
2053
2054







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







  w.u.pGroupBy = pGroupBy;
  w.pParse = pParse;
  sqlite3WalkExpr(&w, p);
  return w.eCode;
}

/*
** Walk an expression tree for the DEFAULT field of a column definition
** in a CREATE TABLE statement.  Return non-zero if the expression is 
** Walk an expression tree.  Return non-zero if the expression is constant
** acceptable for use as a DEFAULT.  That is to say, return non-zero if
** the expression is constant or a function call with constant arguments.
** Return and 0 if there are any variables.
** or a function call with constant arguments.  Return and 0 if there
** are any variables.
**
** isInit is true when parsing from sqlite_schema.  isInit is false when
** processing a new CREATE TABLE statement.  When isInit is true, parameters
** (such as ? or $abc) in the expression are converted into NULL.  When
** isInit is false, parameters raise an error.  Parameters should not be
** allowed in a CREATE TABLE statement, but some legacy versions of SQLite
** allowed it, so we need to support it when reading sqlite_schema for
** backwards compatibility.
**
** If isInit is true, set EP_FromDDL on every TK_FUNCTION node.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
  assert( isInit==0 || isInit==1 );
2263
2264
2265
2266
2267
2268
2269
2270

2271
2272
2273
2274
2275
2276
2277
2077
2078
2079
2080
2081
2082
2083

2084
2085
2086
2087
2088
2089
2090
2091







-
+







** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
  int rc = 0;
  if( NEVER(p==0) ) return 0;  /* Used to only happen following on OOM */
  if( p==0 ) return 0;  /* Can only happen following on OOM */

  /* If an expression is an integer literal that fits in a signed 32-bit
  ** integer, then the EP_IntValue flag will have already been set */
  assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
           || sqlite3GetInt32(p->u.zToken, &rc)==0 );

  if( p->flags & EP_IntValue ){
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332

2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352

2353
2354
2355
2356
2357
2358
2359
2360

2361
2362
2363

2364
2365
2366

2367
2368
2369

2370
2371
2372
2373


2374
2375
2376
2377
2378
2379
2380
2137
2138
2139
2140
2141
2142
2143



2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161

2162

2163



2164
2165
2166
2167

2168
2169
2170

2171
2172
2173

2174
2175
2176

2177
2178
2179
2180

2181
2182
2183
2184
2185
2186
2187
2188
2189







-
-
-
+

















-

-
+
-
-
-




-
+


-
+


-
+


-
+



-
+
+







    case TK_STRING:
    case TK_FLOAT:
    case TK_BLOB:
      return 0;
    case TK_COLUMN:
      return ExprHasProperty(p, EP_CanBeNull) ||
             p->y.pTab==0 ||  /* Reference to column of index on expression */
             (p->iColumn>=0
              && ALWAYS(p->y.pTab->aCol!=0) /* Defense against OOM problems */
              && p->y.pTab->aCol[p->iColumn].notNull==0);
             (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
    default:
      return 1;
  }
}

/*
** Return TRUE if the given expression is a constant which would be
** unchanged by OP_Affinity with the affinity given in the second
** argument.
**
** This routine is used to determine if the OP_Affinity operation
** can be omitted.  When in doubt return FALSE.  A false negative
** is harmless.  A false positive, however, can result in the wrong
** answer.
*/
int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
  u8 op;
  int unaryMinus = 0;
  if( aff==SQLITE_AFF_BLOB ) return 1;
  while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
  while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
    if( p->op==TK_UMINUS ) unaryMinus = 1;
    p = p->pLeft;
  }
  op = p->op;
  if( op==TK_REGISTER ) op = p->op2;
  switch( op ){
    case TK_INTEGER: {
      return aff>=SQLITE_AFF_NUMERIC;
      return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC;
    }
    case TK_FLOAT: {
      return aff>=SQLITE_AFF_NUMERIC;
      return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC;
    }
    case TK_STRING: {
      return !unaryMinus && aff==SQLITE_AFF_TEXT;
      return aff==SQLITE_AFF_TEXT;
    }
    case TK_BLOB: {
      return !unaryMinus;
      return 1;
    }
    case TK_COLUMN: {
      assert( p->iTable>=0 );  /* p cannot be part of a CHECK constraint */
      return aff>=SQLITE_AFF_NUMERIC && p->iColumn<0;
      return p->iColumn<0
          && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC);
    }
    default: {
      return 0;
    }
  }
}

2549
2550
2551
2552
2553
2554
2555
2556

2557
2558
2559
2560
2561
2562
2563
2358
2359
2360
2361
2362
2363
2364

2365
2366
2367
2368
2369
2370
2371
2372







-
+







**   CREATE INDEX i1 ON t1(b, c, a);
**
** then aiMap[] is populated with {2, 0, 1}.
*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3FindInIndex(
  Parse *pParse,             /* Parsing context */
  Expr *pX,                  /* The IN expression */
  Expr *pX,                  /* The right-hand side (RHS) of the IN operator */
  u32 inFlags,               /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
  int *prRhsHasNull,         /* Register holding NULL status.  See notes */
  int *aiMap,                /* Mapping from Index fields to RHS fields */
  int *piTab                 /* OUT: index to use */
){
  Select *p;                            /* SELECT to the right of IN operator */
  int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
2586
2587
2588
2589
2590
2591
2592
2593

2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2395
2396
2397
2398
2399
2400
2401

2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412

2413
2414
2415
2416
2417
2418
2419







-
+










-








  /* Check to see if an existing table or index can be used to
  ** satisfy the query.  This is preferable to generating a new 
  ** ephemeral table.  */
  if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
    sqlite3 *db = pParse->db;              /* Database connection */
    Table *pTab;                           /* Table <table>. */
    int iDb;                               /* Database idx for pTab */
    i16 iDb;                               /* Database idx for pTab */
    ExprList *pEList = p->pEList;
    int nExpr = pEList->nExpr;

    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);
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812


2813
2814
2815
2816
2817
2818
2819
2820
2611
2612
2613
2614
2615
2616
2617



2618
2619

2620
2621
2622
2623
2624
2625
2626







-
-
-
+
+
-







/*
** Load the Parse object passed as the first argument with an error 
** message of the form:
**
**   "sub-select returns N columns - expected M"
*/   
void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
  if( pParse->nErr==0 ){
    const char *zFmt = "sub-select returns %d columns - expected %d";
    sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
  const char *zFmt = "sub-select returns %d columns - expected %d";
  sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
  }
}
#endif

/*
** Expression pExpr is a vector that has been used in a context where
** it is not permitted. If pExpr is a sub-select vector, this routine 
** loads the Parse object with a message of the form:
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2706
2707
2708
2709
2710
2711
2712

2713
2714
2715
2716
2717
2718
2719







-







      sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
      sqlite3VdbeJumpHere(v, addrOnce);
      return;
    }

    /* Begin coding the subroutine */
    ExprSetProperty(pExpr, EP_Subrtn);
    assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
    pExpr->y.sub.regReturn = ++pParse->nMem;
    pExpr->y.sub.iAddr =
      sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
    VdbeComment((v, "return address"));

    addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  }
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
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044

3045
3046
3047
3048
3049
3050
3051
2783
2784
2785
2786
2787
2788
2789

2790
2791

2792
2793


2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812

2813
2814
2815
2816



2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831

2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844

2845
2846
2847
2848
2849
2850
2851
2852







-
+

-
+

-
-



















-




-
-
-
+
+
+












-













-
+







    ** that columns affinity when building index keys. If <expr> is not
    ** a column, use numeric affinity.
    */
    char affinity;            /* Affinity of the LHS of the IN */
    int i;
    ExprList *pList = pExpr->x.pList;
    struct ExprList_item *pItem;
    int r1, r2;
    int r1, r2, r3;
    affinity = sqlite3ExprAffinity(pLeft);
    if( affinity<=SQLITE_AFF_NONE ){
    if( !affinity ){
      affinity = SQLITE_AFF_BLOB;
    }else if( affinity==SQLITE_AFF_REAL ){
      affinity = SQLITE_AFF_NUMERIC;
    }
    if( pKeyInfo ){
      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    }

    /* Loop through each expression in <exprlist>. */
    r1 = sqlite3GetTempReg(pParse);
    r2 = sqlite3GetTempReg(pParse);
    for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
      Expr *pE2 = pItem->pExpr;

      /* If the expression is not constant then we will need to
      ** disable the test that was generated above that makes sure
      ** this code only executes once.  Because for a non-constant
      ** expression we need to rerun this code each time.
      */
      if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
        sqlite3VdbeChangeToNoop(v, addrOnce);
        ExprClearProperty(pExpr, EP_Subrtn);
        addrOnce = 0;
      }

      /* Evaluate the expression and insert it into the temp table */
      sqlite3ExprCode(pParse, pE2, r1);
      sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1);
      r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
      sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
    }
    sqlite3ReleaseTempReg(pParse, r1);
    sqlite3ReleaseTempReg(pParse, r2);
  }
  if( pKeyInfo ){
    sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
  }
  if( addrOnce ){
    sqlite3VdbeJumpHere(v, addrOnce);
    /* Subroutine return */
    sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
    sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
    sqlite3ClearTempRegCache(pParse);
  }
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
** Generate code for scalar subqueries used as a subquery expression
** or EXISTS operator:
**
**     (SELECT a FROM b)          -- subquery
**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
**
** The pExpr parameter is the SELECT or EXISTS operator to be coded.
**
** Return the register that holds the result.  For a multi-column SELECT, 
** The register that holds the result.  For a multi-column SELECT, 
** the result is stored in a contiguous array of registers and the
** return value is the register of the left-most result column.
** Return 0 if an error occurs.
*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  int addrOnce = 0;           /* Address of OP_Once at top of subroutine */
3115
3116
3117
3118
3119
3120
3121

3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132

3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
2916
2917
2918
2919
2920
2921
2922
2923
2924










2925
2926
2927


2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941

2942
2943
2944
2945
2946
2947
2948







+

-
-
-
-
-
-
-
-
-
-
+


-
-














-







    sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
    VdbeComment((v, "Init subquery result"));
  }else{
    dest.eDest = SRT_Exists;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
    VdbeComment((v, "Init EXISTS result"));
  }
  pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
  if( pSel->pLimit ){
    /* The subquery already has a limit.  If the pre-existing limit is X
    ** then make the new limit X<>0 so that the new limit is either 1 or 0 */
    sqlite3 *db = pParse->db;
    pLimit = sqlite3Expr(db, TK_INTEGER, "0");
    if( pLimit ){
      pLimit->affExpr = SQLITE_AFF_NUMERIC;
      pLimit = sqlite3PExpr(pParse, TK_NE,
                            sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit);
    }
    sqlite3ExprDelete(db, pSel->pLimit->pLeft);
    sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
    pSel->pLimit->pLeft = pLimit;
  }else{
    /* If there is no pre-existing limit add a limit of 1 */
    pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
    pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
  }
  pSel->iLimit = 0;
  if( sqlite3Select(pParse, pSel, &dest) ){
    return 0;
  }
  pExpr->iTable = rReg = dest.iSDParm;
  ExprSetVVAProperty(pExpr, EP_NoReduce);
  if( addrOnce ){
    sqlite3VdbeJumpHere(v, addrOnce);

    /* Subroutine return */
    sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
    sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
    sqlite3ClearTempRegCache(pParse);
  }

  return rReg;
}
#endif /* SQLITE_OMIT_SUBQUERY */

#ifndef SQLITE_OMIT_SUBQUERY
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3012
3013
3014
3015
3016
3017
3018

3019

3020
3021
3022
3023
3024
3025
3026







-

-







  int i;                /* loop counter */
  int destStep2;        /* Where to jump when NULLs seen in step 2 */
  int destStep6 = 0;    /* Start of code for Step 6 */
  int addrTruthOp;      /* Address of opcode that determines the IN is true */
  int destNotNull;      /* Jump here if a comparison is not true in step 6 */
  int addrTop;          /* Top of the step-6 loop */ 
  int iTab = 0;         /* Index to use */
  u8 okConstFactor = pParse->okConstFactor;

  assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
  pLeft = pExpr->pLeft;
  if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
  zAff = exprINAffinity(pParse, pExpr);
  nVector = sqlite3ExprVectorSize(pExpr->pLeft);
  aiMap = (int*)sqlite3DbMallocZero(
      pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
  );
3267
3268
3269
3270
3271
3272
3273
3274

3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3055
3056
3057
3058
3059
3060
3061

3062





3063

3064
3065
3066
3067
3068
3069
3070







-
+
-
-
-
-
-

-







  ** vector, then it is stored in an array of nVector registers starting 
  ** at r1.
  **
  ** sqlite3FindInIndex() might have reordered the fields of the LHS vector
  ** so that the fields are in the same order as an existing index.   The
  ** aiMap[] array contains a mapping from the original LHS field order to
  ** the field order that matches the RHS index.
  **
  */
  ** Avoid factoring the LHS of the IN(...) expression out of the loop,
  ** even if it is constant, as OP_Affinity may be used on the register
  ** by code generated below.  */
  assert( pParse->okConstFactor==okConstFactor );
  pParse->okConstFactor = 0;
  rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
  pParse->okConstFactor = okConstFactor;
  for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
  if( i==nVector ){
    /* LHS fields are not reordered */
    rLhs = rLhsOrig;
  }else{
    /* Need to reorder the LHS fields according to aiMap */
    rLhs = sqlite3GetTempRange(pParse, nVector);
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320

3321
3322
3323


3324
3325
3326
3327
3328
3329
3330
3331


3332
3333
3334
3335

3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3092
3093
3094
3095
3096
3097
3098

3099


3100
3101


3102
3103


3104
3105

3106


3107
3108


3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130

3131
3132
3133
3134
3135
3136
3137







-

-
-
+

-
-
+
+
-
-


-

-
-
+
+
-
-


+



















-







      sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
    }
    for(ii=0; ii<pList->nExpr; ii++){
      r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
      if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
        sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
      }
      sqlite3ReleaseTempReg(pParse, regToFree);
      if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){
        int op = rLhs!=r2 ? OP_Eq : OP_NotNull;
        sqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2,
        sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2,
                          (void*)pColl, P4_COLLSEQ);
        VdbeCoverageIf(v, ii<pList->nExpr-1 && op==OP_Eq);
        VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq);
        VdbeCoverageIf(v, ii<pList->nExpr-1);
        VdbeCoverageIf(v, ii==pList->nExpr-1);
        VdbeCoverageIf(v, ii<pList->nExpr-1 && op==OP_NotNull);
        VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull);
        sqlite3VdbeChangeP5(v, zAff[0]);
      }else{
        int op = rLhs!=r2 ? OP_Ne : OP_IsNull;
        assert( destIfNull==destIfFalse );
        sqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2,
                          (void*)pColl, P4_COLLSEQ);
        sqlite3VdbeAddOp4(v, OP_Ne, rLhs, destIfFalse, r2,
                          (void*)pColl, P4_COLLSEQ); VdbeCoverage(v);
        VdbeCoverageIf(v, op==OP_Ne);
        VdbeCoverageIf(v, op==OP_IsNull);
        sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL);
      }
      sqlite3ReleaseTempReg(pParse, regToFree);
    }
    if( regCkNull ){
      sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
      sqlite3VdbeGoto(v, destIfFalse);
    }
    sqlite3VdbeResolveLabel(v, labelOk);
    sqlite3ReleaseTempReg(pParse, regCkNull);
    goto sqlite3ExprCodeIN_finished;
  }

  /* Step 2: Check to see if the LHS contains any NULL columns.  If the
  ** LHS does contain NULLs then the result must be either FALSE or NULL.
  ** We will then skip the binary search of the RHS.
  */
  if( destIfNull==destIfFalse ){
    destStep2 = destIfFalse;
  }else{
    destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
  }
  if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
  for(i=0; i<nVector; i++){
    Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
    if( sqlite3ExprCanBeNull(p) ){
      sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
      VdbeCoverage(v);
    }
  }
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568

3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585

3586
3587

3588
3589
3590
3591
3592
3593
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
3305
3306
3307
3308
3309
3310
3311



























3312
3313
3314
3315

3316
3317
3318
3319
3320
3321


3322
3323
3324
3325
3326
3327
3328



3329


3330
















3331


3332





3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356


3357
3358
3359

3360

3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378

3379


3380
3381
3382
3383
3384
3385
3386







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




-
+





-
-







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


+
+



















+
-
-
+
+

-
+
-









+








-
+
-
-







    pParse->iSelfTab = 0;
  }else{
    sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
                                    iTabCol, regOut);
  }
}

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/*
** Generate code that will compute the value of generated column pCol
** and store the result in register regOut
*/
void sqlite3ExprCodeGeneratedColumn(
  Parse *pParse,
  Column *pCol,
  int regOut
){
  int iAddr;
  Vdbe *v = pParse->pVdbe;
  assert( v!=0 );
  assert( pParse->iSelfTab!=0 );
  if( pParse->iSelfTab>0 ){
    iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut);
  }else{
    iAddr = 0;
  }
  sqlite3ExprCodeCopy(pParse, pCol->pDflt, regOut);
  if( pCol->affinity>=SQLITE_AFF_TEXT ){
    sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
  }
  if( iAddr ) sqlite3VdbeJumpHere(v, iAddr);
}
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */

/*
** Generate code to extract the value of the iCol-th column of a table.
*/
void sqlite3ExprCodeGetColumnOfTable(
  Vdbe *v,        /* Parsing context */
  Vdbe *v,        /* The VDBE under construction */
  Table *pTab,    /* The table containing the value */
  int iTabCur,    /* The table cursor.  Or the PK cursor for WITHOUT ROWID */
  int iCol,       /* Index of the column to extract */
  int regOut      /* Extract the value into this register */
){
  Column *pCol;
  assert( v!=0 );
  if( pTab==0 ){
    sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
    return;
  }
  if( iCol<0 || iCol==pTab->iPKey ){
    sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
  }else{
    int op;
    int x;
    if( IsVirtual(pTab) ){
    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
      op = OP_VColumn;
      x = iCol;
    int x = iCol;
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
    }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){
      Parse *pParse = sqlite3VdbeParser(v);
      if( pCol->colFlags & COLFLAG_BUSY ){
        sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName);
      }else{
        int savedSelfTab = pParse->iSelfTab;
        pCol->colFlags |= COLFLAG_BUSY;
        pParse->iSelfTab = iTabCur+1;
        sqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut);
        pParse->iSelfTab = savedSelfTab;
        pCol->colFlags &= ~COLFLAG_BUSY;
      }
      return;
#endif
    }else if( !HasRowid(pTab) ){
    if( !HasRowid(pTab) && !IsVirtual(pTab) ){
      testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) );
      x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
      x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
      op = OP_Column;
    }else{
      x = sqlite3TableColumnToStorage(pTab,iCol);
      testcase( x!=iCol );
      op = OP_Column;
    }
    sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
  }
  if( iCol>=0 ){
    sqlite3ColumnDefault(v, pTab, iCol, regOut);
  }
}

/*
** Generate code that will extract the iColumn-th column from
** table pTab and store the column value in register iReg. 
**
** There must be an open cursor to pTab in iTable when this routine
** is called.  If iColumn<0 then code is generated that extracts the rowid.
*/
int sqlite3ExprCodeGetColumn(
  Parse *pParse,   /* Parsing and code generating context */
  Table *pTab,     /* Description of the table we are reading from */
  int iColumn,     /* Index of the table column */
  int iTable,      /* The cursor pointing to the table */
  int iReg,        /* Store results here */
  u8 p5            /* P5 value for OP_Column + FLAGS */
){
  Vdbe *v = pParse->pVdbe;
  assert( pParse->pVdbe!=0 );
  sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg);
  assert( v!=0 );
  sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
  if( p5 ){
    VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
    sqlite3VdbeChangeP5(v, p5);
    if( pOp->opcode==OP_Column ) pOp->p5 = p5;
  }
  return iReg;
}

/*
** Generate code to move content from registers iFrom...iFrom+nReg-1
** over to iTo..iTo+nReg-1.
*/
void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
  assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
  sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
}

/*
** Convert a scalar expression node to a TK_REGISTER referencing
** register iReg.  The caller must ensure that iReg already contains
** the correct value for the expression.
*/
static void exprToRegister(Expr *pExpr, int iReg){
static void exprToRegister(Expr *p, int iReg){
  Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
  if( NEVER(p==0) ) return;
  p->op2 = p->op;
  p->op = TK_REGISTER;
  p->iTable = iReg;
  ExprClearProperty(p, EP_Skip);
}

/*
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3414
3415
3416
3417
3418
3419
3420






















































































































3421
3422
3423
3424
3425
3426
3427







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







        sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
      }
    }
  }
  return iResult;
}

/*
** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5)
** so that a subsequent copy will not be merged into this one.
*/
static void setDoNotMergeFlagOnCopy(Vdbe *v){
  if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){
    sqlite3VdbeChangeP5(v, 1);  /* Tag trailing OP_Copy as not mergable */
  }
}

/*
** Generate code to implement special SQL functions that are implemented
** in-line rather than by using the usual callbacks.
*/
static int exprCodeInlineFunction(
  Parse *pParse,        /* Parsing context */
  ExprList *pFarg,      /* List of function arguments */
  int iFuncId,          /* Function ID.  One of the INTFUNC_... values */
  int target            /* Store function result in this register */
){
  int nFarg;
  Vdbe *v = pParse->pVdbe;
  assert( v!=0 );
  assert( pFarg!=0 );
  nFarg = pFarg->nExpr;
  assert( nFarg>0 );  /* All in-line functions have at least one argument */
  switch( iFuncId ){
    case INLINEFUNC_coalesce: {
      /* Attempt a direct implementation of the built-in COALESCE() and
      ** IFNULL() functions.  This avoids unnecessary evaluation of
      ** arguments past the first non-NULL argument.
      */
      int endCoalesce = sqlite3VdbeMakeLabel(pParse);
      int i;
      assert( nFarg>=2 );
      sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
      for(i=1; i<nFarg; i++){
        sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
        VdbeCoverage(v);
        sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
      }
      setDoNotMergeFlagOnCopy(v);
      sqlite3VdbeResolveLabel(v, endCoalesce);
      break;
    }
    case INLINEFUNC_iif: {
      Expr caseExpr;
      memset(&caseExpr, 0, sizeof(caseExpr));
      caseExpr.op = TK_CASE;
      caseExpr.x.pList = pFarg;
      return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
    }

    default: {   
      /* The UNLIKELY() function is a no-op.  The result is the value
      ** of the first argument.
      */
      assert( nFarg==1 || nFarg==2 );
      target = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
      break;
    }

  /***********************************************************************
  ** Test-only SQL functions that are only usable if enabled
  ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
  */
    case INLINEFUNC_expr_compare: {
      /* Compare two expressions using sqlite3ExprCompare() */
      assert( nFarg==2 );
      sqlite3VdbeAddOp2(v, OP_Integer, 
         sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
         target);
      break;
    }

    case INLINEFUNC_expr_implies_expr: {
      /* Compare two expressions using sqlite3ExprImpliesExpr() */
      assert( nFarg==2 );
      sqlite3VdbeAddOp2(v, OP_Integer, 
         sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
         target);
      break;
    }

    case INLINEFUNC_implies_nonnull_row: {
      /* REsult of sqlite3ExprImpliesNonNullRow() */
      Expr *pA1;
      assert( nFarg==2 );
      pA1 = pFarg->a[1].pExpr;
      if( pA1->op==TK_COLUMN ){
        sqlite3VdbeAddOp2(v, OP_Integer, 
           sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable),
           target);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      }
      break;
    }

#ifdef SQLITE_DEBUG
    case INLINEFUNC_affinity: {
      /* The AFFINITY() function evaluates to a string that describes
      ** the type affinity of the argument.  This is used for testing of
      ** the SQLite type logic.
      */
      const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
      char aff;
      assert( nFarg==1 );
      aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
      sqlite3VdbeLoadString(v, target, 
              (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
      break;
    }
#endif
  }
  return target;
}


/*
** Generate code into the current Vdbe to evaluate the given
** expression.  Attempt to store the results in register "target".
** Return the register where results are stored.
**
** With this routine, there is no guarantee that results will
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
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886

3887
3888

3889
3890
3891
3892

3893
3894
3895




3896
3897
3898
3899
3900
3901
3902
3903

3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
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
3437
3438
3439
3440
3441
3442
3443
3444

3445
3446
3447
3448
3449
3450
3451
3452

3453
3454
3455
3456
3457

3458



3459
3460
3461
3462

3463
3464








3465
3466
3467

3468
3469
3470

3471
3472
3473
3474
3475
3476
3477


3478


3479




3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494

3495














3496


























3497
3498
3499
3500
3501
3502

3503
3504
3505




3506
3507
3508
3509
3510
3511
3512







+
-
+
+
+





-





-
+
-
-
-




-


-
-
-
-
-
-
-
-



-



-







-
-
+
-
-
+
-
-
-
-
+



+
+
+
+







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






-
+


-
-
-
-







  int regFree1 = 0;         /* If non-zero free this temporary register */
  int regFree2 = 0;         /* If non-zero free this temporary register */
  int r1, r2;               /* Various register numbers */
  Expr tempX;               /* Temporary expression node */
  int p5 = 0;

  assert( target>0 && target<=pParse->nMem );
  if( v==0 ){
  assert( v!=0 );
    assert( pParse->db->mallocFailed );
    return 0;
  }

expr_code_doover:
  if( pExpr==0 ){
    op = TK_NULL;
  }else{
    assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
    op = pExpr->op;
  }
  switch( op ){
    case TK_AGG_COLUMN: {
      AggInfo *pAggInfo = pExpr->pAggInfo;
      struct AggInfo_col *pCol;
      struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
      assert( pAggInfo!=0 );
      assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
      pCol = &pAggInfo->aCol[pExpr->iAgg];
      if( !pAggInfo->directMode ){
        assert( pCol->iMem>0 );
        return pCol->iMem;
      }else if( pAggInfo->useSortingIdx ){
        Table *pTab = pCol->pTab;
        sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
                              pCol->iSorterColumn, target);
        if( pCol->iColumn<0 ){
          VdbeComment((v,"%s.rowid",pTab->zName));
        }else{
          VdbeComment((v,"%s.%s",pTab->zName,pTab->aCol[pCol->iColumn].zName));
          if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){
            sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
          }
        }
        return target;
      }
      /* Otherwise, fall thru into the TK_COLUMN case */
      /* no break */ deliberate_fall_through
    }
    case TK_COLUMN: {
      int iTab = pExpr->iTable;
      int iReg;
      if( ExprHasProperty(pExpr, EP_FixedCol) ){
        /* This COLUMN expression is really a constant due to WHERE clause
        ** constraints, and that constant is coded by the pExpr->pLeft
        ** expresssion.  However, make sure the constant has the correct
        ** datatype by applying the Affinity of the table column to the
        ** constant.
        */
        int aff;
        iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
        int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
        if( pExpr->y.pTab ){
          aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
        int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
        }else{
          aff = pExpr->affExpr;
        }
        if( aff>SQLITE_AFF_BLOB ){
        if( aff!=SQLITE_AFF_BLOB ){
          static const char zAff[] = "B\000C\000D\000E";
          assert( SQLITE_AFF_BLOB=='A' );
          assert( SQLITE_AFF_TEXT=='B' );
          if( iReg!=target ){
            sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
            iReg = target;
          }
          sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
                            &zAff[(aff-'B')*2], P4_STATIC);
        }
        return iReg;
      }
      if( iTab<0 ){
        if( pParse->iSelfTab<0 ){
          /* Other columns in the same row for CHECK constraints or
          /* Generating CHECK constraints or inserting into partial index */
          ** generated columns or for inserting into partial index.
          ** The row is unpacked into registers beginning at
          ** 0-(pParse->iSelfTab).  The rowid (if any) is in a register
          ** immediately prior to the first column.
          */
          Column *pCol;
          Table *pTab = pExpr->y.pTab;
          int iSrc;
          int iCol = pExpr->iColumn;
          assert( pTab!=0 );
          assert( iCol>=XN_ROWID );
          assert( iCol<pTab->nCol );
          if( iCol<0 ){
            return -1-pParse->iSelfTab;
          return pExpr->iColumn - pParse->iSelfTab;
          }
          pCol = pTab->aCol + iCol;
          testcase( iCol!=sqlite3TableColumnToStorage(pTab,iCol) );
          iSrc = sqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab;
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
          if( pCol->colFlags & COLFLAG_GENERATED ){
            if( pCol->colFlags & COLFLAG_BUSY ){
              sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"",
                              pCol->zName);
              return 0;
            }
            pCol->colFlags |= COLFLAG_BUSY;
            if( pCol->colFlags & COLFLAG_NOTAVAIL ){
              sqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc);
            }
            pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL);
            return iSrc;
          }else
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
          if( pCol->affinity==SQLITE_AFF_REAL ){
            sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target);
            sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
            return target;
          }else{
            return iSrc;
          }
        }else{
          /* Coding an expression that is part of an index where column names
          ** in the index refer to the table to which the index belongs */
          iTab = pParse->iSelfTab - 1;
        }
      }
      iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
      return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
                               pExpr->iColumn, iTab, target,
                               pExpr->op2);
      if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){
        sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
      }
      return iReg;
    }
    case TK_INTEGER: {
      codeInteger(pParse, pExpr, 0, target);
      return target;
    }
    case TK_TRUEFALSE: {
      sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target);
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983

3984
3985
3986
3987
3988
3989
3990
3520
3521
3522
3523
3524
3525
3526






3527
3528
3529
3530
3531
3532
3533
3534







-
-
-
-
-
-
+







    }
#endif
    case TK_STRING: {
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
      return target;
    }
    default: {
      /* Make NULL the default case so that if a bug causes an illegal
      ** Expr node to be passed into this function, it will be handled
      ** sanely and not crash.  But keep the assert() to bring the problem
      ** to the attention of the developers. */
      assert( op==TK_NULL );
    case TK_NULL: {
      sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      return target;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case TK_BLOB: {
      int n;
      const char *z;
4003
4004
4005
4006
4007
4008
4009
4010

4011
4012
4013
4014
4015
4016
4017
3547
3548
3549
3550
3551
3552
3553

3554
3555
3556
3557
3558
3559
3560
3561







-
+







    case TK_VARIABLE: {
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      assert( pExpr->u.zToken!=0 );
      assert( pExpr->u.zToken[0]!=0 );
      sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
      if( pExpr->u.zToken[1]!=0 ){
        const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
        assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) );
        assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
        pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
        sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
      }
      return target;
    }
    case TK_REGISTER: {
      return pExpr->iTable;
4043
4044
4045
4046
4047
4048
4049
4050

4051
4052
4053
4054
4055
4056
4057
4058
3587
3588
3589
3590
3591
3592
3593

3594

3595
3596
3597
3598
3599
3600
3601







-
+
-







      Expr *pLeft = pExpr->pLeft;
      if( sqlite3ExprIsVector(pLeft) ){
        codeVectorCompare(pParse, pExpr, target, op, p5);
      }else{
        r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
        r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
        codeCompare(pParse, pLeft, pExpr->pRight, op,
            r1, r2, inReg, SQLITE_STOREP2 | p5,
            r1, r2, inReg, SQLITE_STOREP2 | p5);
            ExprHasProperty(pExpr,EP_Commuted));
        assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
        assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
        assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
        assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
        assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
        assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
        testcase( regFree1==0 );
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
3645
3646
3647
3648
3649
3650
3651

3652
3653
3654
3655
3656
3657
3658







-







        codeReal(v, pLeft->u.zToken, 1, target);
        return target;
#endif
      }else{
        tempX.op = TK_INTEGER;
        tempX.flags = EP_IntValue|EP_TokenOnly;
        tempX.u.iValue = 0;
        ExprClearVVAProperties(&tempX);
        r1 = sqlite3ExprCodeTemp(pParse, &tempX, &regFree1);
        r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree2);
        sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
        testcase( regFree2==0 );
      }
      break;
    }
4148
4149
4150
4151
4152
4153
4154
4155

4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
3690
3691
3692
3693
3694
3695
3696

3697



3698
3699
3700
3701
3702
3703
3704







-
+
-
-
-







      VdbeCoverageIf(v, op==TK_NOTNULL);
      sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
      sqlite3VdbeJumpHere(v, addr);
      break;
    }
    case TK_AGG_FUNCTION: {
      AggInfo *pInfo = pExpr->pAggInfo;
      if( pInfo==0
      if( pInfo==0 ){
       || NEVER(pExpr->iAgg<0)
       || NEVER(pExpr->iAgg>=pInfo->nFunc)
      ){
        assert( !ExprHasProperty(pExpr, EP_IntValue) );
        sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
      }else{
        return pInfo->aFunc[pExpr->iAgg].iMem;
      }
      break;
    }
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186



4187
4188
4189
4190





4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203





4204
4205
4206
4207
4208
4209
4210


































4211

4212
4213
4214
4215
4216
4217
4218
3716
3717
3718
3719
3720
3721
3722



3723
3724
3725
3726
3727


3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750







3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793







-
-
-
+
+
+


-
-
+
+
+
+
+













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

+







#ifndef SQLITE_OMIT_WINDOWFUNC
      if( ExprHasProperty(pExpr, EP_WinFunc) ){
        return pExpr->y.pWin->regResult;
      }
#endif

      if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
        /* SQL functions can be expensive. So try to avoid running them
        ** multiple times if we know they always give the same result */
        return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
        /* SQL functions can be expensive. So try to move constant functions
        ** out of the inner loop, even if that means an extra OP_Copy. */
        return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
      }
      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
      assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
      pFarg = pExpr->x.pList;
      if( ExprHasProperty(pExpr, EP_TokenOnly) ){
        pFarg = 0;
      }else{
        pFarg = pExpr->x.pList;
      }
      nFarg = pFarg ? pFarg->nExpr : 0;
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      zId = pExpr->u.zToken;
      pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
      if( pDef==0 && pParse->explain ){
        pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
      }
#endif
      if( pDef==0 || pDef->xFinalize!=0 ){
        sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
        break;
      }

      /* Attempt a direct implementation of the built-in COALESCE() and
      ** IFNULL() functions.  This avoids unnecessary evaluation of
      ** arguments past the first non-NULL argument.
      */
      if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
        assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
        assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
        return exprCodeInlineFunction(pParse, pFarg,
             SQLITE_PTR_TO_INT(pDef->pUserData), target);
      }else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){
        sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
      if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
        int endCoalesce = sqlite3VdbeMakeLabel(pParse);
        assert( nFarg>=2 );
        sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
        for(i=1; i<nFarg; i++){
          sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
          VdbeCoverage(v);
          sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
        }
        sqlite3VdbeResolveLabel(v, endCoalesce);
        break;
      }

      /* The UNLIKELY() function is a no-op.  The result is the value
      ** of the first argument.
      */
      if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
        assert( nFarg>=1 );
        return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
      }

#ifdef SQLITE_DEBUG
      /* The AFFINITY() function evaluates to a string that describes
      ** the type affinity of the argument.  This is used for testing of
      ** the SQLite type logic.
      */
      if( pDef->funcFlags & SQLITE_FUNC_AFFINITY ){
        const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
        char aff;
        assert( nFarg==1 );
        aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
        sqlite3VdbeLoadString(v, target, 
                              aff ? azAff[aff-SQLITE_AFF_BLOB] : "none");
        return target;
      }
#endif

      for(i=0; i<nFarg; i++){
        if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
          testcase( i==31 );
          constMask |= MASKBIT32(i);
        }
        if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
4281
4282
4283
4284
4285
4286
4287

4288

4289

4290
4291

4292
4293

4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308

4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322


4323
4324
4325
4326
4327
4328
4329
3856
3857
3858
3859
3860
3861
3862
3863

3864

3865
3866

3867


3868



3869
3870
3871
3872
3873
3874
3875
3876
3877



3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890


3891
3892
3893
3894
3895
3896
3897
3898
3899







+
-
+
-
+

-
+
-
-
+
-
-
-









-
-
-
+












-
-
+
+







          sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
        }else{
          sqlite3VdbeAddOp2(v, OP_Null, 0, target);
        }
      }else
#endif
      {
        sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
        sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
                          constMask, r1, target, (char*)pDef, P4_FUNCDEF);
                                   pDef, pExpr->op2);
        sqlite3VdbeChangeP5(v, (u8)nFarg);
      }
      if( nFarg ){
      if( nFarg && constMask==0 ){
        if( constMask==0 ){
          sqlite3ReleaseTempRange(pParse, r1, nFarg);
        sqlite3ReleaseTempRange(pParse, r1, nFarg);
        }else{
          sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1);
        }
      }
      return target;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      int nCol;
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );
      if( pParse->db->mallocFailed ){
        return 0;
      }else if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
      if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
        sqlite3SubselectError(pParse, nCol, 1);
      }else{
        return sqlite3CodeSubselect(pParse, pExpr);
      }
      break;
    }
    case TK_SELECT_COLUMN: {
      int n;
      if( pExpr->pLeft->iTable==0 ){
        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
      }
      assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
      if( pExpr->iTable!=0
       && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft))
      if( pExpr->iTable
       && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) 
      ){
        sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
                                pExpr->iTable, n);
      }
      return pExpr->pLeft->iTable + pExpr->iColumn;
    }
    case TK_IN: {
4385
4386
4387
4388
4389
4390
4391
4392
4393

4394
4395
4396
4397
4398


4399
4400
4401
4402
4403
4404

4405
4406
4407
4408
4409
4410
4411
4412

4413


4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
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







-
-
+
-


-
-
+
+





-
+








+
-
+
+











-
-
-
-
-
-


-

-
-
-
-
-

-







      ** Then p1 is interpreted as follows:
      **
      **   p1==0   ->    old.rowid     p1==3   ->    new.rowid
      **   p1==1   ->    old.a         p1==4   ->    new.a
      **   p1==2   ->    old.b         p1==5   ->    new.b       
      */
      Table *pTab = pExpr->y.pTab;
      int iCol = pExpr->iColumn;
      int p1 = pExpr->iTable * (pTab->nCol+1) + 1 
      int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
                     + sqlite3TableColumnToStorage(pTab, iCol);

      assert( pExpr->iTable==0 || pExpr->iTable==1 );
      assert( iCol>=-1 && iCol<pTab->nCol );
      assert( pTab->iPKey<0 || iCol!=pTab->iPKey );
      assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
      assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
      assert( p1>=0 && p1<(pTab->nCol*2+2) );

      sqlite3VdbeAddOp2(v, OP_Param, p1, target);
      VdbeComment((v, "r[%d]=%s.%s", target,
        (pExpr->iTable ? "new" : "old"),
        (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zName)
        (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
      ));

#ifndef SQLITE_OMIT_FLOATING_POINT
      /* If the column has REAL affinity, it may currently be stored as an
      ** integer. Use OP_RealAffinity to make sure it is really real.
      **
      ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
      ** floating point when extracting it from the record.  */
      if( pExpr->iColumn>=0 
      if( iCol>=0 && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){
       && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
      ){
        sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
      }
#endif
      break;
    }

    case TK_VECTOR: {
      sqlite3ErrorMsg(pParse, "row value misused");
      break;
    }

    /* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions
    ** that derive from the right-hand table of a LEFT JOIN.  The
    ** Expr.iTable value is the table number for the right-hand table.
    ** The expression is only evaluated if that table is not currently
    ** on a LEFT JOIN NULL row.
    */
    case TK_IF_NULL_ROW: {
      int addrINR;
      u8 okConstFactor = pParse->okConstFactor;
      addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
      /* Temporarily disable factoring of constant expressions, since
      ** even though expressions may appear to be constant, they are not
      ** really constant because they originate from the right-hand side
      ** of a LEFT JOIN. */
      pParse->okConstFactor = 0;
      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
      pParse->okConstFactor = okConstFactor;
      sqlite3VdbeJumpHere(v, addrINR);
      sqlite3VdbeChangeP3(v, addrINR, inReg);
      break;
    }

    /*
    ** Form A:
4461
4462
4463
4464
4465
4466
4467
4468

4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488

4489
4490
4491
4492
4493
4494

4495
4496
4497
4498

4499
4500
4501
4502
4503
4504
4505
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







-
+









-
-








-
+
-
-
-
-

-
+



-
+







    ** is even, then Y is omitted and the "otherwise" result is NULL.
    ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1].
    **
    ** The result of the expression is the Ri for the first matching Ei,
    ** or if there is no matching Ei, the ELSE term Y, or if there is
    ** no ELSE term, NULL.
    */
    case TK_CASE: {
    default: assert( op==TK_CASE ); {
      int endLabel;                     /* GOTO label for end of CASE stmt */
      int nextCase;                     /* GOTO label for next WHEN clause */
      int nExpr;                        /* 2x number of WHEN terms */
      int i;                            /* Loop counter */
      ExprList *pEList;                 /* List of WHEN terms */
      struct ExprList_item *aListelem;  /* Array of WHEN terms */
      Expr opCompare;                   /* The X==Ei expression */
      Expr *pX;                         /* The X expression */
      Expr *pTest = 0;                  /* X==Ei (form A) or just Ei (form B) */
      Expr *pDel = 0;
      sqlite3 *db = pParse->db;

      assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
      assert(pExpr->x.pList->nExpr > 0);
      pEList = pExpr->x.pList;
      aListelem = pEList->a;
      nExpr = pEList->nExpr;
      endLabel = sqlite3VdbeMakeLabel(pParse);
      if( (pX = pExpr->pLeft)!=0 ){
        pDel = sqlite3ExprDup(db, pX, 0);
        exprNodeCopy(&tempX, pX);
        if( db->mallocFailed ){
          sqlite3ExprDelete(db, pDel);
          break;
        }
        testcase( pX->op==TK_COLUMN );
        exprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1));
        exprToRegister(&tempX, exprCodeVector(pParse, &tempX, &regFree1));
        testcase( regFree1==0 );
        memset(&opCompare, 0, sizeof(opCompare));
        opCompare.op = TK_EQ;
        opCompare.pLeft = pDel;
        opCompare.pLeft = &tempX;
        pTest = &opCompare;
        /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
        ** The value in regFree1 might get SCopy-ed into the file result.
        ** So make sure that the regFree1 register is not reused for other
        ** purposes and possibly overwritten.  */
        regFree1 = 0;
      }
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536




4537
4538

4539
4540
4541
4542
4543

4544
4545
4546
4547

4548
4549
4550
4551
4552

4553
4554

4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567

4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579


4580
4581
4582
4583

4584
4585
4586
4587
4588
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
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
4648
4649

4650
4651
4652
4653
4654
4655
4656
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
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







-
-





-
-
-
-
+
+
+
+

-
+




-
+



-
+




-
+
-
-
+












-
+
-
-
-
-
-
-




-
-
+
+
-
-

-
+

















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


















-
+

-




-
+







        sqlite3VdbeResolveLabel(v, nextCase);
      }
      if( (nExpr&1)!=0 ){
        sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      }
      sqlite3ExprDelete(db, pDel);
      setDoNotMergeFlagOnCopy(v);
      sqlite3VdbeResolveLabel(v, endLabel);
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      assert( pExpr->affExpr==OE_Rollback 
           || pExpr->affExpr==OE_Abort
           || pExpr->affExpr==OE_Fail
           || pExpr->affExpr==OE_Ignore
      assert( pExpr->affinity==OE_Rollback 
           || pExpr->affinity==OE_Abort
           || pExpr->affinity==OE_Fail
           || pExpr->affinity==OE_Ignore
      );
      if( !pParse->pTriggerTab && !pParse->nested ){
      if( !pParse->pTriggerTab ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
        return 0;
      }
      if( pExpr->affExpr==OE_Abort ){
      if( pExpr->affinity==OE_Abort ){
        sqlite3MayAbort(pParse);
      }
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      if( pExpr->affExpr==OE_Ignore ){
      if( pExpr->affinity==OE_Ignore ){
        sqlite3VdbeAddOp4(
            v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
        VdbeCoverage(v);
      }else{
        sqlite3HaltConstraint(pParse,
        sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
             pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
             pExpr->affExpr, pExpr->u.zToken, 0, 0);
                              pExpr->affinity, pExpr->u.zToken, 0, 0);
      }

      break;
    }
#endif
  }
  sqlite3ReleaseTempReg(pParse, regFree1);
  sqlite3ReleaseTempReg(pParse, regFree2);
  return inReg;
}

/*
** Generate code that will evaluate expression pExpr just one time
** Factor out the code of the given expression to initialization time.
** per prepared statement execution.
**
** If the expression uses functions (that might throw an exception) then
** guard them with an OP_Once opcode to ensure that the code is only executed
** once. If no functions are involved, then factor the code out and put it at
** the end of the prepared statement in the initialization section.
**
** If regDest>=0 then the result is always stored in that register and the
** result is not reusable.  If regDest<0 then this routine is free to 
** store the value whereever it wants.  The register where the expression 
** is stored is returned.  When regDest<0, two identical expressions might
** code to the same register, if they do not contain function calls and hence
** is stored is returned.  When regDest<0, two identical expressions will
** code to the same register.
** are factored out into the initialization section at the end of the
** prepared statement.
*/
int sqlite3ExprCodeRunJustOnce(
int sqlite3ExprCodeAtInit(
  Parse *pParse,    /* Parsing context */
  Expr *pExpr,      /* The expression to code when the VDBE initializes */
  int regDest       /* Store the value in this register */
){
  ExprList *p;
  assert( ConstFactorOk(pParse) );
  p = pParse->pConstExpr;
  if( regDest<0 && p ){
    struct ExprList_item *pItem;
    int i;
    for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
      if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){
        return pItem->u.iConstExprReg;
      }
    }
  }
  pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
  if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){
    Vdbe *v = pParse->pVdbe;
    int addr;
    assert( v );
    addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
    pParse->okConstFactor = 0;
    if( !pParse->db->mallocFailed ){
      if( regDest<0 ) regDest = ++pParse->nMem;
      sqlite3ExprCode(pParse, pExpr, regDest);
    }
    pParse->okConstFactor = 1;
    sqlite3ExprDelete(pParse->db, pExpr);
    sqlite3VdbeJumpHere(v, addr);
  }else{
    p = sqlite3ExprListAppend(pParse, p, pExpr);
    if( p ){
       struct ExprList_item *pItem = &p->a[p->nExpr-1];
       pItem->reusable = regDest<0;
       if( regDest<0 ) regDest = ++pParse->nMem;
       pItem->u.iConstExprReg = regDest;
    }
    pParse->pConstExpr = p;
  p = sqlite3ExprListAppend(pParse, p, pExpr);
  if( p ){
     struct ExprList_item *pItem = &p->a[p->nExpr-1];
     pItem->reusable = regDest<0;
     if( regDest<0 ) regDest = ++pParse->nMem;
     pItem->u.iConstExprReg = regDest;
  }
  pParse->pConstExpr = p;
  }
  return regDest;
}

/*
** Generate code to evaluate an expression and store the results
** into a register.  Return the register number where the results
** are stored.
**
** If the register is a temporary register that can be deallocated,
** then write its number into *pReg.  If the result register is not
** a temporary, then set *pReg to zero.
**
** If pExpr is a constant, then this routine might generate this
** code to fill the register in the initialization section of the
** VDBE program, in order to factor it out of the evaluation loop.
*/
int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
  int r2;
  pExpr = sqlite3ExprSkipCollateAndLikely(pExpr);
  pExpr = sqlite3ExprSkipCollate(pExpr);
  if( ConstFactorOk(pParse)
   && ALWAYS(pExpr!=0)
   && pExpr->op!=TK_REGISTER
   && sqlite3ExprIsConstantNotJoin(pExpr)
  ){
    *pReg  = 0;
    r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
    r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
  }else{
    int r1 = sqlite3GetTempReg(pParse);
    r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
    if( r2==r1 ){
      *pReg = r1;
    }else{
      sqlite3ReleaseTempReg(pParse, r1);
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
4188
4189
4190
4191
4192
4193
4194

4195
4196




4197
4198
4199
4200
4201





4202
4203

4204
4205
4206
4207
4208
4209
4210







-

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

-







** Generate code that will evaluate expression pExpr and store the
** results in register target.  The results are guaranteed to appear
** in register target.
*/
void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
  int inReg;

  assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
  assert( target>0 && target<=pParse->nMem );
  if( pExpr && pExpr->op==TK_REGISTER ){
  assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
  if( pParse->pVdbe==0 ) return;
  inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
  if( inReg!=target ){
    sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
  }else{
    inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
    assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
    if( inReg!=target && pParse->pVdbe ){
    u8 op;
    if( ExprHasProperty(pExpr,EP_Subquery) ){
      op = OP_Copy;
    }else{
      op = OP_SCopy;
      sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
    }
    sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target);
  }
}

/*
** Make a transient copy of expression pExpr and then code it using
** sqlite3ExprCode().  This routine works just like sqlite3ExprCode()
** except that the input expression is guaranteed to be unchanged.
4700
4701
4702
4703
4704
4705
4706
4707

4708
4709

4710
4711
























4712
4713
4714
4715
4716
4717
4718
4220
4221
4222
4223
4224
4225
4226

4227
4228

4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262







-
+

-
+


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







** Generate code that will evaluate expression pExpr and store the
** results in register target.  The results are guaranteed to appear
** in register target.  If the expression is constant, then this routine
** might choose to code the expression at initialization time.
*/
void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
  if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
    sqlite3ExprCodeRunJustOnce(pParse, pExpr, target);
    sqlite3ExprCodeAtInit(pParse, pExpr, target);
  }else{
    sqlite3ExprCodeCopy(pParse, pExpr, target);
    sqlite3ExprCode(pParse, pExpr, target);
  }
}

/*
** Generate code that evaluates the given expression and puts the result
** in register target.
**
** Also make a copy of the expression results into another "cache" register
** and modify the expression so that the next time it is evaluated,
** the result is a copy of the cache register.
**
** This routine is used for expressions that are used multiple 
** times.  They are evaluated once and the results of the expression
** are reused.
*/
void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
  Vdbe *v = pParse->pVdbe;
  int iMem;

  assert( target>0 );
  assert( pExpr->op!=TK_REGISTER );
  sqlite3ExprCode(pParse, pExpr, target);
  iMem = ++pParse->nMem;
  sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
  exprToRegister(pExpr, iMem);
}

/*
** Generate code that pushes the value of every element of the given
** expression list into a sequence of registers beginning at target.
**
** Return the number of elements evaluated.  The number returned will
** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF
4760
4761
4762
4763
4764
4765
4766
4767

4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4304
4305
4306
4307
4308
4309
4310

4311
4312
4313
4314
4315
4316
4317
4318
4319

4320
4321
4322
4323
4324
4325
4326







-
+








-







        n--;
      }else{
        sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
      }
    }else if( (flags & SQLITE_ECEL_FACTOR)!=0
           && sqlite3ExprIsConstantNotJoin(pExpr)
    ){
      sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i);
      sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
    }else{
      int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
      if( inReg!=target+i ){
        VdbeOp *pOp;
        if( copyOp==OP_Copy
         && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
         && pOp->p1+pOp->p3+1==inReg
         && pOp->p2+pOp->p3+1==target+i
         && pOp->p5==0  /* The do-not-merge flag must be clear */
        ){
          pOp->p3++;
        }else{
          sqlite3VdbeAddOp2(v, copyOp, inReg, target+i);
        }
      }
    }
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
4351
4352
4353
4354
4355
4356
4357

4358
4359
4360
4361
4362


4363
4364
4365
4366
4367
4368

4369























4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391


4392
4393
4394
4395
4396
4397
4398







-
+


+

-
-






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







static void exprCodeBetween(
  Parse *pParse,    /* Parsing and code generating context */
  Expr *pExpr,      /* The BETWEEN expression */
  int dest,         /* Jump destination or storage location */
  void (*xJump)(Parse*,Expr*,int,int), /* Action to take */
  int jumpIfNull    /* Take the jump if the BETWEEN is NULL */
){
  Expr exprAnd;     /* The AND operator in  x>=y AND x<=z  */
 Expr exprAnd;     /* The AND operator in  x>=y AND x<=z  */
  Expr compLeft;    /* The  x>=y  term */
  Expr compRight;   /* The  x<=z  term */
  Expr exprX;       /* The  x  subexpression */
  int regFree1 = 0; /* Temporary use register */
  Expr *pDel = 0;
  sqlite3 *db = pParse->db;

  memset(&compLeft, 0, sizeof(Expr));
  memset(&compRight, 0, sizeof(Expr));
  memset(&exprAnd, 0, sizeof(Expr));

  assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
  pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
  exprNodeCopy(&exprX, pExpr->pLeft);
  if( db->mallocFailed==0 ){
    exprAnd.op = TK_AND;
    exprAnd.pLeft = &compLeft;
    exprAnd.pRight = &compRight;
    compLeft.op = TK_GE;
    compLeft.pLeft = pDel;
    compLeft.pRight = pExpr->x.pList->a[0].pExpr;
    compRight.op = TK_LE;
    compRight.pLeft = pDel;
    compRight.pRight = pExpr->x.pList->a[1].pExpr;
    exprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1));
    if( xJump ){
      xJump(pParse, &exprAnd, dest, jumpIfNull);
    }else{
      /* Mark the expression is being from the ON or USING clause of a join
      ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
      ** it into the Parse.pConstExpr list.  We should use a new bit for this,
      ** for clarity, but we are out of bits in the Expr.flags field so we
      ** have to reuse the EP_FromJoin bit.  Bummer. */
      pDel->flags |= EP_FromJoin;
      sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
    }
    sqlite3ReleaseTempReg(pParse, regFree1);
  exprAnd.op = TK_AND;
  exprAnd.pLeft = &compLeft;
  exprAnd.pRight = &compRight;
  compLeft.op = TK_GE;
  compLeft.pLeft = &exprX;
  compLeft.pRight = pExpr->x.pList->a[0].pExpr;
  compRight.op = TK_LE;
  compRight.pLeft = &exprX;
  compRight.pRight = pExpr->x.pList->a[1].pExpr;
  exprToRegister(&exprX, exprCodeVector(pParse, &exprX, &regFree1));
  if( xJump ){
    xJump(pParse, &exprAnd, dest, jumpIfNull);
  }else{
    /* Mark the expression is being from the ON or USING clause of a join
    ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
    ** it into the Parse.pConstExpr list.  We should use a new bit for this,
    ** for clarity, but we are out of bits in the Expr.flags field so we
    ** have to reuse the EP_FromJoin bit.  Bummer. */
    exprX.flags |= EP_FromJoin;
    sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
  }
  sqlite3ReleaseTempReg(pParse, regFree1);
  }
  sqlite3ExprDelete(db, pDel);

  /* Ensure adequate test coverage */
  testcase( xJump==sqlite3ExprIfTrue  && jumpIfNull==0 && regFree1==0 );
  testcase( xJump==sqlite3ExprIfTrue  && jumpIfNull==0 && regFree1!=0 );
  testcase( xJump==sqlite3ExprIfTrue  && jumpIfNull!=0 && regFree1==0 );
  testcase( xJump==sqlite3ExprIfTrue  && jumpIfNull!=0 && regFree1!=0 );
  testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 );
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
4422
4423
4424
4425
4426
4427
4428

4429
4430

4431








4432
4433
4434







4435
4436
4437
4438
4439
4440
4441
4442

4443
4444
4445
4446
4447
4448
4449







-


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







  int regFree1 = 0;
  int regFree2 = 0;
  int r1, r2;

  assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
  if( NEVER(v==0) )     return;  /* Existence of VDBE checked by caller */
  if( NEVER(pExpr==0) ) return;  /* No way this can happen */
  assert( !ExprHasVVAProperty(pExpr, EP_Immutable) );
  op = pExpr->op;
  switch( op ){
    case TK_AND:
    case TK_AND: {
    case TK_OR: {
      Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
      if( pAlt!=pExpr ){
        sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
      }else if( op==TK_AND ){
        int d2 = sqlite3VdbeMakeLabel(pParse);
        testcase( jumpIfNull==0 );
        sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
      int d2 = sqlite3VdbeMakeLabel(pParse);
      testcase( jumpIfNull==0 );
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
                           jumpIfNull^SQLITE_JUMPIFNULL);
        sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
        sqlite3VdbeResolveLabel(v, d2);
      }else{
        testcase( jumpIfNull==0 );
        sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
        sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3VdbeResolveLabel(v, d2);
      break;
    }
    case TK_OR: {
      testcase( jumpIfNull==0 );
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
      }
      break;
    }
    case TK_NOT: {
      testcase( jumpIfNull==0 );
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
      break;
    }
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
4466
4467
4468
4469
4470
4471
4472

4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484

4485
4486
4487
4488
4489
4490
4491
4492







-
+











-
+







    }
    case TK_IS:
    case TK_ISNOT:
      testcase( op==TK_IS );
      testcase( op==TK_ISNOT );
      op = (op==TK_IS) ? TK_EQ : TK_NE;
      jumpIfNull = SQLITE_NULLEQ;
      /* no break */ deliberate_fall_through
      /* Fall thru */
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
      testcase( jumpIfNull==0 );
      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
      r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
                  r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted));
                  r1, r2, dest, jumpIfNull);
      assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
      assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
      assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
      assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
4988
4989
4990
4991
4992
4993
4994
4995

4996
4997

4998
4999
5000
5001
5002
5003
5004
4521
4522
4523
4524
4525
4526
4527

4528
4529

4530
4531
4532
4533
4534
4535
4536
4537







-
+

-
+







      sqlite3VdbeGoto(v, dest);
      sqlite3VdbeResolveLabel(v, destIfFalse);
      break;
    }
#endif
    default: {
    default_expr:
      if( ExprAlwaysTrue(pExpr) ){
      if( exprAlwaysTrue(pExpr) ){
        sqlite3VdbeGoto(v, dest);
      }else if( ExprAlwaysFalse(pExpr) ){
      }else if( exprAlwaysFalse(pExpr) ){
        /* No-op */
      }else{
        r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
        sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
        VdbeCoverage(v);
        testcase( regFree1==0 );
        testcase( jumpIfNull==0 );
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
4558
4559
4560
4561
4562
4563
4564

4565
4566
4567
4568
4569
4570
4571







-







  int regFree1 = 0;
  int regFree2 = 0;
  int r1, r2;

  assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
  if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
  if( pExpr==0 )    return;
  assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );

  /* The value of pExpr->op and op are related as follows:
  **
  **       pExpr->op            op
  **       ---------          ----------
  **       TK_ISNULL          OP_NotNull
  **       TK_NOTNULL         OP_IsNull
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
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







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







  assert( pExpr->op!=TK_EQ || op==OP_Ne );
  assert( pExpr->op!=TK_LT || op==OP_Ge );
  assert( pExpr->op!=TK_LE || op==OP_Gt );
  assert( pExpr->op!=TK_GT || op==OP_Le );
  assert( pExpr->op!=TK_GE || op==OP_Lt );

  switch( pExpr->op ){
    case TK_AND:
    case TK_AND: {
    case TK_OR: {
      Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
      if( pAlt!=pExpr ){
        sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
      }else if( pExpr->op==TK_AND ){
        testcase( jumpIfNull==0 );
        sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
        sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      }else{
        int d2 = sqlite3VdbeMakeLabel(pParse);
        testcase( jumpIfNull==0 );
        sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
      testcase( jumpIfNull==0 );
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      break;
    }
    case TK_OR: {
      int d2 = sqlite3VdbeMakeLabel(pParse);
      testcase( jumpIfNull==0 );
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
                          jumpIfNull^SQLITE_JUMPIFNULL);
        sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
        sqlite3VdbeResolveLabel(v, d2);
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3VdbeResolveLabel(v, d2);
      }
      break;
    }
    case TK_NOT: {
      testcase( jumpIfNull==0 );
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
      break;
    }
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
4636
4637
4638
4639
4640
4641
4642

4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654

4655
4656
4657
4658
4659
4660
4661
4662







-
+











-
+







    }
    case TK_IS:
    case TK_ISNOT:
      testcase( pExpr->op==TK_IS );
      testcase( pExpr->op==TK_ISNOT );
      op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
      jumpIfNull = SQLITE_NULLEQ;
      /* no break */ deliberate_fall_through
      /* Fall thru */
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
      testcase( jumpIfNull==0 );
      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
      r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
                  r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted));
                  r1, r2, dest, jumpIfNull);
      assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
      assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
      assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
      assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
5164
5165
5166
5167
5168
5169
5170
5171

5172
5173

5174
5175
5176
5177
5178
5179
5180
4691
4692
4693
4694
4695
4696
4697

4698
4699

4700
4701
4702
4703
4704
4705
4706
4707







-
+

-
+







        sqlite3VdbeResolveLabel(v, destIfNull);
      }
      break;
    }
#endif
    default: {
    default_expr: 
      if( ExprAlwaysFalse(pExpr) ){
      if( exprAlwaysFalse(pExpr) ){
        sqlite3VdbeGoto(v, dest);
      }else if( ExprAlwaysTrue(pExpr) ){
      }else if( exprAlwaysTrue(pExpr) ){
        /* no-op */
      }else{
        r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
        sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
        VdbeCoverage(v);
        testcase( regFree1==0 );
        testcase( jumpIfNull==0 );
5286
5287
5288
5289
5290
5291
5292
5293

5294
5295
5296
5297









5298
5299
5300
5301

5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314

5315
5316

5317
5318
5319
5320
5321
5322
5323
5324

5325
5326
5327
5328
5329


5330
5331
5332
5333
5334
5335
5336
5337

5338
5339

5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362


5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374


5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
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
4813
4814
4815
4816
4817
4818
4819

4820
4821
4822


4823
4824
4825
4826
4827
4828
4829
4830
4831


4832

4833


4834
4835
4836
4837
4838
4839
4840
4841
4842
4843

4844


4845
4846
4847
4848
4849
4850
4851
4852

4853
4854
4855



4856
4857

4858
4859
4860
4861
4862
4863

4864


4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883

4884
4885


4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897


4898
4899
4900
4901
4902













































































4903
4904
4905
4906
4907
4908
4909







-
+


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

-
+
-
-










-
+
-
-
+







-
+


-
-
-
+
+
-






-
+
-
-
+


















-


-
-
+
+










-
-
+
+



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







    }
    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
      return 1;
    }
    return 2;
  }
  if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
    if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
    if( pA->op==TK_FUNCTION ){
      if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
#ifndef SQLITE_OMIT_WINDOWFUNC
      assert( pA->op==pB->op );
      if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){
      /* Justification for the assert():
      ** window functions have p->op==TK_FUNCTION but aggregate functions
      ** have p->op==TK_AGG_FUNCTION.  So any comparison between an aggregate
      ** function and a window function should have failed before reaching
      ** this point.  And, it is not possible to have a window function and
      ** a scalar function with the same name and number of arguments.  So
      ** if we reach this point, either A and B both window functions or
      ** neither are a window functions. */
      assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
        return 2;
      }
      if( ExprHasProperty(pA,EP_WinFunc) ){
        if( sqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){
        if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
          return 2;
        }
      }
#endif
    }else if( pA->op==TK_NULL ){
      return 0;
    }else if( pA->op==TK_COLLATE ){
      if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
    }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
      return 2;
    }
  }
  if( (pA->flags & (EP_Distinct|EP_Commuted))
  if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
     != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
  if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
  if( (combinedFlags & EP_TokenOnly)==0 ){
    if( combinedFlags & EP_xIsSelect ) return 2;
    if( (combinedFlags & EP_FixedCol)==0
     && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
    if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
    if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
    if( pA->op!=TK_STRING
     && pA->op!=TK_TRUEFALSE
     && ALWAYS((combinedFlags & EP_Reduced)==0)
     && (combinedFlags & EP_Reduced)==0
    ){
      if( pA->iColumn!=pB->iColumn ) return 2;
      if( pA->op2!=pB->op2 && pA->op==TK_TRUTH ) return 2;
      if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
        return 2;
      if( pA->iTable!=pB->iTable 
       && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
      }
    }
  }
  return 0;
}

/*
** Compare two ExprList objects.  Return 0 if they are identical, 1
** Compare two ExprList objects.  Return 0 if they are identical and 
** if they are certainly different, or 2 if it is not possible to 
** determine if they are identical or not.
** non-zero if they differ in any way.
**
** If any subelement of pB has Expr.iTable==(-1) then it is allowed
** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
**
** This routine might return non-zero for equivalent ExprLists.  The
** only consequence will be disabled optimizations.  But this routine
** must never return 0 if the two ExprList objects are different, or
** a malfunction will result.
**
** Two NULL pointers are considered to be the same.  But a NULL pointer
** always differs from a non-NULL pointer.
*/
int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
  int i;
  if( pA==0 && pB==0 ) return 0;
  if( pA==0 || pB==0 ) return 1;
  if( pA->nExpr!=pB->nExpr ) return 1;
  for(i=0; i<pA->nExpr; i++){
    int res;
    Expr *pExprA = pA->a[i].pExpr;
    Expr *pExprB = pB->a[i].pExpr;
    if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
    if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res;
    if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
    if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1;
  }
  return 0;
}

/*
** Like sqlite3ExprCompare() except COLLATE operators at the top-level
** are ignored.
*/
int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
  return sqlite3ExprCompare(0,
             sqlite3ExprSkipCollateAndLikely(pA),
             sqlite3ExprSkipCollateAndLikely(pB),
             sqlite3ExprSkipCollate(pA),
             sqlite3ExprSkipCollate(pB),
             iTab);
}

/*
** Return non-zero if Expr p can only be true if pNN is not NULL.
**
** Or if seenNot is true, return non-zero if Expr p can only be
** non-NULL if pNN is not NULL
*/
static int exprImpliesNotNull(
  Parse *pParse,      /* Parsing context */
  Expr *p,            /* The expression to be checked */
  Expr *pNN,          /* The expression that is NOT NULL */
  int iTab,           /* Table being evaluated */
  int seenNot         /* Return true only if p can be any non-NULL value */
){
  assert( p );
  assert( pNN );
  if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){
    return pNN->op!=TK_NULL;
  }
  switch( p->op ){
    case TK_IN: {
      if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
      assert( ExprHasProperty(p,EP_xIsSelect)
           || (p->x.pList!=0 && p->x.pList->nExpr>0) );
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
    }
    case TK_BETWEEN: {
      ExprList *pList = p->x.pList;
      assert( pList!=0 );
      assert( pList->nExpr==2 );
      if( seenNot ) return 0;
      if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1)
       || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1)
      ){
        return 1;
      }
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
    }
    case TK_EQ:
    case TK_NE:
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_PLUS:
    case TK_MINUS:
    case TK_BITOR:
    case TK_LSHIFT:
    case TK_RSHIFT: 
    case TK_CONCAT: 
      seenNot = 1;
      /* no break */ deliberate_fall_through
    case TK_STAR:
    case TK_REM:
    case TK_BITAND:
    case TK_SLASH: {
      if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1;
      /* no break */ deliberate_fall_through
    }
    case TK_SPAN:
    case TK_COLLATE:
    case TK_UPLUS:
    case TK_UMINUS: {
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
    }
    case TK_TRUTH: {
      if( seenNot ) return 0;
      if( p->op2!=TK_IS ) return 0;
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
    }
    case TK_BITNOT:
    case TK_NOT: {
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
    }
  }
  return 0;
}

/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true.  Return false if we cannot complete the proof or if pE2 might
** be false.  Examples:
**
**     pE1: x==5       pE2: x==5             Result: true
**     pE1: x>0        pE2: x==5             Result: false
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493




5494
5495
5496
5497
5498
5499

5500
5501
5502
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
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565

5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576

5577
5578

5579
5580
5581

5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
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







-
-
-
-
+
+
+
+





-
+













+




-



-
-
+
+




-



-






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










-
+
-
-






-
-
-
+
-
-
+
-

-
+

-
-







  }
  if( pE2->op==TK_OR
   && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
             || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
  ){
    return 1;
  }
  if( pE2->op==TK_NOTNULL
   && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
  ){
    return 1;
  if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
    Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
    testcase( pX!=pE1->pLeft );
    if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
  }
  return 0;
}

/*
** This is the Expr node callback for sqlite3ExprImpliesNonNullRow().
** This is the Expr node callback for sqlite3ExprImpliesNotNullRow().
** If the expression node requires that the table at pWalker->iCur
** have one or more non-NULL column, then set pWalker->eCode to 1 and abort.
**
** This routine controls an optimization.  False positives (setting
** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives
** (never setting pWalker->eCode) is a harmless missed optimization.
*/
static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
  testcase( pExpr->op==TK_AGG_COLUMN );
  testcase( pExpr->op==TK_AGG_FUNCTION );
  if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
  switch( pExpr->op ){
    case TK_ISNOT:
    case TK_NOT:
    case TK_ISNULL:
    case TK_NOTNULL:
    case TK_IS:
    case TK_OR:
    case TK_VECTOR:
    case TK_CASE:
    case TK_IN:
    case TK_FUNCTION:
    case TK_TRUTH:
      testcase( pExpr->op==TK_ISNOT );
      testcase( pExpr->op==TK_ISNOT );
      testcase( pExpr->op==TK_NOT );
      testcase( pExpr->op==TK_ISNULL );
      testcase( pExpr->op==TK_NOTNULL );
      testcase( pExpr->op==TK_IS );
      testcase( pExpr->op==TK_OR );
      testcase( pExpr->op==TK_VECTOR );
      testcase( pExpr->op==TK_CASE );
      testcase( pExpr->op==TK_IN );
      testcase( pExpr->op==TK_FUNCTION );
      testcase( pExpr->op==TK_TRUTH );
      return WRC_Prune;
    case TK_COLUMN:
      if( pWalker->u.iCur==pExpr->iTable ){
        pWalker->eCode = 1;
        return WRC_Abort;
      }
      return WRC_Prune;

    case TK_AND:
      if( pWalker->eCode==0 ){
        sqlite3WalkExpr(pWalker, pExpr->pLeft);
        if( pWalker->eCode ){
          pWalker->eCode = 0;
          sqlite3WalkExpr(pWalker, pExpr->pRight);
        }
      }
      return WRC_Prune;

    case TK_BETWEEN:
      if( sqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){
        assert( pWalker->eCode );
        return WRC_Abort;
      }
      return WRC_Prune;

    /* Virtual tables are allowed to use constraints like x=NULL.  So
    ** a term of the form x=y does not prove that y is not null if x
    ** is the column of a virtual table */
    case TK_EQ:
    case TK_NE:
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE: {
    case TK_GE:
      Expr *pLeft = pExpr->pLeft;
      Expr *pRight = pExpr->pRight;
      testcase( pExpr->op==TK_EQ );
      testcase( pExpr->op==TK_NE );
      testcase( pExpr->op==TK_LT );
      testcase( pExpr->op==TK_LE );
      testcase( pExpr->op==TK_GT );
      testcase( pExpr->op==TK_GE );
      /* The y.pTab=0 assignment in wherecode.c always happens after the
      ** impliesNotNullRow() test */
      if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0)
      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
                               && IsVirtual(pLeft->y.pTab))
       || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0)
       || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
                               && IsVirtual(pRight->y.pTab))
      ){
        return WRC_Prune;
       return WRC_Prune;
      }
      /* no break */ deliberate_fall_through
    }
    default:
      return WRC_Continue;
  }
}

/*
** Return true (non-zero) if expression p can only be true if at least
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617




5618
5619

5620
5621


5622
5623
5624
5625
5626
5627
5628
5028
5029
5030
5031
5032
5033
5034




5035
5036
5037
5038


5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050







-
-
-
-
+
+
+
+
-
-
+


+
+







** an ordinary JOIN.  The p argument is the WHERE clause.  If the WHERE
** clause requires that some column of the right table of the LEFT JOIN
** be non-NULL, then the LEFT JOIN can be safely converted into an
** ordinary join.
*/
int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
  Walker w;
  p = sqlite3ExprSkipCollateAndLikely(p);
  if( p==0 ) return 0;
  if( p->op==TK_NOTNULL ){
    p = p->pLeft;
  p = sqlite3ExprSkipCollate(p);
  while( p ){
    if( p->op==TK_NOTNULL ){
      p = p->pLeft;
  }else{
    while( p->op==TK_AND ){
    }else if( p->op==TK_AND ){
      if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1;
      p = p->pRight;
    }else{
      break;
    }
  }
  w.xExprCallback = impliesNotNullRow;
  w.xSelectCallback = 0;
  w.xSelectCallback2 = 0;
  w.eCode = 0;
  w.u.iCur = iTab;
5646
5647
5648
5649
5650
5651
5652
5653

5654
5655
5656
5657
5658
5659
5660
5068
5069
5070
5071
5072
5073
5074

5075
5076
5077
5078
5079
5080
5081
5082







-
+







** Check to see if there are references to columns in table 
** pWalker->u.pIdxCover->iCur can be satisfied using the index
** pWalker->u.pIdxCover->pIdx.
*/
static int exprIdxCover(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_COLUMN
   && pExpr->iTable==pWalker->u.pIdxCover->iCur
   && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
   && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
  ){
    pWalker->eCode = 1;
    return WRC_Abort;
  }
  return WRC_Continue;
}

5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722



5723
5724
5725



5726
5727
5728
5729
5730
5731
5732
5733
5734
5735

5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757

5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
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







-




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




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









-
+
-
-
-
















-

-
+


-



-
-
-
-
-



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







** An instance of the following structure is used by the tree walker
** to count references to table columns in the arguments of an 
** aggregate function, in order to implement the
** sqlite3FunctionThisSrc() routine.
*/
struct SrcCount {
  SrcList *pSrc;   /* One particular FROM clause in a nested query */
  int iSrcInner;   /* Smallest cursor number in this context */
  int nThis;       /* Number of references to columns in pSrcList */
  int nOther;      /* Number of references to columns in other FROM clauses */
};

/*
** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
** SELECT with a FROM clause encountered during this iteration, set
** SrcCount.iSrcInner to the cursor number of the leftmost object in
** the FROM cause.
*/
static int selectSrcCount(Walker *pWalker, Select *pSel){
  struct SrcCount *p = pWalker->u.pSrcCount;
  if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){
    pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
  }
  return WRC_Continue;
}

/*
** Count the number of references to columns.
*/
static int exprSrcCount(Walker *pWalker, Expr *pExpr){
  /* There was once a NEVER() on the second term on the grounds that
  ** sqlite3FunctionUsesThisSrc() was always called before 
  ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet 
  ** been converted into TK_AGG_COLUMN. But this is no longer true due
  /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc()
  ** is always called before sqlite3ExprAnalyzeAggregates() and so the
  ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN.  If
  ** to window functions - sqlite3WindowRewrite() may now indirectly call
  ** FunctionUsesThisSrc() when creating a new sub-select. */
  if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
  ** sqlite3FunctionUsesThisSrc() is used differently in the future, the
  ** NEVER() will need to be removed. */
  if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){
    int i;
    struct SrcCount *p = pWalker->u.pSrcCount;
    SrcList *pSrc = p->pSrc;
    int nSrc = pSrc ? pSrc->nSrc : 0;
    for(i=0; i<nSrc; i++){
      if( pExpr->iTable==pSrc->a[i].iCursor ) break;
    }
    if( i<nSrc ){
      p->nThis++;
    }else if( pExpr->iTable<p->iSrcInner ){
    }else{
      /* In a well-formed parse tree (no name resolution errors),
      ** TK_COLUMN nodes with smaller Expr.iTable values are in an
      ** outer context.  Those are the only ones to count as "other" */
      p->nOther++;
    }
  }
  return WRC_Continue;
}

/*
** Determine if any of the arguments to the pExpr Function reference
** pSrcList.  Return true if they do.  Also return true if the function
** has no arguments or has only constant arguments.  Return false if pExpr
** references columns but not columns of tables found in pSrcList.
*/
int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
  Walker w;
  struct SrcCount cnt;
  assert( pExpr->op==TK_AGG_FUNCTION );
  memset(&w, 0, sizeof(w));
  w.xExprCallback = exprSrcCount;
  w.xSelectCallback = selectSrcCount;
  w.xSelectCallback = 0;
  w.u.pSrcCount = &cnt;
  cnt.pSrc = pSrcList;
  cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
  cnt.nThis = 0;
  cnt.nOther = 0;
  sqlite3WalkExprList(&w, pExpr->x.pList);
#ifndef SQLITE_OMIT_WINDOWFUNC
  if( ExprHasProperty(pExpr, EP_WinFunc) ){
    sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
  }
#endif
  return cnt.nThis>0 || cnt.nOther==0;
}

/*
** This is a Walker expression node callback.
**
** For Expr nodes that contain pAggInfo pointers, make sure the AggInfo
** object that is referenced does not refer directly to the Expr.  If
** it does, make a copy.  This is done because the pExpr argument is
** subject to change.
**
** The copy is stored on pParse->pConstExpr with a register number of 0.
** This will cause the expression to be deleted automatically when the
** Parse object is destroyed, but the zero register number means that it
** will not generate any code in the preamble.
*/
static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
  if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced))
   && pExpr->pAggInfo!=0
  ){
    AggInfo *pAggInfo = pExpr->pAggInfo;
    int iAgg = pExpr->iAgg;
    Parse *pParse = pWalker->pParse;
    sqlite3 *db = pParse->db;
    assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_AGG_FUNCTION );
    if( pExpr->op==TK_AGG_COLUMN ){
      assert( iAgg>=0 && iAgg<pAggInfo->nColumn );
      if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        if( pExpr ){
          pAggInfo->aCol[iAgg].pCExpr = pExpr;
          sqlite3ExprDeferredDelete(pParse, pExpr);
        }
      }
    }else{
      assert( iAgg>=0 && iAgg<pAggInfo->nFunc );
      if( pAggInfo->aFunc[iAgg].pFExpr==pExpr ){
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        if( pExpr ){
          pAggInfo->aFunc[iAgg].pFExpr = pExpr;
          sqlite3ExprDeferredDelete(pParse, pExpr);
        }
      }
    }
  }
  return WRC_Continue;
}

/*
** Initialize a Walker object so that will persist AggInfo entries referenced
** by the tree that is walked.
*/
void sqlite3AggInfoPersistWalkerInit(Walker *pWalker, Parse *pParse){
  memset(pWalker, 0, sizeof(*pWalker));
  pWalker->pParse = pParse;
  pWalker->xExprCallback = agginfoPersistExprCb;
  pWalker->xSelectCallback = sqlite3SelectWalkNoop;
}

/*
** Add a new element to the pAggInfo->aCol[] array.  Return the index of
** the new element.  Return a negative number if malloc fails.
*/
static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
  int i;
  pInfo->aCol = sqlite3ArrayAllocate(
5851
5852
5853
5854
5855
5856
5857
5858

5859
5860
5861
5862
5863
5864
5865
5191
5192
5193
5194
5195
5196
5197

5198
5199
5200
5201
5202
5203
5204
5205







-
+







       db, 
       pInfo->aFunc,
       sizeof(pInfo->aFunc[0]),
       &pInfo->nFunc,
       &i
  );
  return i;
}
}    

/*
** This is the xExprCallback for a tree walker.  It is used to
** implement sqlite3ExprAnalyzeAggregates().  See sqlite3ExprAnalyzeAggregates
** for additional information.
*/
static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
5874
5875
5876
5877
5878
5879
5880
5881

5882
5883
5884
5885
5886
5887
5888
5214
5215
5216
5217
5218
5219
5220

5221
5222
5223
5224
5225
5226
5227
5228







-
+







    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;
        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.  
            **
5902
5903
5904
5905
5906
5907
5908
5909

5910
5911
5912
5913
5914
5915
5916
5242
5243
5244
5245
5246
5247
5248

5249
5250
5251
5252
5253
5254
5255
5256







-
+







            ){
              pCol = &pAggInfo->aCol[k];
              pCol->pTab = pExpr->y.pTab;
              pCol->iTable = pExpr->iTable;
              pCol->iColumn = pExpr->iColumn;
              pCol->iMem = ++pParse->nMem;
              pCol->iSorterColumn = -1;
              pCol->pCExpr = pExpr;
              pCol->pExpr = pExpr;
              if( pAggInfo->pGroupBy ){
                int j, n;
                ExprList *pGB = pAggInfo->pGroupBy;
                struct ExprList_item *pTerm = pGB->a;
                n = pGB->nExpr;
                for(j=0; j<n; j++, pTerm++){
                  Expr *pE = pTerm->pExpr;
5945
5946
5947
5948
5949
5950
5951
5952

5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964

5965
5966
5967
5968
5969
5970
5971
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







-
+











-
+







       && pWalker->walkerDepth==pExpr->op2
      ){
        /* Check to see if pExpr is a duplicate of another aggregate 
        ** function that is already in the pAggInfo structure
        */
        struct AggInfo_func *pItem = pAggInfo->aFunc;
        for(i=0; i<pAggInfo->nFunc; i++, pItem++){
          if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
          if( sqlite3ExprCompare(0, pItem->pExpr, pExpr, -1)==0 ){
            break;
          }
        }
        if( i>=pAggInfo->nFunc ){
          /* pExpr is original.  Make a new entry in pAggInfo->aFunc[]
          */
          u8 enc = ENC(pParse->db);
          i = addAggInfoFunc(pParse->db, pAggInfo);
          if( i>=0 ){
            assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
            pItem = &pAggInfo->aFunc[i];
            pItem->pFExpr = pExpr;
            pItem->pExpr = pExpr;
            pItem->iMem = ++pParse->nMem;
            assert( !ExprHasProperty(pExpr, EP_IntValue) );
            pItem->pFunc = sqlite3FindFunction(pParse->db,
                   pExpr->u.zToken, 
                   pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
            if( pExpr->flags & EP_Distinct ){
              pItem->iDistinct = pParse->nTab++;
5984
5985
5986
5987
5988
5989
5990









5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005


6006
6007
6008
6009
6010
6011
6012
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352


5353
5354
5355
5356
5357
5358
5359
5360
5361







+
+
+
+
+
+
+
+
+













-
-
+
+







      }else{
        return WRC_Continue;
      }
    }
  }
  return WRC_Continue;
}
static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
  UNUSED_PARAMETER(pSelect);
  pWalker->walkerDepth++;
  return WRC_Continue;
}
static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
  UNUSED_PARAMETER(pSelect);
  pWalker->walkerDepth--;
}

/*
** Analyze the pExpr expression looking for aggregate functions and
** for variables that need to be added to AggInfo object that pNC->pAggInfo
** points to.  Additional entries are made on the AggInfo object as
** necessary.
**
** This routine should only be called after the expression has been
** analyzed by sqlite3ResolveExprNames().
*/
void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
  Walker w;
  w.xExprCallback = analyzeAggregate;
  w.xSelectCallback = sqlite3WalkerDepthIncrease;
  w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
  w.xSelectCallback = analyzeAggregatesInSelect;
  w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
  w.walkerDepth = 0;
  w.u.pNC = pNC;
  w.pParse = 0;
  assert( pNC->pSrcList!=0 );
  sqlite3WalkExpr(&w, pExpr);
}

6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047


6048
6049
6050
6051
6052
6053
6054
6055
5386
5387
5388
5389
5390
5391
5392




5393
5394

5395
5396
5397
5398
5399
5400
5401







-
-
-
-
+
+
-







}

/*
** Deallocate a register, making available for reuse for some other
** purpose.
*/
void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
  if( iReg ){
    sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0);
    if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
      pParse->aTempReg[pParse->nTempReg++] = iReg;
  if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
    pParse->aTempReg[pParse->nTempReg++] = iReg;
    }
  }
}

/*
** Allocate or deallocate a block of nReg consecutive registers.
*/
int sqlite3GetTempRange(Parse *pParse, int nReg){
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
5413
5414
5415
5416
5417
5418
5419

5420
5421
5422
5423
5424
5425
5426
5427





5428
5429
5430
5431
5432
5433
5434







-








-
-
-
-
-







  return i;
}
void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
  if( nReg==1 ){
    sqlite3ReleaseTempReg(pParse, iReg);
    return;
  }
  sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0);
  if( nReg>pParse->nRangeReg ){
    pParse->nRangeReg = nReg;
    pParse->iRangeReg = iReg;
  }
}

/*
** Mark all temporary registers as being unavailable for reuse.
**
** Always invoke this procedure after coding a subroutine or co-routine
** that might be invoked from other parts of the code, to ensure that
** the sub/co-routine does not use registers in common with the code that
** invokes the sub/co-routine.
*/
void sqlite3ClearTempRegCache(Parse *pParse){
  pParse->nTempReg = 0;
  pParse->nRangeReg = 0;
}

/*

Changes to src/fkey.c.

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







-
+















-
+
-







  ** any are, then the constraint is considered satisfied. No need to 
  ** search for a matching row in the parent table.  */
  if( nIncr<0 ){
    sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
    VdbeCoverage(v);
  }
  for(i=0; i<pFKey->nCol; i++){
    int iReg = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) + regData + 1;
    int iReg = aiCol[i] + regData + 1;
    sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v);
  }

  if( isIgnore==0 ){
    if( pIdx==0 ){
      /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
      ** column of the parent table (table pTab).  */
      int iMustBeInt;               /* Address of MustBeInt instruction */
      int regTemp = sqlite3GetTempReg(pParse);
  
      /* Invoke MustBeInt to coerce the child key value to an integer (i.e. 
      ** apply the affinity of the parent key). If this fails, then there
      ** is no matching parent key. Before using MustBeInt, make a copy of
      ** the value. Otherwise, the value inserted into the child key column
      ** will have INTEGER affinity applied to it, which may not be correct.  */
      sqlite3VdbeAddOp2(v, OP_SCopy, 
      sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
        sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[0])+1+regData, regTemp);
      iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
      VdbeCoverage(v);
  
      /* If the parent table is the same as the child table, and we are about
      ** to increment the constraint-counter (i.e. this is an INSERT operation),
      ** then check if the row being inserted matches itself. If so, do not
      ** increment the constraint-counter.  */
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
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







-
+
-
-















-
-
-
+
+
-
-







      int nCol = pFKey->nCol;
      int regTemp = sqlite3GetTempRange(pParse, nCol);
      int regRec = sqlite3GetTempReg(pParse);
  
      sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
      sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
      for(i=0; i<nCol; i++){
        sqlite3VdbeAddOp2(v, OP_Copy, 
        sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
               sqlite3TableColumnToStorage(pFKey->pFrom, aiCol[i])+1+regData,
               regTemp+i);
      }
  
      /* If the parent table is the same as the child table, and we are about
      ** to increment the constraint-counter (i.e. this is an INSERT operation),
      ** then check if the row being inserted matches itself. If so, do not
      ** increment the constraint-counter. 
      **
      ** If any of the parent-key values are NULL, then the row cannot match 
      ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
      ** of the parent-key values are NULL (at this point it is known that
      ** none of the child key values are).
      */
      if( pTab==pFKey->pFrom && nIncr==1 ){
        int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
        for(i=0; i<nCol; i++){
          int iChild = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i])
                              +1+regData;
          int iParent = 1+regData;
          int iChild = aiCol[i]+1+regData;
          int iParent = pIdx->aiColumn[i]+1+regData;
          iParent += sqlite3TableColumnToStorage(pIdx->pTable,
                                                 pIdx->aiColumn[i]);
          assert( pIdx->aiColumn[i]>=0 );
          assert( aiCol[i]!=pTab->iPKey );
          if( pIdx->aiColumn[i]==pTab->iPKey ){
            /* The parent key is a composite key that includes the IPK column */
            iParent = regData;
          }
          sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
479
480
481
482
483
484
485
486
487


488
489
490
491
492
493

494
495
496
497
498
499
500
473
474
475
476
477
478
479


480
481
482
483
484
485
486

487
488
489
490
491
492
493
494







-
-
+
+





-
+







  const char *zColl;
  sqlite3 *db = pParse->db;

  pExpr = sqlite3Expr(db, TK_REGISTER, 0);
  if( pExpr ){
    if( iCol>=0 && iCol!=pTab->iPKey ){
      pCol = &pTab->aCol[iCol];
      pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1;
      pExpr->affExpr = pCol->affinity;
      pExpr->iTable = regBase + iCol + 1;
      pExpr->affinity = pCol->affinity;
      zColl = pCol->zColl;
      if( zColl==0 ) zColl = db->pDfltColl->zName;
      pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl);
    }else{
      pExpr->iTable = regBase;
      pExpr->affExpr = SQLITE_AFF_INTEGER;
      pExpr->affinity = SQLITE_AFF_INTEGER;
    }
  }
  return pExpr;
}

/*
** Return an Expr object that refers to column iCol of table pTab which
593
594
595
596
597
598
599
600

601
602
603
604
605
606
607
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601







-
+







    iCol = pIdx ? pIdx->aiColumn[i] : -1;
    pLeft = exprTableRegister(pParse, pTab, regData, iCol);
    iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
    assert( iCol>=0 );
    zCol = pFKey->pFrom->aCol[iCol].zName;
    pRight = sqlite3Expr(db, TK_ID, zCol);
    pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
    pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
    pWhere = sqlite3ExprAnd(db, pWhere, pEq);
  }

  /* If the child table is the same as the parent table, then add terms
  ** to the WHERE clause that prevent this entry from being scanned.
  ** The added WHERE clause terms are like this:
  **
  **     $current_rowid!=rowid
627
628
629
630
631
632
633
634

635
636
637
638

639
640
641
642
643
644
645
621
622
623
624
625
626
627

628
629
630
631

632
633
634
635
636
637
638
639







-
+



-
+







      assert( pIdx!=0 );
      for(i=0; i<pIdx->nKeyCol; i++){
        i16 iCol = pIdx->aiColumn[i];
        assert( iCol>=0 );
        pLeft = exprTableRegister(pParse, pTab, regData, iCol);
        pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
        pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
        pAll = sqlite3ExprAnd(pParse, pAll, pEq);
        pAll = sqlite3ExprAnd(db, pAll, pEq);
      }
      pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
    }
    pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
    pWhere = sqlite3ExprAnd(db, pWhere, pNe);
  }

  /* Resolve the references in the WHERE clause. */
  memset(&sNameContext, 0, sizeof(NameContext));
  sNameContext.pSrcList = pSrc;
  sNameContext.pParse = pParse;
  sqlite3ResolveExprNames(&sNameContext, pWhere);
654
655
656
657
658
659
660
661

662
663
664
665
666
667
668
648
649
650
651
652
653
654

655
656
657
658
659
660
661
662







-
+







      sqlite3WhereEnd(pWInfo);
    }
  }

  /* Clean up the WHERE clause constructed above. */
  sqlite3ExprDelete(db, pWhere);
  if( iFkIfZero ){
    sqlite3VdbeJumpHereOrPopInst(v, iFkIfZero);
    sqlite3VdbeJumpHere(v, iFkIfZero);
  }
}

/*
** This function returns a linked list of FKey objects (connected by
** FKey.pNextTo) holding all children of table pTab.  For example,
** given the following schema:
928
929
930
931
932
933
934
935
936

937
938
939
940
941
942
943
944
922
923
924
925
926
927
928


929

930
931
932
933
934
935
936







-
-
+
-







        ** If the parent table of an FK constraint on the current table is
        ** missing, behave as if it is empty. i.e. decrement the relevant
        ** FK counter for each row of the current table with non-NULL keys.
        */
        Vdbe *v = sqlite3GetVdbe(pParse);
        int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
        for(i=0; i<pFKey->nCol; i++){
          int iFromCol, iReg;
          iFromCol = pFKey->aCol[i].iFrom;
          int iReg = pFKey->aCol[i].iFrom + regOld + 1;
          iReg = sqlite3TableColumnToStorage(pFKey->pFrom,iFromCol) + regOld+1;
          sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v);
        }
        sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
      }
      continue;
    }
    assert( pFKey->nCol==1 || (aiFree && pIdx) );
1020
1021
1022
1023
1024
1025
1026
1027

1028
1029
1030
1031
1032
1033
1034
1012
1013
1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024
1025
1026







-
+







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







-
+
-
-











-
+
-





-
+







+

-
-
+







-
+




-
+







**
** 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
**   * There are any FKs for which pTab is the child and the parent table, or
**     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 eRet = 0;
  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);
      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) ){
          if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2;
          bHaveFK = 1;
          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;
          bHaveFK = 1;
          eRet = 1;
        }
      }
    }
  }
  return bHaveFK ? eRet : 0;
  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
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
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







-
+















-
+









-
-
+
-
-
-
-
-
-
-







      ** parent table are used for the comparison. */
      pEq = sqlite3PExpr(pParse, TK_EQ,
          sqlite3PExpr(pParse, TK_DOT, 
            sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
          sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
      );
      pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
      pWhere = sqlite3ExprAnd(db, pWhere, pEq);

      /* For ON UPDATE, construct the next term of the WHEN clause.
      ** The final WHEN clause will be like this:
      **
      **    WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
      */
      if( pChanges ){
        pEq = sqlite3PExpr(pParse, TK_IS,
            sqlite3PExpr(pParse, TK_DOT, 
              sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
            sqlite3PExpr(pParse, TK_DOT, 
              sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
            );
        pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
        pWhen = sqlite3ExprAnd(db, pWhen, pEq);
      }
  
      if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
        Expr *pNew;
        if( action==OE_Cascade ){
          pNew = sqlite3PExpr(pParse, TK_DOT, 
            sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0));
        }else if( action==OE_SetDflt ){
          Column *pCol = pFKey->pFrom->aCol + iFromCol;
          Expr *pDflt;
          Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
          if( pCol->colFlags & COLFLAG_GENERATED ){
            testcase( pCol->colFlags & COLFLAG_VIRTUAL );
            testcase( pCol->colFlags & COLFLAG_STORED );
            pDflt = 0;
          }else{
            pDflt = pCol->pDflt;
          }
          if( pDflt ){
            pNew = sqlite3ExprDup(db, pDflt, 0);
          }else{
            pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
          }
        }else{
          pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
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
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







-
+











-
+







      Token tFrom;
      Expr *pRaise; 

      tFrom.z = zFrom;
      tFrom.n = nFrom;
      pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
      if( pRaise ){
        pRaise->affExpr = OE_Abort;
        pRaise->affinity = OE_Abort;
      }
      pSelect = sqlite3SelectNew(pParse, 
          sqlite3ExprListAppend(pParse, 0, pRaise),
          sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
          pWhere,
          0, 0, 0, 0, 0
      );
      pWhere = 0;
    }

    /* Disable lookaside memory allocation */
    DisableLookaside;
    db->lookaside.bDisable++;

    pTrigger = (Trigger *)sqlite3DbMallocZero(db, 
        sizeof(Trigger) +         /* struct Trigger */
        sizeof(TriggerStep) +     /* Single step in trigger program */
        nFrom + 1                 /* Space for pStep->zTarget */
    );
    if( pTrigger ){
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
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







-
+










-



-
+






-







      if( pWhen ){
        pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0);
        pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
      }
    }

    /* Re-enable the lookaside buffer, if it was disabled earlier. */
    EnableLookaside;
    db->lookaside.bDisable--;

    sqlite3ExprDelete(db, pWhere);
    sqlite3ExprDelete(db, pWhen);
    sqlite3ExprListDelete(db, pList);
    sqlite3SelectDelete(db, pSelect);
    if( db->mallocFailed==1 ){
      fkTriggerDelete(db, pTrigger);
      return 0;
    }
    assert( pStep!=0 );
    assert( pTrigger!=0 );

    switch( action ){
      case OE_Restrict:
        pStep->op = TK_SELECT;
        pStep->op = TK_SELECT; 
        break;
      case OE_Cascade: 
        if( !pChanges ){ 
          pStep->op = TK_DELETE; 
          break; 
        }
        /* no break */ deliberate_fall_through
      default:
        pStep->op = TK_UPDATE;
    }
    pStep->pTrig = pTrigger;
    pTrigger->pSchema = pTab->pSchema;
    pTrigger->pTabSchema = pTab->pSchema;
    pFKey->apTrigger[iAction] = pTrigger;

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
12
13
14
15
16
17
18



19
20
21
22
23
24
25







-
-
-







** This file contains the C-language implementations for many of the SQL
** functions of SQLite.  (Some function, and in particular the date and
** time functions, are implemented separately.)
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <assert.h>
#ifndef SQLITE_OMIT_FLOATING_POINT
#include <math.h>
#endif
#include "vdbeInt.h"

/*
** Return the collating function associated with a function.
*/
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
  VdbeOp *pOp;
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
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







-
-












-
+



-
-
-
-
-
-
-
-
-
-

-
+













-
-
-
-
-
-
-







  const unsigned char *zNeedle;
  int nHaystack;
  int nNeedle;
  int typeHaystack, typeNeedle;
  int N = 1;
  int isText;
  unsigned char firstChar;
  sqlite3_value *pC1 = 0;
  sqlite3_value *pC2 = 0;

  UNUSED_PARAMETER(argc);
  typeHaystack = sqlite3_value_type(argv[0]);
  typeNeedle = sqlite3_value_type(argv[1]);
  if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
  nHaystack = sqlite3_value_bytes(argv[0]);
  nNeedle = sqlite3_value_bytes(argv[1]);
  if( nNeedle>0 ){
    if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
      zHaystack = sqlite3_value_blob(argv[0]);
      zNeedle = sqlite3_value_blob(argv[1]);
      isText = 0;
    }else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){
    }else{
      zHaystack = sqlite3_value_text(argv[0]);
      zNeedle = sqlite3_value_text(argv[1]);
      isText = 1;
    }else{
      pC1 = sqlite3_value_dup(argv[0]);
      zHaystack = sqlite3_value_text(pC1);
      if( zHaystack==0 ) goto endInstrOOM;
      nHaystack = sqlite3_value_bytes(pC1);
      pC2 = sqlite3_value_dup(argv[1]);
      zNeedle = sqlite3_value_text(pC2);
      if( zNeedle==0 ) goto endInstrOOM;
      nNeedle = sqlite3_value_bytes(pC2);
      isText = 1;
    }
    if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM;
    if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
    firstChar = zNeedle[0];
    while( nNeedle<=nHaystack
       && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
    ){
      N++;
      do{
        nHaystack--;
        zHaystack++;
      }while( isText && (zHaystack[0]&0xc0)==0x80 );
    }
    if( nNeedle>nHaystack ) N = 0;
  }
  sqlite3_result_int(context, N);
endInstr:
  sqlite3_value_free(pC1);
  sqlite3_value_free(pC2);
  return;
endInstrOOM:
  sqlite3_result_error_nomem(context);
  goto endInstr;
}

/*
** Implementation of the printf() function.
*/
static void printfFunc(
  sqlite3_context *context,
404
405
406
407
408
409
410
411
412
413
414




415
416
417
418
419
420
421
382
383
384
385
386
387
388




389
390
391
392
393
394
395
396
397
398
399







-
-
-
-
+
+
+
+







  }
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  r = sqlite3_value_double(argv[0]);
  /* If Y==0 and X will fit in a 64-bit int,
  ** handle the rounding directly,
  ** otherwise use printf.
  */
  if( r<-4503599627370496.0 || r>+4503599627370496.0 ){
    /* The value has no fractional part so there is nothing to round */
  }else if( n==0 ){  
    r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
  if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
    r = (double)((sqlite_int64)(r+0.5));
  }else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
    r = -(double)((sqlite_int64)((-r)+0.5));
  }else{
    zBuf = sqlite3_mprintf("%.*f",n,r);
    if( zBuf==0 ){
      sqlite3_result_error_nomem(context);
      return;
    }
    sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
690
691
692
693
694
695
696
697

698
699
700
701
702
703
704
705
668
669
670
671
672
673
674

675

676
677
678
679
680
681
682







-
+
-







  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 
      while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
             || (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 ){
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
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







-












+
+











+
+












-
-
-
-
-
-



-
-







  sqlite3_value **argv
){
  const unsigned char *zA, *zB;
  u32 escape;
  int nPat;
  sqlite3 *db = sqlite3_context_db_handle(context);
  struct compareInfo *pInfo = sqlite3_user_data(context);
  struct compareInfo backupInfo;

#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
  if( sqlite3_value_type(argv[0])==SQLITE_BLOB
   || sqlite3_value_type(argv[1])==SQLITE_BLOB
  ){
#ifdef SQLITE_TEST
    sqlite3_like_count++;
#endif
    sqlite3_result_int(context, 0);
    return;
  }
#endif
  zB = sqlite3_value_text(argv[0]);
  zA = sqlite3_value_text(argv[1]);

  /* Limit the length of the LIKE or GLOB pattern to avoid problems
  ** of deep recursion and N*N behavior in patternCompare().
  */
  nPat = sqlite3_value_bytes(argv[0]);
  testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] );
  testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
  if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
    sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
    return;
  }
  assert( zB==sqlite3_value_text(argv[0]) );  /* Encoding did not change */

  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
    if( zEsc==0 ) return;
    if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
      sqlite3_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite3Utf8Read(&zEsc);
    if( escape==pInfo->matchAll || escape==pInfo->matchOne ){
      memcpy(&backupInfo, pInfo, sizeof(backupInfo));
      pInfo = &backupInfo;
      if( escape==pInfo->matchAll ) pInfo->matchAll = 0;
      if( escape==pInfo->matchOne ) pInfo->matchOne = 0;
    }
  }else{
    escape = pInfo->matchSet;
  }
  zB = sqlite3_value_text(argv[0]);
  zA = sqlite3_value_text(argv[1]);
  if( zA && zB ){
#ifdef SQLITE_TEST
    sqlite3_like_count++;
#endif
    sqlite3_result_int(context,
                      patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
  }
1280
1281
1282
1283
1284
1285
1286
1287

1288
1289
1290
1291
1292
1293
1294
1252
1253
1254
1255
1256
1257
1258

1259
1260
1261
1262
1263
1264
1265
1266







-
+







        }
        cntExpand++;
        if( (cntExpand&(cntExpand-1))==0 ){
          /* Grow the size of the output buffer only on substitutions
          ** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */
          u8 *zOld;
          zOld = zOut;
          zOut = sqlite3Realloc(zOut, (int)nOut + (nOut - nStr - 1));
          zOut = sqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1));
          if( zOut==0 ){
            sqlite3_result_error_nomem(context);
            sqlite3_free(zOld);
            return;
          }
        }
      }
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
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







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

-
+



-


-


-



-
-
+
+
+
+
+







  assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
  if( rc==SQLITE_NOMEM ){
    sqlite3OomFault(db);
  }
}

/*
** Set the LIKEOPT flag on the 2-argument function with the given name.
*/
static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
  FuncDef *pDef;
  pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
  if( ALWAYS(pDef) ){
    pDef->funcFlags |= flagVal;
  }
  pDef = sqlite3FindFunction(db, zName, 3, SQLITE_UTF8, 0);
  if( pDef ){
    pDef->funcFlags |= flagVal;
  }
}

/*
** Re-register the built-in LIKE functions.  The caseSensitive
** Register the built-in LIKE and GLOB functions.  The caseSensitive
** parameter determines whether or not the LIKE operator is case
** sensitive.
** sensitive.  GLOB is always case sensitive.
*/
void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
  struct compareInfo *pInfo;
  int flags;
  if( caseSensitive ){
    pInfo = (struct compareInfo*)&likeInfoAlt;
    flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
  }else{
    pInfo = (struct compareInfo*)&likeInfoNorm;
    flags = SQLITE_FUNC_LIKE;
  }
  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
  sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
  sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
  sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
      (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
  setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
  setLikeOptFlag(db, "like", 
      caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
}

/*
** pExpr points to an expression which implements a function.  If
** it is appropriate to apply the LIKE optimization to that function
** then set aWc[0] through aWc[2] to the wildcard characters and the
** escape character and then return TRUE.  If the function is not a 
1862
1863
1864
1865
1866
1867
1868
1869
1870

1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882










1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139


2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150






2151
2152
2153
2154
2155
2156
2157
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







-
-
+
-





-
-
-



+
+
+
+
+
+
+
+
+
+









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




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



















-
-
-
-
-
-
-
-




-
-
+
+








-
-
-
+
+
+
+
+
+







** 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->op!=TK_FUNCTION || !pExpr->x.pList ){
  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;
#endif
  if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
    return 0;
  }
  if( nExpr<3 ){
    aWc[3] = 0;
  }else{
    Expr *pEscape = pExpr->x.pList->a[2].pExpr;
    char *zEscape;
    if( pEscape->op!=TK_STRING ) return 0;
    zEscape = pEscape->u.zToken;
    if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
    aWc[3] = zEscape[0];
  }

  /* The memcpy() statement assumes that the wildcard characters are
  ** the first three statements in the compareInfo structure.  The
  ** asserts() that follow verify that assumption
  */
  memcpy(aWc, pDef->pUserData, 3);
  assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
  assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
  assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );

  if( nExpr<3 ){
    aWc[3] = 0;
  }else{
    Expr *pEscape = pExpr->x.pList->a[2].pExpr;
    char *zEscape;
    if( pEscape->op!=TK_STRING ) return 0;
    zEscape = pEscape->u.zToken;
    if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
    if( zEscape[0]==aWc[0] ) return 0;
    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
*/
void sqlite3RegisterBuiltinFunctions(void){
  /*
  ** The following array holds FuncDef structures for all of the functions
  ** defined in this file.
  **
  ** The array cannot be constant since changes are made to the
  ** FuncDef.pHash elements at start-time.  The elements of this array
  ** are read-only after initialization is complete.
  **
  ** For peak efficiency, put the most frequently used function last.
  */
  static FuncDef aBuiltinFunc[] = {
/***** Functions only available with SQLITE_TESTCTRL_INTERNAL_FUNCTIONS *****/
    TEST_FUNC(implies_nonnull_row, 2, INLINEFUNC_implies_nonnull_row, 0),
    TEST_FUNC(expr_compare,        2, INLINEFUNC_expr_compare,        0),
    TEST_FUNC(expr_implies_expr,   2, INLINEFUNC_expr_implies_expr,   0),
#ifdef SQLITE_DEBUG
    TEST_FUNC(affinity,          1, INLINEFUNC_affinity, 0),
#endif
/***** Regular functions *****/
#ifdef SQLITE_SOUNDEX
    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
    SFUNCTION(load_extension,    1, 0, 0, loadExt          ),
    SFUNCTION(load_extension,    2, 0, 0, loadExt          ),
    VFUNCTION(load_extension,    1, 0, 0, loadExt          ),
    VFUNCTION(load_extension,    2, 0, 0, loadExt          ),
#endif
#if SQLITE_USER_AUTHENTICATION
    FUNCTION(sqlite_crypt,       2, 0, 0, sqlite3CryptFunc ),
#endif
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
    DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
    DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
    INLINE_FUNC(unlikely,        1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
    INLINE_FUNC(likelihood,      2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
    INLINE_FUNC(likely,          1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
    FUNCTION2(unlikely,          1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
    FUNCTION2(likelihood,        2, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
    FUNCTION2(likely,            1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
#ifdef SQLITE_DEBUG
    FUNCTION2(affinity,          1, 0, 0, noopFunc,  SQLITE_FUNC_AFFINITY),
#endif
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
    FUNCTION2(sqlite_offset,     1, 0, 0, noopFunc,  SQLITE_FUNC_OFFSET|
                                                     SQLITE_FUNC_TYPEOF),
#endif
    FUNCTION(ltrim,              1, 1, 0, trimFunc         ),
    FUNCTION(ltrim,              2, 1, 0, trimFunc         ),
    FUNCTION(rtrim,              1, 2, 0, trimFunc         ),
2176
2177
2178
2179
2180
2181
2182
2183

2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
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







-
+














-
-







#ifndef SQLITE_OMIT_FLOATING_POINT
    FUNCTION(round,              1, 0, 0, roundFunc        ),
    FUNCTION(round,              2, 0, 0, roundFunc        ),
#endif
    FUNCTION(upper,              1, 0, 0, upperFunc        ),
    FUNCTION(lower,              1, 0, 0, lowerFunc        ),
    FUNCTION(hex,                1, 0, 0, hexFunc          ),
    INLINE_FUNC(ifnull,          2, INLINEFUNC_coalesce, 0 ),
    FUNCTION2(ifnull,            2, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
    VFUNCTION(random,            0, 0, 0, randomFunc       ),
    VFUNCTION(randomblob,        1, 0, 0, randomBlob       ),
    FUNCTION(nullif,             2, 0, 1, nullifFunc       ),
    DFUNCTION(sqlite_version,    0, 0, 0, versionFunc      ),
    DFUNCTION(sqlite_source_id,  0, 0, 0, sourceidFunc     ),
    FUNCTION(sqlite_log,         2, 0, 0, errlogFunc       ),
    FUNCTION(quote,              1, 0, 0, quoteFunc        ),
    VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
    VFUNCTION(changes,           0, 0, 0, changes          ),
    VFUNCTION(total_changes,     0, 0, 0, total_changes    ),
    FUNCTION(replace,            3, 0, 0, replaceFunc      ),
    FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
    FUNCTION(substr,             2, 0, 0, substrFunc       ),
    FUNCTION(substr,             3, 0, 0, substrFunc       ),
    FUNCTION(substring,          2, 0, 0, substrFunc       ),
    FUNCTION(substring,          3, 0, 0, substrFunc       ),
    WAGGREGATE(sum,   1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0),
    WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0),
    WAGGREGATE(avg,   1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0),
    WAGGREGATE(count, 0,0,0, countStep, 
        countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT  ),
    WAGGREGATE(count, 1,0,0, countStep, 
        countFinalize, countFinalize, countInverse, 0  ),
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262

2263
2264
2265
2266
2267
2268



2269
2270
2271
2272
2273
2274
2275
1992
1993
1994
1995
1996
1997
1998






































1999

2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014







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





+
+
+







    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 ),
    FUNCTION2(coalesce,         -1, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
    INLINE_FUNC(iif,             3, INLINEFUNC_iif,      0 ),
  };
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions();
#endif
  sqlite3WindowFunctions();
#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
  sqlite3AnalyzeFunctions();
#endif
  sqlite3RegisterDateTimeFunctions();
  sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));

#if 0  /* Enable to print out how the built-in functions are hashed */
  {
    int i;
    FuncDef *p;

Changes to src/global.c.

83
84
85
86
87
88
89

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







+







** array. tolower() is used more often than toupper() by SQLite.
**
** Bit 0x40 is set if the character is non-alphanumeric and can be used in an 
** SQLite identifier.  Identifiers are alphanumerics, "_", "$", and any
** non-ASCII UTF character. Hence the test for whether or not a character is
** part of an identifier is 0x46.
*/
#ifdef SQLITE_ASCII
const unsigned char sqlite3CtypeMap[256] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 00..07    ........ */
  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
  0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80,  /* 20..27     !"#$%&' */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 28..2f    ()*+,-./ */
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
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







+











+
+
+


+
+
+
-
+
+






-
+

-
-
-
-
-
-
-







  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d0..d7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d8..df    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
};
#endif

/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
** compatibility for legacy applications, the URI filename capability is
** disabled by default.
**
** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
**
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.
**
** URI filenames are enabled by default if SQLITE_HAS_CODEC is
** enabled.
*/
#ifndef SQLITE_USE_URI
# ifdef SQLITE_HAS_CODEC
#  define SQLITE_USE_URI 1
# else
# define SQLITE_USE_URI 0
#  define SQLITE_USE_URI 0
# endif
#endif

/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
#if !defined(SQLITE_ALLOW_COVERING_INDEX_SCAN)
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
#else
# if !SQLITE_ALLOW_COVERING_INDEX_SCAN 
#   error "Compile-time disabling of covering index scan using the\
 -DSQLITE_ALLOW_COVERING_INDEX_SCAN=0 option is deprecated.\
 Contact SQLite developers if this is a problem for you, and\
 delete this #error macro to continue with your build."
# endif
#endif

/* The minimum PMA size is set to this value multiplied by the database
** page size in bytes.
*/
#ifndef SQLITE_SORTER_PMASZ
# define SQLITE_SORTER_PMASZ 250
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
179
180
181
182
183
184
185





186
187


188



189
190
191
192
193
194
195







-
-
-
-
-


-
-
+
-
-
-







/*
** The default lookaside-configuration, the format "SZ,N".  SZ is the
** number of bytes in each lookaside slot (should be a multiple of 8)
** and N is the number of slots.  The lookaside-configuration can be
** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE)
** or at run-time for an individual database connection using
** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE);
**
** With the two-size-lookaside enhancement, less lookaside is required.
** The default configuration of 1200,40 actually provides 30 1200-byte slots
** and 93 128-byte slots, which is more lookaside than is available
** using the older 1200,100 configuration without two-size-lookaside.
*/
#ifndef SQLITE_DEFAULT_LOOKASIDE
# ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE
#   define SQLITE_DEFAULT_LOOKASIDE 1200,100  /* 120KB of memory */
# define SQLITE_DEFAULT_LOOKASIDE 1200,100
# else
#   define SQLITE_DEFAULT_LOOKASIDE 1200,40   /* 48KB of memory */
# endif
#endif


/* The default maximum size of an in-memory database created using
** sqlite3_deserialize()
*/
#ifndef SQLITE_MEMDB_DEFAULT_MAXSIZE
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
203
204
205
206
207
208
209

210
211
212
213
214
215
216







-







SQLITE_WSD struct Sqlite3Config sqlite3Config = {
   SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
   1,                         /* bCoreMutex */
   SQLITE_THREADSAFE==1,      /* bFullMutex */
   SQLITE_USE_URI,            /* bOpenUri */
   SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
   0,                         /* bSmallMalloc */
   1,                         /* bExtraSchemaChecks */
   0x7ffffffe,                /* mxStrlen */
   0,                         /* neverCorrupt */
   SQLITE_DEFAULT_LOOKASIDE,  /* szLookaside, nLookaside */
   SQLITE_STMTJRNL_SPILL,     /* nStmtSpill */
   {0,0,0,0,0,0,0,0},         /* m */
   {0,0,0,0,0,0,0,0,0},       /* mutex */
   {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
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
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







+


-








+
+
+
+
+
+
+
+







#ifdef SQLITE_ENABLE_DESERIALIZE
   SQLITE_MEMDB_DEFAULT_MAXSIZE,   /* mxMemdbSize */
#endif
#ifndef SQLITE_UNTESTABLE
   0,                         /* xTestCallback */
#endif
   0,                         /* bLocaltimeFault */
   0,                         /* bInternalFunctions */
   0x7ffffffe,                /* iOnceResetThreshold */
   SQLITE_DEFAULT_SORTERREF_SIZE,   /* szSorterRef */
   0,                         /* iPrngSeed */
};

/*
** Hash table for global functions - functions common to all
** database connections.  After initialization, this table is
** read-only.
*/
FuncDefHash sqlite3BuiltinFunctions;

/*
** Constant tokens for values 0 and 1.
*/
const Token sqlite3IntTokens[] = {
   { "0", 1 },
   { "1", 1 }
};

#ifdef VDBE_PROFILE
/*
** The following performance counter can be used in place of
** sqlite3Hwtime() for profiling.  This is a no-op on standard builds.
*/
sqlite3_uint64 sqlite3NProfileCnt = 0;
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
296
297
298
299
300
301
302






303
304
305
306
307
308
309
310
311
312
313
314
315







-
-
-
-
-
-













** Changing the pending byte during operation will result in undefined
** 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.  
*/
const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;

/*
** Name of the default collating sequence
*/
const char sqlite3StrBINARY[] = "BINARY";

Changes to src/hwtime.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72


73
74
75

76
77



78
79

80
81
82
83
84
85
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













-
+










-
-
-
+
+




















-
+







-
+
















+
+

-
-
+
-
-
+
+
+
-
-
+






/*
** 2008 May 27
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains inline asm code for retrieving "high-performance"
** counters for x86 and x86_64 class CPUs.
** counters for x86 class CPUs.
*/
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H

/*
** The following routine only works on pentium-class (or newer) processors.
** It uses the RDTSC opcode to read the cycle count value out of the
** processor and returns that value.  This can be used for high-res
** profiling.
*/
#if !defined(__STRICT_ANSI__) && \
    (defined(__GNUC__) || defined(_MSC_VER)) && \
    (defined(i386) || defined(__i386__) || defined(_M_IX86))
#if (defined(__GNUC__) || defined(_MSC_VER)) && \
      (defined(i386) || defined(__i386__) || defined(_M_IX86))

  #if defined(__GNUC__)

  __inline__ sqlite_uint64 sqlite3Hwtime(void){
     unsigned int lo, hi;
     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
     return (sqlite_uint64)hi << 32 | lo;
  }

  #elif defined(_MSC_VER)

  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
     __asm {
        rdtsc
        ret       ; return value at EDX:EAX
     }
  }

  #endif

#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
#elif (defined(__GNUC__) && defined(__x86_64__))

  __inline__ sqlite_uint64 sqlite3Hwtime(void){
      unsigned long val;
      __asm__ __volatile__ ("rdtsc" : "=A" (val));
      return val;
  }
 
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
#elif (defined(__GNUC__) && defined(__ppc__))

  __inline__ sqlite_uint64 sqlite3Hwtime(void){
      unsigned long long retval;
      unsigned long junk;
      __asm__ __volatile__ ("\n\
          1:      mftbu   %1\n\
                  mftb    %L0\n\
                  mftbu   %0\n\
                  cmpw    %0,%1\n\
                  bne     1b"
                  : "=r" (retval), "=r" (junk));
      return retval;
  }

#else

  #error Need implementation of sqlite3Hwtime() for your platform.

  /*
  ** asm() is needed for hardware timing support.  Without asm(),
  ** disable the sqlite3Hwtime() routine.
  ** To compile without implementing sqlite3Hwtime() for your platform,
  **
  ** sqlite3Hwtime() is only used for some obscure debugging
  ** you can remove the above #error and use the following
  ** stub function.  You will lose timing support for many
  ** of the debugging and testing utilities, but it should at
  ** and analysis configurations, not in any deliverable, so this
  ** should not be a great loss.
  ** least compile and run.
  */
  sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }

#endif

#endif /* !defined(SQLITE_HWTIME_H) */

Changes to src/insert.c.

28
29
30
31
32
33
34
35
36

37
38
39
40
41

42
43
44
45
46
47
48
28
29
30
31
32
33
34


35
36
37
38
39

40
41
42
43
44
45
46
47







-
-
+




-
+







  int iCur,       /* The cursor number of the table */
  int iDb,        /* The database index in sqlite3.aDb[] */
  Table *pTab,    /* The table to be opened */
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  Vdbe *v;
  assert( !IsVirtual(pTab) );
  assert( pParse->pVdbe!=0 );
  v = pParse->pVdbe;
  v = sqlite3GetVdbe(pParse);
  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  sqlite3TableLock(pParse, iDb, pTab->tnum, 
                   (opcode==OP_OpenWrite)?1:0, pTab->zName);
  if( HasRowid(pTab) ){
    sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol);
    sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
    VdbeComment((v, "%s", pTab->zName));
  }else{
    Index *pPk = sqlite3PrimaryKeyIndex(pTab);
    assert( pPk!=0 );
    assert( pPk->tnum==pTab->tnum );
    sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
    sqlite3VdbeSetP4KeyInfo(pParse, pPk);
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
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







-

-
+

-
+

+



-
-
+
-
-
+
+







    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
    if( !pIdx->zColAff ){
      sqlite3OomFault(db);
      return 0;
    }
    for(n=0; n<pIdx->nColumn; n++){
      i16 x = pIdx->aiColumn[n];
      char aff;
      if( x>=0 ){
        aff = pTab->aCol[x].affinity;
        pIdx->zColAff[n] = pTab->aCol[x].affinity;
      }else if( x==XN_ROWID ){
        aff = SQLITE_AFF_INTEGER;
        pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
      }else{
        char aff;
        assert( x==XN_EXPR );
        assert( pIdx->aColExpr!=0 );
        aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
      }
      if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB;
        if( aff==0 ) aff = SQLITE_AFF_BLOB;
      if( aff>SQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC;
      pIdx->zColAff[n] = aff;
        pIdx->zColAff[n] = aff;
      }
    }
    pIdx->zColAff[n] = 0;
  }
 
  return pIdx->zColAff;
}

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







-
+









-
+
-
-
-
-
+
+
-

-
-
+
+







**  'A'            BLOB
**  'B'            TEXT
**  'C'            NUMERIC
**  'D'            INTEGER
**  'E'            REAL
*/
void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
  int i, j;
  int i;
  char *zColAff = pTab->zColAff;
  if( zColAff==0 ){
    sqlite3 *db = sqlite3VdbeDb(v);
    zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
    if( !zColAff ){
      sqlite3OomFault(db);
      return;
    }

    for(i=j=0; i<pTab->nCol; i++){
    for(i=0; i<pTab->nCol; i++){
      assert( pTab->aCol[i].affinity!=0 );
      if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
        zColAff[j++] = pTab->aCol[i].affinity;
      }
      zColAff[i] = pTab->aCol[i].affinity;
    }
    }
    do{
      zColAff[j--] = 0;
    }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB );
      zColAff[i--] = 0;
    }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
    pTab->zColAff = zColAff;
  }
  assert( zColAff!=0 );
  i = sqlite3Strlen30NN(zColAff);
  if( i ){
    if( iReg ){
      sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
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
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







-
+



















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







#endif

  for(i=1; i<iEnd; i++){
    VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
    assert( pOp!=0 );
    if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
      Index *pIndex;
      Pgno tnum = pOp->p2;
      int tnum = pOp->p2;
      if( tnum==pTab->tnum ){
        return 1;
      }
      for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
        if( tnum==pIndex->tnum ){
          return 1;
        }
      }
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){
      assert( pOp->p4.pVtab!=0 );
      assert( pOp->p4type==P4_VTAB );
      return 1;
    }
#endif
  }
  return 0;
}

/* This walker callback will compute the union of colFlags flags for all
** referenced columns in a CHECK constraint or generated column expression.
*/
static int exprColumnFlagUnion(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 ){
    assert( pExpr->iColumn < pWalker->u.pTab->nCol );
    pWalker->eCode |= pWalker->u.pTab->aCol[pExpr->iColumn].colFlags;
  }
  return WRC_Continue;
}

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/*
** All regular columns for table pTab have been puts into registers
** starting with iRegStore.  The registers that correspond to STORED
** or VIRTUAL columns have not yet been initialized.  This routine goes
** back and computes the values for those columns based on the previously
** computed normal columns.
*/
void sqlite3ComputeGeneratedColumns(
  Parse *pParse,    /* Parsing context */
  int iRegStore,    /* Register holding the first column */
  Table *pTab       /* The table */
){
  int i;
  Walker w;
  Column *pRedo;
  int eProgress;
  VdbeOp *pOp;

  assert( pTab->tabFlags & TF_HasGenerated );
  testcase( pTab->tabFlags & TF_HasVirtual );
  testcase( pTab->tabFlags & TF_HasStored );

  /* Before computing generated columns, first go through and make sure
  ** that appropriate affinity has been applied to the regular columns
  */
  sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
  if( (pTab->tabFlags & TF_HasStored)!=0
   && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity
  ){
    /* Change the OP_Affinity argument to '@' (NONE) for all stored
    ** columns.  '@' is the no-op affinity and those columns have not
    ** yet been computed. */
    int ii, jj;
    char *zP4 = pOp->p4.z;
    assert( zP4!=0 );
    assert( pOp->p4type==P4_DYNAMIC );
    for(ii=jj=0; zP4[jj]; ii++){
      if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
        continue;
      }
      if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
        zP4[jj] = SQLITE_AFF_NONE;
      }
      jj++;
    }
  }

  /* Because there can be multiple generated columns that refer to one another,
  ** this is a two-pass algorithm.  On the first pass, mark all generated
  ** columns as "not available".
  */
  for(i=0; i<pTab->nCol; i++){
    if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){
      testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL );
      testcase( pTab->aCol[i].colFlags & COLFLAG_STORED );
      pTab->aCol[i].colFlags |= COLFLAG_NOTAVAIL;
    }
  }

  w.u.pTab = pTab;
  w.xExprCallback = exprColumnFlagUnion;
  w.xSelectCallback = 0;
  w.xSelectCallback2 = 0;

  /* On the second pass, compute the value of each NOT-AVAILABLE column.
  ** Companion code in the TK_COLUMN case of sqlite3ExprCodeTarget() will
  ** compute dependencies and mark remove the COLSPAN_NOTAVAIL mark, as
  ** they are needed.
  */
  pParse->iSelfTab = -iRegStore;
  do{
    eProgress = 0;
    pRedo = 0;
    for(i=0; i<pTab->nCol; i++){
      Column *pCol = pTab->aCol + i;
      if( (pCol->colFlags & COLFLAG_NOTAVAIL)!=0 ){
        int x;
        pCol->colFlags |= COLFLAG_BUSY;
        w.eCode = 0;
        sqlite3WalkExpr(&w, pCol->pDflt);
        pCol->colFlags &= ~COLFLAG_BUSY;
        if( w.eCode & COLFLAG_NOTAVAIL ){
          pRedo = pCol;
          continue;
        }
        eProgress = 1;
        assert( pCol->colFlags & COLFLAG_GENERATED );
        x = sqlite3TableColumnToStorage(pTab, i) + iRegStore;
        sqlite3ExprCodeGeneratedColumn(pParse, pCol, x);
        pCol->colFlags &= ~COLFLAG_NOTAVAIL;
      }
    }
  }while( pRedo && eProgress );
  if( pRedo ){
    sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zName);
  }
  pParse->iSelfTab = 0;
}
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */


#ifndef SQLITE_OMIT_AUTOINCREMENT
/*
** Locate or create an AutoincInfo structure associated with table pTab
** which is in database iDb.  Return the register number for the register
** that holds the maximum rowid.  Return zero if pTab is not an AUTOINCREMENT
** table.  (Also return zero when doing a VACUUM since we do not want to
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
248
249
250
251
252
253
254



255
256
257
258
259
260
261
262







-
-
-
+







      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;
      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 */
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
500
501
502
503
504
505
506

507
508
509
510
511
512
513
514







-
+







**         end loop
**      D: cleanup
*/
void sqlite3Insert(
  Parse *pParse,        /* Parser context */
  SrcList *pTabList,    /* Name of table into which we are inserting */
  Select *pSelect,      /* A SELECT statement to use as the data source */
  IdList *pColumn,      /* Column names corresponding to IDLIST, or NULL. */
  IdList *pColumn,      /* Column names corresponding to IDLIST. */
  int onError,          /* How to handle constraint errors */
  Upsert *pUpsert       /* ON CONFLICT clauses for upsert, or NULL */
){
  sqlite3 *db;          /* The main database structure */
  Table *pTab;          /* The table to insert into.  aka TABLE */
  int i, j;             /* Loop counters */
  Vdbe *v;              /* Generate code into this virtual machine */
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
525
526
527
528
529
530
531

532
533
534
535
536
537
538







-







  SelectDest dest;      /* Destination for SELECT on rhs of INSERT */
  int iDb;              /* Index of database holding TABLE */
  u8 useTempTable = 0;  /* Store SELECT results in intermediate table */
  u8 appendFlag = 0;    /* True if the insert is likely to be an append */
  u8 withoutRowid;      /* 0 for normal table.  1 for WITHOUT ROWID table */
  u8 bIdListInOrder;    /* True if IDLIST is in table order */
  ExprList *pList = 0;  /* List of VALUES() to be inserted  */
  int iRegStore;        /* Register in which to store next column */

  /* Register allocations */
  int regFromSelect = 0;/* Base register for data coming from SELECT */
  int regAutoinc = 0;   /* Register holding the AUTOINCREMENT counter */
  int regRowCount = 0;  /* Memory cell used for the row counter */
  int regIns;           /* Block of regs holding rowid+data being inserted */
  int regRowid;         /* registers holding insert rowid */
753
754
755
756
757
758
759
760
761


762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
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







-
-
+
+


















-
+
-
-
-
-
-
-
-
-

-
+












-
-
-
-
-
-
-
-







#endif /* SQLITE_OMIT_XFER_OPT */

  /* If this is an AUTOINCREMENT table, look up the sequence number in the
  ** sqlite_sequence table and store it in memory cell regAutoinc.
  */
  regAutoinc = autoIncBegin(pParse, iDb, pTab);

  /* Allocate a block registers to hold the rowid and the values
  ** for all columns of the new row.
  /* Allocate registers for holding the rowid of the new row,
  ** the content of the new row, and the assembled row record.
  */
  regRowid = regIns = pParse->nMem+1;
  pParse->nMem += pTab->nCol + 1;
  if( IsVirtual(pTab) ){
    regRowid++;
    pParse->nMem++;
  }
  regData = regRowid+1;

  /* If the INSERT statement included an IDLIST term, then make sure
  ** all elements of the IDLIST really are columns of the table and 
  ** remember the column indices.
  **
  ** If the table has an INTEGER PRIMARY KEY column and that column
  ** is named in the IDLIST, then record in the ipkColumn variable
  ** the index into IDLIST of the primary key column.  ipkColumn is
  ** the index of the primary key as it appears in IDLIST, not as
  ** is appears in the original table.  (The index of the INTEGER
  ** PRIMARY KEY in the original table is pTab->iPKey.)  After this
  ** PRIMARY KEY in the original table is pTab->iPKey.)
  ** loop, if ipkColumn==(-1), that means that integer primary key
  ** is unspecified, and hence the table is either WITHOUT ROWID or
  ** it will automatically generated an integer primary key.
  **
  ** bIdListInOrder is true if the columns in IDLIST are in storage
  ** order.  This enables an optimization that avoids shuffling the
  ** columns into storage order.  False negatives are harmless,
  ** but false positives will cause database corruption.
  */
  bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
  bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
  if( pColumn ){
    for(i=0; i<pColumn->nId; i++){
      pColumn->a[i].idx = -1;
    }
    for(i=0; i<pColumn->nId; i++){
      for(j=0; j<pTab->nCol; j++){
        if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
          pColumn->a[i].idx = j;
          if( i!=j ) bIdListInOrder = 0;
          if( j==pTab->iPKey ){
            ipkColumn = i;  assert( !withoutRowid );
          }
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
          if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){
            sqlite3ErrorMsg(pParse, 
               "cannot INSERT into generated column \"%s\"",
               pTab->aCol[j].zName);
            goto insert_cleanup;
          }
#endif
          break;
        }
      }
      if( j>=pTab->nCol ){
        if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
          ipkColumn = i;
          bIdListInOrder = 0;
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930


931
932
933
934
935
936



937
938
939
940
941
942
943



944
945
946
947
948
949





950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973

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






1008
1009

1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
776
777
778
779
780
781
782











783
784






785
786
787







788
789
790






791
792
793
794
795

796
797
798
799
800
801
802
803
804
805
806

807
808
809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
825

826
827
828

829
830
831
832
833







834








835
836
837
838
839
840


841



842
843
844
845
846
847
848







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











-










-
+








-



-





-
-
-
-
-
-
-

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








  /* If there is no IDLIST term but the table has an integer primary
  ** key, the set the ipkColumn variable to the integer primary key 
  ** column index in the original table definition.
  */
  if( pColumn==0 && nColumn>0 ){
    ipkColumn = pTab->iPKey;
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
    if( ipkColumn>=0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){
      testcase( pTab->tabFlags & TF_HasVirtual );
      testcase( pTab->tabFlags & TF_HasStored );
      for(i=ipkColumn-1; i>=0; i--){
        if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){
          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.
    */
  /* 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++;
      }
  for(i=0; i<pTab->nCol; i++){
    nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
  }
    }
    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 && 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 ){
    int nIdx;
    nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
                                      &iDataCur, &iIdxCur);
    aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
    aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
    if( aRegIdx==0 ){
      goto insert_cleanup;
    }
    for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
      assert( pIdx );
      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 ){
        if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){
    pUpsert->pUpsertSrc = pTabList;
    pUpsert->regData = regData;
    pUpsert->iDataCur = iDataCur;
    pUpsert->iIdxCur = iIdxCur;
    if( pUpsert->pUpsertTarget ){
      sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert);
          goto insert_cleanup;
        }
    }
      }
      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
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
861
862
863
864
865
866
867

868
869






870











































































871
872
873
874
875
876
877







-


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







    ** following pseudocode (template 3):
    **
    **      C: yield X, at EOF goto D
    **         insert the select result into <table> from R..R+n
    **         goto C
    **      D: ...
    */
    sqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0, 0);
    addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
    VdbeCoverage(v);
    if( ipkColumn>=0 ){
      /* tag-20191021-001: If the INTEGER PRIMARY KEY is being generated by the
      ** SELECT, go ahead and copy the value into the rowid slot now, so that
      ** the value does not get overwritten by a NULL at tag-20191021-002. */
      sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
    }
  }
  }

  /* Compute data for ordinary columns of the new entry.  Values
  ** are written in storage order into registers starting with regData.
  ** Only ordinary columns are computed in this loop. The rowid
  ** (if there is one) is computed later and generated columns are
  ** computed after the rowid since they might depend on the value
  ** of the rowid.
  */
  nHidden = 0;
  iRegStore = regData;  assert( regData==regRowid+1 );
  for(i=0; i<pTab->nCol; i++, iRegStore++){
    int k;
    u32 colFlags;
    assert( i>=nHidden );
    if( i==pTab->iPKey ){
      /* tag-20191021-002: References to the INTEGER PRIMARY KEY are filled
      ** using the rowid. So put a NULL in the IPK slot of the record to avoid
      ** using excess space.  The file format definition requires this extra
      ** NULL - we cannot optimize further by skipping the column completely */
      sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
      continue;
    }
    if( ((colFlags = pTab->aCol[i].colFlags) & COLFLAG_NOINSERT)!=0 ){
      nHidden++;
      if( (colFlags & COLFLAG_VIRTUAL)!=0 ){
        /* Virtual columns do not participate in OP_MakeRecord.  So back up
        ** iRegStore by one slot to compensate for the iRegStore++ in the
        ** outer for() loop */
        iRegStore--;
        continue;
      }else if( (colFlags & COLFLAG_STORED)!=0 ){
        /* Stored columns are computed later.  But if there are BEFORE
        ** triggers, the slots used for stored columns will be OP_Copy-ed
        ** to a second block of registers, so the register needs to be
        ** initialized to NULL to avoid an uninitialized register read */
        if( tmask & TRIGGER_BEFORE ){
          sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
        }
        continue;
      }else if( pColumn==0 ){
        /* Hidden columns that are not explicitly named in the INSERT
        ** get there default value */
        sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
        continue;
      }
    }
    if( pColumn ){
      for(j=0; j<pColumn->nId && pColumn->a[j].idx!=i; j++){}
      if( j>=pColumn->nId ){
        /* A column not named in the insert column list gets its
        ** default value */
        sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
        continue;
      }
      k = j;
    }else if( nColumn==0 ){
      /* This is INSERT INTO ... DEFAULT VALUES.  Load the default value. */
      sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
      continue;
    }else{
      k = i - nHidden;
    }

    if( useTempTable ){
      sqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore); 
    }else if( pSelect ){
      if( regFromSelect!=regData ){
        sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore);
      }
    }else{
      sqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore);
    }
  }


  /* Run the BEFORE and INSTEAD OF triggers, if there are any
  */
  endOfLoop = sqlite3VdbeMakeLabel(pParse);
  if( tmask & TRIGGER_BEFORE ){
    int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);

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
894
895
896
897
898
899
900


901
902
903
904

905




906
907
908
909
910






911
912
913
914
915
916
917
918
919
920
921
922

923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950

951
952
953

954
955
956
957
958
959
960
961







-
-
+
+
+
+
-

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

















+
+
+






-



-
+







      }
      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 );
    /* Cannot have triggers on a virtual table. If it were possible,
    ** this block would have to account for hidden column.
    */
    assert( !IsVirtual(pTab) );
    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
    ** computing the ROWID in case one of the generated columns
    /* Create the new column data
    */
    for(i=j=0; i<pTab->nCol; i++){
      if( pColumn ){
        for(j=0; j<pColumn->nId; j++){
    ** refers to the ROWID. */
    if( pTab->tabFlags & TF_HasGenerated ){
      testcase( pTab->tabFlags & TF_HasVirtual );
      testcase( pTab->tabFlags & TF_HasStored );
      sqlite3ComputeGeneratedColumns(pParse, regCols+1, pTab);
    }
          if( pColumn->a[j].idx==i ) break;
        }
      }
      if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId)
            || (pColumn==0 && IsOrdinaryHiddenColumn(&pTab->aCol[i])) ){
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
      }else if( useTempTable ){
        sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); 
      }else{
        assert( pSelect==0 ); /* Otherwise useTempTable is true */
        sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
      }
#endif
      if( pColumn==0 && !IsOrdinaryHiddenColumn(&pTab->aCol[i]) ) j++;
    }

    /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
    ** do not attempt any conversions before assembling the record.
    ** If this is a real table, attempt conversions as required by the
    ** table column affinities.
    */
    if( !isView ){
      sqlite3TableAffinity(v, pTab, regCols+1);
    }

    /* Fire BEFORE or INSTEAD OF triggers */
    sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
        pTab, regCols-pTab->nCol-1, onError, endOfLoop);

    sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
  }

  /* Compute the content of the next row to insert into a range of
  ** registers beginning at regIns.
  */
  if( !isView ){
    if( IsVirtual(pTab) ){
      /* The row that the VUpdate opcode will delete: none */
      sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
    }
    if( ipkColumn>=0 ){
      /* Compute the new rowid */
      if( useTempTable ){
        sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid);
      }else if( pSelect ){
        /* Rowid already initialized at tag-20191021-001 */
        sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
      }else{
        Expr *pIpk = pList->a[ipkColumn].pExpr;
        if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){
          sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
          appendFlag = 1;
        }else{
          sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236







































1237
1238
1239
1240
1241
1242
1243
980
981
982
983
984
985
986









987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032







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







      sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
    }else{
      sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
      appendFlag = 1;
    }
    autoIncStep(pParse, regAutoinc, regRowid);

#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
    ** computing the ROWID in case one of the generated columns
    ** is derived from the INTEGER PRIMARY KEY. */
    if( pTab->tabFlags & TF_HasGenerated ){
      sqlite3ComputeGeneratedColumns(pParse, regRowid+1, pTab);
    }
#endif
    /* Compute data for all columns of the new entry, beginning
    ** with the first column.
    */
    nHidden = 0;
    for(i=0; i<pTab->nCol; i++){
      int iRegStore = regRowid+1+i;
      if( i==pTab->iPKey ){
        /* The value of the INTEGER PRIMARY KEY column is always a NULL.
        ** Whenever this column is read, the rowid will be substituted
        ** in its place.  Hence, fill this column with a NULL to avoid
        ** taking up data space with information that will never be used.
        ** As there may be shallow copies of this value, make it a soft-NULL */
        sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
        continue;
      }
      if( pColumn==0 ){
        if( IsHiddenColumn(&pTab->aCol[i]) ){
          j = -1;
          nHidden++;
        }else{
          j = i - nHidden;
        }
      }else{
        for(j=0; j<pColumn->nId; j++){
          if( pColumn->a[j].idx==i ) break;
        }
      }
      if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
        sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
      }else if( useTempTable ){
        sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); 
      }else if( pSelect ){
        if( regFromSelect!=regData ){
          sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
        }
      }else{
        sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
      }
    }

    /* Generate code to check constraints and generate index keys and
    ** do the insertion.
    */
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
1259
1260
1261
1262
1263
1264
1265
1266



1267
1268
1269
1270
1271
1272
1273
1048
1049
1050
1051
1052
1053
1054

1055
1056
1057
1058
1059
1060
1061
1062
1063
1064







-
+
+
+







      ** constraints or (b) there are no triggers and this table is not a
      ** parent table in a foreign key constraint. It is safe to set the
      ** flag in the second case as if any REPLACE constraint is hit, an
      ** OP_Delete or OP_IdxDelete instruction will be executed on each 
      ** cursor that is disturbed. And these instructions both clear the
      ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
      ** functionality.  */
      bUseSeek = (isReplace==0 || !sqlite3VdbeHasSubProgram(v));
      bUseSeek = (isReplace==0 || (pTrigger==0 &&
          ((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0)
      ));
      sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
          regIns, aRegIdx, 0, appendFlag, bUseSeek
      );
    }
  }

  /* Update the count of rows that are inserted
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
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







-
-
-
-
-
-
-
-
-



-

-














-
+







  sqlite3VdbeResolveLabel(v, endOfLoop);
  if( useTempTable ){
    sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
    sqlite3VdbeJumpHere(v, addrInsTop);
    sqlite3VdbeAddOp1(v, OP_Close, srcTab);
  }else if( pSelect ){
    sqlite3VdbeGoto(v, addrCont);
#ifdef SQLITE_DEBUG
    /* If we are jumping back to an OP_Yield that is preceded by an
    ** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the
    ** OP_ReleaseReg will be included in the loop. */
    if( sqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){
      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);
    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);
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1187
1188
1189
1190
1191
1192
1193
































































1194
1195
1196
1197
1198
1199
1200







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







  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
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1222
1223
1224
1225
1226
1227
1228








1229
1230
1231
1232
1233
1234
1235







-
-
-
-
-
-
-
-







**
** The code generated by this routine will store new index entries into
** registers identified by aRegIdx[].  No index entry is created for
** indices where aRegIdx[i]==0.  The order of indices in aRegIdx[] is
** the same as the order of indices on the linked list of indices
** at pTab->pIndex.
**
** (2019-05-07) The generated code also creates a new record for the
** main table, if pTab is a rowid table, and stores that record in the
** register identified by aRegIdx[nIdx] - in other words in the first
** entry of aRegIdx[] past the last index.  It is important that the
** record be generated during constraint checks to avoid affinity changes
** to the register content that occur after constraint checks but before
** the new record is inserted.
**
** The caller must have already opened writeable cursors on the main
** table and all applicable indices (that is to say, all indices for which
** aRegIdx[] is not zero).  iDataCur is the cursor for the main table when
** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
** index when operating on a WITHOUT ROWID table.  iIdxCur is the cursor
** for the first index in the pTab->pIndex list.  Cursors for other indices
** are at iIdxCur+N for the N-th element of the pTab->pIndex list.
1579
1580
1581
1582
1583
1584
1585
1586

1587
1588
1589
1590
1591

1592
1593
1594
1595


1596
1597
1598


1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612

1613
1614
1615
1616
1617
1618
1619
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







-
+





+


-
-
+
+

-
-
+
+


-
-
-
-
-
-
-
-



-
+







  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 */
  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 addr1;           /* Address of jump instruction */
  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 */
  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 upsertIpkReturn = 0; /* Address of Goto at end of IPK uniqueness check */
  int upsertIpkDelay = 0;  /* Address of Goto to bypass initial IPK check */
  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 */
  IndexIterator sIdxIter;  /* Index iterator */

  isUpdate = regOldData!=0;
  db = pParse->db;
  v = pParse->pVdbe;
  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;
  
  /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for
  ** normal rowid tables.  nPkField is the number of key fields in the 
  ** pPk index or 1 for a rowid table.  In other words, nPkField is the
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640

1641
1642
1643
1644
1645
1646
1647
1648



1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663












1664
1665
1666
1667
1668
1669
1670

1671
1672
1673

1674
1675
1676
1677
1678


1679
1680
1681
1682
1683
1684







1685
1686
1687
1688


1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710


























1711
1712
1713
1714
1715
1716
1717
1718

1719
1720
1721
1722
1723
1724
1725
1726
1727
1728

1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765
1766
1767



1768
1769
1770
1771
1772
1773
1774
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







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










-








-
-
-
-


-
-
-
+
-
-



-
-
-
+
+
+








  /* Record that this module has started */
  VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
                     iDataCur, iIdxCur, regNewData, regOldData, pkChng));

  /* Test all NOT NULL constraints.
  */
  if( pTab->tabFlags & TF_HasNotNull ){
    int b2ndPass = 0;         /* True if currently running 2nd pass */
    int nSeenReplace = 0;     /* Number of ON CONFLICT REPLACE operations */
    int nGenerated = 0;       /* Number of generated columns with NOT NULL */
    while(1){  /* Make 2 passes over columns. Exit loop via "break" */
      for(i=0; i<nCol; i++){
  for(i=0; i<nCol; i++){
        int iReg;                        /* Register holding column value */
        Column *pCol = &pTab->aCol[i];   /* The column to check for NOT NULL */
        int isGenerated;                 /* non-zero if column is generated */
        onError = pCol->notNull;
        if( onError==OE_None ) continue; /* No NOT NULL on this column */
        if( i==pTab->iPKey ){
          continue;        /* ROWID is never NULL */
        }
    if( i==pTab->iPKey ){
      continue;        /* ROWID is never NULL */
    }
        isGenerated = pCol->colFlags & COLFLAG_GENERATED;
        if( isGenerated && !b2ndPass ){
          nGenerated++;
          continue;        /* Generated columns processed on 2nd pass */
        }
        if( aiChng && aiChng[i]<0 && !isGenerated ){
          /* Do not check NOT NULL on columns that do not change */
          continue;
        }
        if( overrideError!=OE_Default ){
          onError = overrideError;
        }else if( onError==OE_Default ){
          onError = OE_Abort;
        }
        if( onError==OE_Replace ){
    if( aiChng && aiChng[i]<0 ){
      /* Don't bother checking for NOT NULL on columns that do not change */
      continue;
    }
    onError = pTab->aCol[i].notNull;
    if( onError==OE_None ) continue;  /* This column is allowed to be NULL */
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
          if( b2ndPass        /* REPLACE becomes ABORT on the 2nd pass */
           || pCol->pDflt==0  /* REPLACE is ABORT if no DEFAULT value */
          ){
            testcase( pCol->colFlags & COLFLAG_VIRTUAL );
            testcase( pCol->colFlags & COLFLAG_STORED );
            testcase( pCol->colFlags & COLFLAG_GENERATED );
            onError = OE_Abort;
      onError = OE_Abort;
          }else{
            assert( !isGenerated );
          }
    }
        }else if( b2ndPass && !isGenerated ){
          continue;
        }
        assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
            || onError==OE_Ignore || onError==OE_Replace );
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
        testcase( i!=sqlite3TableColumnToStorage(pTab, i) );
        iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1;
        switch( onError ){
          case OE_Replace: {
            int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, iReg);
            VdbeCoverage(v);
    addr1 = 0;
    switch( onError ){
      case OE_Replace: {
        assert( onError==OE_Replace );
        addr1 = sqlite3VdbeMakeLabel(pParse);
        sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
          VdbeCoverage(v);
            assert( (pCol->colFlags & COLFLAG_GENERATED)==0 );
            nSeenReplace++;
            sqlite3ExprCodeCopy(pParse, pCol->pDflt, iReg);
            sqlite3VdbeJumpHere(v, addr1);
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
        sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
            break;
          }
          case OE_Abort:
            sqlite3MayAbort(pParse);
            /* no break */ deliberate_fall_through
          case OE_Rollback:
          case OE_Fail: {
            char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
                                        pCol->zName);
            sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL,
                              onError, iReg);
            sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
            sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
            VdbeCoverage(v);
            break;
          }
          default: {
            assert( onError==OE_Ignore );
            sqlite3VdbeAddOp2(v, OP_IsNull, iReg, ignoreDest);
            VdbeCoverage(v);
            break;
          }
          VdbeCoverage(v);
        onError = OE_Abort;
        /* Fall through into the OE_Abort case to generate code that runs
        ** if both the input and the default value are NULL */
      }
      case OE_Abort:
        sqlite3MayAbort(pParse);
        /* Fall through */
      case OE_Rollback:
      case OE_Fail: {
        char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
                                    pTab->aCol[i].zName);
        sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
                          regNewData+1+i);
        sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
        sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
        VdbeCoverage(v);
        if( addr1 ) sqlite3VdbeResolveLabel(v, addr1);
        break;
      }
      default: {
        assert( onError==OE_Ignore );
        sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
        VdbeCoverage(v);
        break;
      }
        } /* end switch(onError) */
      } /* end loop i over columns */
      if( nGenerated==0 && nSeenReplace==0 ){
        /* If there are no generated columns with NOT NULL constraints
        ** and no NOT NULL ON CONFLICT REPLACE constraints, then a single
        ** pass is sufficient */
        break;
      }
    }
      if( b2ndPass ) break;  /* Never need more than 2 passes */
      b2ndPass = 1;
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
      if( nSeenReplace>0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){
        /* If any NOT NULL ON CONFLICT REPLACE constraints fired on the
        ** first pass, recomputed values for all generated columns, as
        ** those values might depend on columns affected by the REPLACE.
        */
        sqlite3ComputeGeneratedColumns(pParse, regNewData+1, pTab);
      }
  }
#endif
    } /* end of 2-pass loop */
  } /* end if( has-not-null-constraints ) */

  /* Test all CHECK constraints
  */
#ifndef SQLITE_OMIT_CHECK
  if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
    ExprList *pCheck = pTab->pCheck;
    pParse->iSelfTab = -(regNewData+1);
    onError = overrideError!=OE_Default ? overrideError : OE_Abort;
    for(i=0; i<pCheck->nExpr; i++){
      int allOk;
      Expr *pCopy;
      Expr *pExpr = pCheck->a[i].pExpr;
      if( aiChng
       && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
      ){
        /* The check constraints do not reference any of the columns being
        ** updated so there is no point it verifying the check constraint */
        continue;
      }
      if( bAffinityDone==0 ){
        sqlite3TableAffinity(v, pTab, regNewData+1);
        bAffinityDone = 1;
      }
      allOk = sqlite3VdbeMakeLabel(pParse);
      sqlite3VdbeVerifyAbortable(v, onError);
      pCopy = sqlite3ExprDup(db, pExpr, 0);
      if( !db->mallocFailed ){
        sqlite3ExprIfTrue(pParse, pCopy, allOk, SQLITE_JUMPIFNULL);
      sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
      }
      sqlite3ExprDelete(db, pCopy);
      if( onError==OE_Ignore ){
        sqlite3VdbeGoto(v, ignoreDest);
      }else{
        char *zName = pCheck->a[i].zEName;
        assert( zName!=0 || pParse->db->mallocFailed );
        if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */
        char *zName = pCheck->a[i].zName;
        if( zName==0 ) zName = pTab->zName;
        if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
        sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
                              onError, zName, P4_TRANSIENT,
                              P5_ConstraintCheck);
      }
      sqlite3VdbeResolveLabel(v, allOk);
    }
    pParse->iSelfTab = 0;
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
1451
1452
1453
1454
1455
1456
1457

1458



1459
1460







1461
1462
1463
1464
1465





1466










































1467





1468


































1469
1470


1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488

1489


1490




1491
1492
1493







1494
1495
1496
1497
1498
1499
1500
1501
1502

1503
1504
1505
1506
1507
1508
1509
1510







-
+
-
-
-


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


















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









-
+







  **        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;
      /* 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{
        /* A single ON CONFLICT DO UPDATE.  Make all resolutions OE_Update */
        overrideError = OE_Update;
      }
    }else if( pTab->pIndex!=0 ){
    }else if( (pUpIdx = pUpsert->pUpsertIdx)!=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 );
    }
  }

      /* If the constraint-target uniqueness check must be run 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
  ** recheck all of the uniqueness constraints after they have all run.
      ** Jump to that uniqueness check now */
  ** But on the recheck, the resolution is OE_Abort instead of OE_Replace.
  **
  ** If replace triggers are a possibility, then
  **
  **   (1) Allocate register regTrigCnt and initialize it to zero.
  **       That register will count the number of replace triggers that
  **       fire.  Constraint recheck only occurs if the number is positive.
  **   (2) Initialize pTrigger to the list of all DELETE triggers on pTab.
  **   (3) Initialize addrRecheck and lblRecheckOk
  **
  ** The uniqueness rechecking code will create a series of tests to run
  ** in a second pass.  The addrRecheck and lblRecheckOk variables are
  ** used to link together these tests which are separated from each other
  ** in the generate bytecode.
  */
  if( (db->flags & (SQLITE_RecTriggers|SQLITE_ForeignKeys))==0 ){
    /* There are not DELETE triggers nor FK constraints.  No constraint
    ** rechecks are needed. */
    pTrigger = 0;
    regTrigCnt = 0;
  }else{
    if( db->flags&SQLITE_RecTriggers ){
      pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
      regTrigCnt = pTrigger!=0 || sqlite3FkRequired(pParse, pTab, 0, 0);
    }else{
      pTrigger = 0;
      regTrigCnt = sqlite3FkRequired(pParse, pTab, 0, 0);
    }
    if( regTrigCnt ){
      /* Replace triggers might exist.  Allocate the counter and
      ** initialize it to zero. */
      regTrigCnt = ++pParse->nMem;
      sqlite3VdbeAddOp2(v, OP_Integer, 0, regTrigCnt);
      VdbeComment((v, "trigger count"));
      upsertJump = sqlite3VdbeAddOp0(v, OP_Goto);
      VdbeComment((v, "UPSERT constraint goes first"));
      lblRecheckOk = sqlite3VdbeMakeLabel(pParse);
      addrRecheck = lblRecheckOk;
    }
  }

  /* If rowid is changing, make sure the new rowid does not previously
  ** exist in the table.
  */
  if( pkChng && pPk==0 ){
    int addrRowidOk = sqlite3VdbeMakeLabel(pParse);

    /* Figure out what action to take in case of a rowid collision */
    onError = pTab->keyConf;
    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 ){
    if( pUpsert && pUpsert->pUpsertIdx==0 ){
      pUpsertClause = sqlite3UpsertOfIndex(pUpsert,0);
      if( pUpsertClause!=0 ){
      if( pUpsert->pUpsertSet==0 ){
        if( pUpsertClause->isDoUpdate==0 ){
          onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
        }else{
          onError = OE_Update;  /* DO UPDATE */
        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 */
     && 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 ){
1967
1968
1969
1970
1971
1972
1973
1974

1975
1976
1977
1978
1979
1980
1981
1522
1523
1524
1525
1526
1527
1528

1529
1530
1531
1532
1533
1534
1535
1536







-
+







    sqlite3VdbeVerifyAbortable(v, onError);
    sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
    VdbeCoverage(v);

    switch( onError ){
      default: {
        onError = OE_Abort;
        /* no break */ deliberate_fall_through
        /* Fall thru into the next case */
      }
      case OE_Rollback:
      case OE_Abort:
      case OE_Fail: {
        testcase( onError==OE_Rollback );
        testcase( onError==OE_Abort );
        testcase( onError==OE_Fail );
2001
2002
2003
2004
2005
2006
2007
2008





2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
1556
1557
1558
1559
1560
1561
1562

1563
1564
1565
1566
1567
1568
1569
1570


1571
1572
1573
1574
1575
1576
1577







-
+
+
+
+
+



-
-







        ** but being more selective here allows statements like:
        **
        **   REPLACE INTO t(rowid) VALUES($newrowid)
        **
        ** to run without a statement journal if there are no indexes on the
        ** table.
        */
        if( regTrigCnt ){
        Trigger *pTrigger = 0;
        if( db->flags&SQLITE_RecTriggers ){
          pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
        }
        if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
          sqlite3MultiWrite(pParse);
          sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
                                   regNewData, 1, 0, OE_Replace, 1, -1);
          sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */
          nReplaceTrig++;
        }else{
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
          assert( HasRowid(pTab) );
          /* This OP_Delete opcode fires the pre-update-hook only. It does
          ** not modify the b-tree. It is more efficient to let the coming
          ** OP_Insert replace the existing entry than it is to delete the
          ** existing entry and then insert a new one. */
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
1585
1586
1587
1588
1589
1590
1591

1592
1593
1594
1595
1596
1597
1598
1599
1600
1601



1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614


1615


1616
1617
1618
1619

1620
1621





1622
1623
1624
1625
1626
1627



1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
1641







-
+









-
-
-
+












-
-
+
-
-




-


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



-
+







        }
        seenReplace = 1;
        break;
      }
#ifndef SQLITE_OMIT_UPSERT
      case OE_Update: {
        sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur);
        /* no break */ deliberate_fall_through
        /* Fall through */
      }
#endif
      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 ){
    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;
  for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){
      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);
      }
    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 ){
      addrUniqueOk = sqlite3VdbeMakeLabel(pParse);
    }
    if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
      sqlite3TableAffinity(v, pTab, regNewData+1);
      bAffinityDone = 1;
    }
    VdbeNoopComment((v, "prep index %s", pIdx->zName));
    VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
    iThisCur = iIdxCur+ix;


    /* Skip partial indices for which the WHERE clause is not true */
    if( pIdx->pPartIdxWhere ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
      pParse->iSelfTab = -(regNewData+1);
2100
2101
2102
2103
2104
2105
2106

2107
2108


2109
2110
2111

2112
2113
2114
2115




2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
1652
1653
1654
1655
1656
1657
1658
1659


1660
1661



1662




1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675

1676
1677
1678
1679
1680
1681
1682







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









-







      int iField = pIdx->aiColumn[i];
      int x;
      if( iField==XN_EXPR ){
        pParse->iSelfTab = -(regNewData+1);
        sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
        pParse->iSelfTab = 0;
        VdbeComment((v, "%s column %d", pIdx->zName, i));
      }else{
      }else if( iField==XN_ROWID || iField==pTab->iPKey ){
        x = regNewData;
        if( iField==XN_ROWID || iField==pTab->iPKey ){
          x = regNewData;
        sqlite3VdbeAddOp2(v, OP_IntCopy, x, regIdx+i);
        VdbeComment((v, "rowid"));
      }else{
        }else{
        testcase( sqlite3TableColumnToStorage(pTab, iField)!=iField );
        x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1;
        sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
        VdbeComment((v, "%s", pTab->aCol[iField].zName));
          x = iField + regNewData + 1;
        }
        sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i);
        VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
      }
    }
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
    VdbeComment((v, "for %s", pIdx->zName));
#ifdef SQLITE_ENABLE_NULL_TRIM
    if( pIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
      sqlite3SetMakeRecordP5(v, pIdx->pTable);
    }
#endif
    sqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0);

    /* In an UPDATE operation, if this index is the PRIMARY KEY index 
    ** of a WITHOUT ROWID table and there has been no change the
    ** primary key, then no collision is possible.  The collision detection
    ** logic below can all be skipped. */
    if( isUpdate && pPk==pIdx && pkChng==0 ){
      sqlite3VdbeResolveLabel(v, addrUniqueOk);
2142
2143
2144
2145
2146
2147
2148
2149
2150


2151
2152
2153
2154
2155
2156
2157
1692
1693
1694
1695
1696
1697
1698


1699
1700
1701
1702
1703
1704
1705
1706
1707







-
-
+
+







    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 ){
    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:
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185


2186
2187
2188

2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206

2207
2208
2209
2210
2211
2212
2213
1726
1727
1728
1729
1730
1731
1732



1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754

1755
1756
1757
1758
1759
1760
1761
1762







-
-
-
+
+


-
+

















-
+







      sqlite3VdbeResolveLabel(v, addrUniqueOk);
      continue;
    }
#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */

    /* 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);
    sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
                         regIdx, pIdx->nKeyCol); VdbeCoverage(v);

    /* Generate code to handle collisions */
    regR = pIdx==pPk ? regIdx : sqlite3GetTempRange(pParse, nPkField);
    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);
          sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
          VdbeCoverage(v);
        }
      }else{
        int x;
        /* Extract the PRIMARY KEY from the end of the index entry and
        ** store it in registers regR..regR+nPk-1 */
        if( pIdx!=pPk ){
          for(i=0; i<pPk->nKeyCol; i++){
            assert( pPk->aiColumn[i]>=0 );
            x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]);
            x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
            sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
            VdbeComment((v, "%s.%s", pTab->zName,
                         pTab->aCol[pPk->aiColumn[i]].zName));
          }
        }
        if( isUpdate ){
          /* If currently processing the PRIMARY KEY of a WITHOUT ROWID 
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
1774
1775
1776
1777
1778
1779
1780

1781
1782
1783
1784
1785
1786
1787







-







            char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
            x = pPk->aiColumn[i];
            assert( x>=0 );
            if( i==(pPk->nKeyCol-1) ){
              addrJump = addrUniqueOk;
              op = OP_Eq;
            }
            x = sqlite3TableColumnToStorage(pTab, x);
            sqlite3VdbeAddOp4(v, op, 
                regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
            );
            sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
            VdbeCoverageIf(v, op==OP_Eq);
            VdbeCoverageIf(v, op==OP_Ne);
          }
2253
2254
2255
2256
2257
2258
2259
2260

2261
2262
2263
2264
2265
2266
2267
2268
2269
2270

2271
2272
2273
2274
2275
2276


2277
2278
2279
2280


2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342

2343
2344
2345
2346
2347
2348




2349

2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
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







-
+








-
-
+

-
-
-
-
-
+
+
-

-
-
+
+




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




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

+









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







        testcase( onError==OE_Fail );
        sqlite3UniqueConstraint(pParse, onError, pIdx);
        break;
      }
#ifndef SQLITE_OMIT_UPSERT
      case OE_Update: {
        sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix);
        /* no break */ deliberate_fall_through
        /* Fall through */
      }
#endif
      case OE_Ignore: {
        testcase( onError==OE_Ignore );
        sqlite3VdbeGoto(v, ignoreDest);
        break;
      }
      default: {
        int nConflictCk;   /* Number of opcodes in conflict check logic */

        Trigger *pTrigger = 0;
        assert( onError==OE_Replace );
        nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
        assert( nConflictCk>0 );
        testcase( nConflictCk>1 );
        if( regTrigCnt ){
          sqlite3MultiWrite(pParse);
        if( db->flags&SQLITE_RecTriggers ){
          pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
          nReplaceTrig++;
        }
        if( pTrigger && isUpdate ){
          sqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur);
        if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
          sqlite3MultiWrite(pParse);
        }
        sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
            regR, nPkField, 0, OE_Replace,
            (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
        if( pTrigger && isUpdate ){
          sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur);
        }
        if( regTrigCnt ){
          int addrBypass;  /* Jump destination to bypass recheck logic */

          sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */
          addrBypass = sqlite3VdbeAddOp0(v, OP_Goto);  /* Bypass recheck */
          VdbeComment((v, "bypass recheck"));

          /* Here we insert code that will be invoked after all constraint
          ** checks have run, if and only if one or more replace triggers
          ** fired. */
          sqlite3VdbeResolveLabel(v, lblRecheckOk);
          lblRecheckOk = sqlite3VdbeMakeLabel(pParse);
          if( pIdx->pPartIdxWhere ){
            /* Bypass the recheck if this partial index is not defined
            ** for the current row */
            sqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk);
            VdbeCoverage(v);
          }
          /* Copy the constraint check code from above, except change
          ** the constraint-ok jump destination to be the address of
          ** the next retest block */
          while( nConflictCk>0 ){
            VdbeOp x;    /* Conflict check opcode to copy */
            /* The sqlite3VdbeAddOp4() call might reallocate the opcode array.
            ** Hence, make a complete copy of the opcode, rather than using
            ** a pointer to the opcode. */
            x = *sqlite3VdbeGetOp(v, addrConflictCk);
            if( x.opcode!=OP_IdxRowid ){
              int p2;      /* New P2 value for copied conflict check opcode */
              const char *zP4;
              if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){
                p2 = lblRecheckOk;
              }else{
                p2 = x.p2;
              }
              zP4 = x.p4type==P4_INT32 ? SQLITE_INT_TO_PTR(x.p4.i) : x.p4.z;
              sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, zP4, x.p4type);
              sqlite3VdbeChangeP5(v, x.p5);
              VdbeCoverageIf(v, p2!=x.p2);
            }
            nConflictCk--;
            addrConflictCk++;
          }
          /* If the retest fails, issue an abort */
          sqlite3UniqueConstraint(pParse, OE_Abort, pIdx);

          sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */
        }
        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeResolveLabel(v, addrUniqueOk);
    if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
    if( pUpsertClause 
    if( pUpIdx==pIdx ){
     && upsertIpkReturn
     && sqlite3UpsertNextIsIPK(pUpsertClause)
    ){
      sqlite3VdbeGoto(v, upsertIpkDelay+1);
      sqlite3VdbeJumpHere(v, upsertIpkReturn);
      upsertIpkReturn = 0;
      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);
  }

  /* Recheck all uniqueness constraints after replace triggers have run */
  testcase( regTrigCnt!=0 && nReplaceTrig==0 );
  assert( regTrigCnt!=0 || nReplaceTrig==0 );
  if( nReplaceTrig ){
    sqlite3VdbeAddOp2(v, OP_IfNot, regTrigCnt, lblRecheckOk);VdbeCoverage(v);
    if( !pPk ){
      if( isUpdate ){
        sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRecheck, regOldData);
        sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
        VdbeCoverage(v);
      }
      sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRecheck, regNewData);
      VdbeCoverage(v);
      sqlite3RowidConstraint(pParse, OE_Abort, pTab);
    }else{
      sqlite3VdbeGoto(v, addrRecheck);
    }
    sqlite3VdbeResolveLabel(v, lblRecheckOk);
  }

  /* Generate the table record */
  if( HasRowid(pTab) ){
    int regRec = aRegIdx[ix];
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec);
    sqlite3SetMakeRecordP5(v, pTab);
    if( !bAffinityDone ){
      sqlite3TableAffinity(v, pTab, 0);
    }
  }

  *pbMayReplace = seenReplace;
  VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}

#ifdef SQLITE_ENABLE_NULL_TRIM
/*
** Change the P5 operand on the last opcode (which should be an OP_MakeRecord)
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
1867
1868
1869
1870
1871
1872
1873


























1874
1875
1876
1877
1878
1879
1880







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







    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 */
){
  Vdbe *v = pParse->pVdbe;
  int r = sqlite3GetTempReg(pParse);
  assert( !HasRowid(pTab) );
  assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) || CORRUPT_DB );
  sqlite3VdbeAddOp2(v, OP_Integer, 0, r);
  sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE);
  sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP);
  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
2457
2458
2459
2460
2461
2462
2463


2464

2465
2466
2467
2468
2469
2470
2471

2472
2473
2474
2475
2476
2477
2478
2479

2480
2481
2482
2483
2484
2485
2486
2487
2488

2489



2490




2491

2492
2493
2494
2495
2496
2497
2498







2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511

2512
2513
2514
2515
2516
2517
2518
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







+
+

+






-
+



-
-
-
-

+









+

+
+
+
-
+
+
+
+

+







+
+
+
+
+
+
+












-
+







  int update_flags,   /* True for UPDATE, False for INSERT */
  int appendBias,     /* True if this is likely to be an append */
  int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
  Vdbe *v;            /* Prepared statements under construction */
  Index *pIdx;        /* An index being inserted or updated */
  u8 pik_flags;       /* flag values passed to the btree insert */
  int regData;        /* Content registers (after the rowid) */
  int regRec;         /* Register holding assembled record for the table */
  int i;              /* Loop counter */
  u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */

  assert( update_flags==0
       || update_flags==OPFLAG_ISUPDATE
       || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
  );

  v = pParse->pVdbe;
  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    /* All REPLACE indexes are at the end of the list */
    assert( pIdx->onError!=OE_Replace
         || pIdx->pNext==0
         || pIdx->pNext->onError==OE_Replace );
    if( aRegIdx[i]==0 ) continue;
    bAffinityDone = 1;
    if( pIdx->pPartIdxWhere ){
      sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
      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( update_flags==0 ){
        int r = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp2(v, OP_Integer, 0, r);
        sqlite3VdbeAddOp4(v, OP_Insert, 
        codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i]);
            iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE
        );
        sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP);
        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;
  regData = regNewData + 1;
  regRec = sqlite3GetTempReg(pParse);
  sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
  sqlite3SetMakeRecordP5(v, pTab);
  if( !bAffinityDone ){
    sqlite3TableAffinity(v, pTab, 0);
  }
  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = OPFLAG_NCHANGE;
    pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
  }
  if( appendBias ){
    pik_flags |= OPFLAG_APPEND;
  }
  if( useSeekResult ){
    pik_flags |= OPFLAG_USESEEKRESULT;
  }
  sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
  sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
  if( !pParse->nested ){
    sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
  }
  sqlite3VdbeChangeP5(v, pik_flags);
}

/*
2557
2558
2559
2560
2561
2562
2563
2564

2565
2566
2567
2568
2569
2570
2571
2005
2006
2007
2008
2009
2010
2011

2012
2013
2014
2015
2016
2017
2018
2019







-
+







  if( IsVirtual(pTab) ){
    /* This routine is a no-op for virtual tables. Leave the output
    ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
    ** can detect if they are used by mistake in the caller. */
    return 0;
  }
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  v = pParse->pVdbe;
  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  if( iBase<0 ) iBase = pParse->nTab;
  iDataCur = iBase++;
  if( piDataCur ) *piDataCur = iDataCur;
  if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){
    sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op);
  }else{
2614
2615
2616
2617
2618
2619
2620
2621

2622
2623
2624
2625
2626
2627
2628
2062
2063
2064
2065
2066
2067
2068

2069
2070
2071
2072
2073
2074
2075
2076







-
+







**    *   The same collating sequence on each column
**    *   The index has the exact same WHERE clause
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
  int i;
  assert( pDest && pSrc );
  assert( pDest->pTable!=pSrc->pTable );
  if( pDest->nKeyCol!=pSrc->nKeyCol || pDest->nColumn!=pSrc->nColumn ){
  if( pDest->nKeyCol!=pSrc->nKeyCol ){
    return 0;   /* Different number of columns */
  }
  if( pDest->onError!=pSrc->onError ){
    return 0;   /* Different conflict resolution strategies */
  }
  for(i=0; i<pSrc->nKeyCol; i++){
    if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
2682
2683
2684
2685
2686
2687
2688
2689

2690
2691
2692
2693
2694
2695
2696
2130
2131
2132
2133
2134
2135
2136

2137
2138
2139
2140
2141
2142
2143
2144







-
+







  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 */
  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 */
2762
2763
2764
2765
2766
2767
2768
2769

2770
2771
2772
2773
2774
2775
2776
2210
2211
2212
2213
2214
2215
2216

2217
2218
2219
2220
2221
2222
2223
2224







-
+







  */
  pItem = pSelect->pSrc->a;
  pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
  if( pSrc==0 ){
    return 0;   /* FROM clause does not contain a real table */
  }
  if( pSrc->tnum==pDest->tnum && pSrc->pSchema==pDest->pSchema ){
    testcase( pSrc!=pDest ); /* Possible due to bad sqlite_schema.rootpage */
    testcase( pSrc!=pDest ); /* Possible due to bad sqlite_master.rootpage */
    return 0;   /* tab1 and tab2 may not be the same table */
  }
  if( HasRowid(pDest)!=HasRowid(pSrc) ){
    return 0;   /* source and destination must both be WITHOUT ROWID or not */
  }
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pSrc) ){
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842

2843
2844
2845
2846
2847
2848
2849
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







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











-
+







    Column *pSrcCol = &pSrc->aCol[i];
#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
    if( (db->mDbFlags & DBFLAG_Vacuum)==0 
     && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN 
    ){
      return 0;    /* Neither table may have __hidden__ columns */
    }
#endif
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
    /* Even if tables t1 and t2 have identical schemas, if they contain
    ** generated columns, then this statement is semantically incorrect:
    **
    **     INSERT INTO t2 SELECT * FROM t1;
    **
    ** The reason is that generated column values are returned by the
    ** the SELECT statement on the right but the INSERT statement on the
    ** left wants them to be omitted.
    **
    ** Nevertheless, this is a useful notational shorthand to tell SQLite
    ** to do a bulk transfer all of the content from t1 over to t2.
    ** 
    ** We could, in theory, disable this (except for internal use by the
    ** VACUUM command where it is actually needed).  But why do that?  It
    ** seems harmless enough, and provides a useful service.
    */
    if( (pDestCol->colFlags & COLFLAG_GENERATED) !=
        (pSrcCol->colFlags & COLFLAG_GENERATED) ){
      return 0;    /* Both columns have the same generated-column type */
    }
    /* But the transfer is only allowed if both the source and destination
    ** tables have the exact same expressions for generated columns.
    ** This requirement could be relaxed for VIRTUAL columns, I suppose.
    */
    if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){
      if( sqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){
        testcase( pDestCol->colFlags & COLFLAG_VIRTUAL );
        testcase( pDestCol->colFlags & COLFLAG_STORED );
        return 0;  /* Different generator expressions */
      }
    }
#endif
    if( pDestCol->affinity!=pSrcCol->affinity ){
      return 0;    /* Affinity must be the same on all columns */
    }
    if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
      return 0;    /* Collating sequence must be the same on all columns */
    }
    if( pDestCol->notNull && !pSrcCol->notNull ){
      return 0;    /* tab2 must be NOT NULL if tab1 is */
    }
    /* Default values for second and subsequent columns need to match. */
    if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){
    if( i>0 ){
      assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
      assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
      if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) 
       || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
                                       pSrcCol->pDflt->u.zToken)!=0)
      ){
        return 0;    /* Default values must be the same for all columns */
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2314
2315
2316
2317
2318
2319
2320

2321
2322
2323
2324
2325
2326
2327







-







  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) */
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947





2948
2949
2950
2951
2952
2953
2954
2955
2956

2957
2958

2959

2960
2961

2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972

2973
2974

2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2349
2350
2351
2352
2353
2354
2355






2356
2357
2358
2359
2360

2361
2362
2363
2364
2365
2366
2367

2368
2369
2370
2371

2372
2373

2374
2375










2376


2377

2378

2379
2380
2381
2382
2383
2384
2385







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







-
+


+
-
+

-
+

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

-







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

    sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
    if( db->mDbFlags & DBFLAG_Vacuum ){
      sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
      insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|
      insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT;
                           OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
    }else{
      insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT;
      insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND;
    }
#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);
    sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid,
    if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){
      sqlite3VdbeChangeP4(v, -1, (char*)pDest, P4_TABLE);
                      (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);
  }
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
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420

2421
2422

2423
2424

2425
2426









2427
2428
2429
2430
2431
2432
2433







+




















-
+

-

+
-
+

-
-
-
-
-
-
-
-
-







    sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
    VdbeComment((v, "%s", pSrcIdx->zName));
    sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
    sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
    sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
    VdbeComment((v, "%s", pDestIdx->zName));
    addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
    sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
    if( db->mDbFlags & DBFLAG_Vacuum ){
      /* This INSERT command is part of a VACUUM operation, which guarantees
      ** that the destination table is empty. If all indexed columns use
      ** collation sequence BINARY, then it can also be assumed that the
      ** index will be populated by inserting keys in strictly sorted 
      ** order. In this case, instead of seeking within the b-tree as part
      ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the
      ** OP_IdxInsert to seek to the point within the b-tree where each key 
      ** should be inserted. This is faster.
      **
      ** If any of the indexed columns use a collation sequence other than
      ** BINARY, this optimization is disabled. This is because the user 
      ** might change the definition of a collation sequence and then run
      ** 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;
        idxInsFlags = OPFLAG_USESEEKRESULT;
        sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
        sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc);
      }
    }
    }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
    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);
      }
    }
    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/loadext.c.

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
457
458
459
460
461
462
463

464


















465
466








467
468
469
470
471
472
473







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


-
-
-
-
-
-
-
-







#ifdef SQLITE_ENABLE_NORMALIZE
  sqlite3_normalized_sql,
#else
  0,
#endif
  /* Version 3.28.0 and later */
  sqlite3_stmt_isexplain,
  sqlite3_value_frombind,
  sqlite3_value_frombind
  /* Version 3.30.0 and later */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3_drop_modules,
#else
  0,
#endif
  /* Version 3.31.0 and later */
  sqlite3_hard_heap_limit64,
  sqlite3_uri_key,
  sqlite3_filename_database,
  sqlite3_filename_journal,
  sqlite3_filename_wal,
  /* Version 3.32.0 and later */
  sqlite3_create_filename,
  sqlite3_free_filename,
  sqlite3_database_file_object,
  /* Version 3.34.0 and later */
  sqlite3_txn_state,
};

/* True if x is the directory separator character
*/
#if SQLITE_OS_WIN
# define DirSep(X)  ((X)=='/'||(X)=='\\')
#else
# define DirSep(X)  ((X)=='/')
#endif

/*
** Attempt to load an SQLite extension library contained in the file
** zFile.  The entry point is zProc.  zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used.  Use
** of the default name is recommended.
**
** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong.
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575







-
+







    int ncFile = sqlite3Strlen30(zFile);
    zAltEntry = sqlite3_malloc64(ncFile+30);
    if( zAltEntry==0 ){
      sqlite3OsDlClose(pVfs, handle);
      return SQLITE_NOMEM_BKPT;
    }
    memcpy(zAltEntry, "sqlite3_", 8);
    for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){}
    for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
    iFile++;
    if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
    for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
      if( sqlite3Isalpha(c) ){
        zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
      }
    }
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
661
662
663
664
665
666
667

668
669
670
671
672
673
674
675







-
+








#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */

/*
** The following object holds the list of automatically loaded
** extensions.
**
** This list is shared across threads.  The SQLITE_MUTEX_STATIC_MAIN
** This list is shared across threads.  The SQLITE_MUTEX_STATIC_MASTER
** mutex must be held while accessing this list.
*/
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
static SQLITE_WSD struct sqlite3AutoExtList {
  u32 nExt;              /* Number of entries in aExt[] */          
  void (**aExt)(void);   /* Pointers to the extension init functions */
} sqlite3Autoext = { 0, 0 };
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743
703
704
705
706
707
708
709

710
711
712
713
714
715
716
717







-
+







  if( rc ){
    return rc;
  }else
#endif
  {
    u32 i;
#if SQLITE_THREADSAFE
    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
    wsdAutoextInit;
    sqlite3_mutex_enter(mutex);
    for(i=0; i<wsdAutoext.nExt; i++){
      if( wsdAutoext.aExt[i]==xInit ) break;
    }
    if( i==wsdAutoext.nExt ){
767
768
769
770
771
772
773
774

775
776
777
778
779
780
781
741
742
743
744
745
746
747

748
749
750
751
752
753
754
755







-
+







** Return 1 if xInit was found on the list and removed.  Return 0 if xInit
** was not on the list.
*/
int sqlite3_cancel_auto_extension(
  void (*xInit)(void)
){
#if SQLITE_THREADSAFE
  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
  int i;
  int n = 0;
  wsdAutoextInit;
  sqlite3_mutex_enter(mutex);
  for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
    if( wsdAutoext.aExt[i]==xInit ){
794
795
796
797
798
799
800
801

802
803
804
805
806
807
808
768
769
770
771
772
773
774

775
776
777
778
779
780
781
782







-
+







*/
void sqlite3_reset_auto_extension(void){
#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize()==SQLITE_OK )
#endif
  {
#if SQLITE_THREADSAFE
    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
    wsdAutoextInit;
    sqlite3_mutex_enter(mutex);
    sqlite3_free(wsdAutoext.aExt);
    wsdAutoext.aExt = 0;
    wsdAutoext.nExt = 0;
    sqlite3_mutex_leave(mutex);
824
825
826
827
828
829
830
831

832
833
834
835
836
837
838
798
799
800
801
802
803
804

805
806
807
808
809
810
811
812







-
+







  if( wsdAutoext.nExt==0 ){
    /* Common case: early out without every having to acquire a mutex */
    return;
  }
  for(i=0; go; i++){
    char *zErrmsg;
#if SQLITE_THREADSAFE
    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
#ifdef SQLITE_OMIT_LOAD_EXTENSION
    const sqlite3_api_routines *pThunk = 0;
#else
    const sqlite3_api_routines *pThunk = &sqlite3Apis;
#endif
    sqlite3_mutex_enter(mutex);

Changes to src/main.c.

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







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






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

-
+

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



-
+







#endif
#ifdef SQLITE_ENABLE_RTREE
# include "rtree.h"
#endif
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
# include "sqliteicu.h"
#endif

/*
** This is an extension initializer that is a no-op and always
** succeeds, except that it fails if the fault-simulation is set
** to 500.
*/
static int sqlite3TestExtInit(sqlite3 *db){
  (void)db;
  return sqlite3FaultSim(500);
}


/*
** Forward declarations of external module initializer functions
** for modules that need them.
*/
#ifdef SQLITE_ENABLE_FTS1
int sqlite3Fts1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_FTS2
int sqlite3Fts2Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_FTS5
int sqlite3Fts5Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_JSON1
int sqlite3Json1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
int sqlite3StmtVtabInit(sqlite3*);
#endif

/*
** An array of pointers to extension initializer functions for
** built-in extensions.
*/
static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
#ifdef SQLITE_ENABLE_FTS1
  sqlite3Fts1Init,
#endif
#ifdef SQLITE_ENABLE_FTS2
  sqlite3Fts2Init,
#endif
#ifdef SQLITE_ENABLE_FTS3
  sqlite3Fts3Init,
#endif
#ifdef SQLITE_ENABLE_FTS5
  sqlite3Fts5Init,
int sqlite3Fts5Init(sqlite3*);
#endif
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
  sqlite3IcuInit,
#endif
#ifdef SQLITE_ENABLE_RTREE
  sqlite3RtreeInit,
#endif
#ifdef SQLITE_ENABLE_DBPAGE_VTAB
  sqlite3DbpageRegister,
#endif
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
  sqlite3DbstatRegister,
#endif
  sqlite3TestExtInit,
#ifdef SQLITE_ENABLE_JSON1
  sqlite3Json1Init,
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
  sqlite3StmtVtabInit,
#endif
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
  sqlite3VdbeBytecodeVtabInit,
#endif
};

#ifndef SQLITE_AMALGAMATION
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
** contains the text of SQLITE_VERSION macro.
** contains the text of SQLITE_VERSION macro. 
*/
const char sqlite3_version[] = SQLITE_VERSION;
#endif

/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
** a pointer to the to the sqlite3_version[] string constant. 
*/
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148







-
+







**    *  Calls to this routine from Y must block until the outer-most
**       call by X completes.
**
**    *  Recursive calls to this routine from thread X return immediately
**       without blocking.
*/
int sqlite3_initialize(void){
  MUTEX_LOGIC( sqlite3_mutex *pMainMtx; )      /* The main static mutex */
  MUTEX_LOGIC( sqlite3_mutex *pMaster; )       /* The main static mutex */
  int rc;                                      /* Result code */
#ifdef SQLITE_EXTRA_INIT
  int bRunExtraInit = 0;                       /* Extra initialization needed */
#endif

#ifdef SQLITE_OMIT_WSD
  rc = sqlite3_wsd_init(4096, 24);
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
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







-
+
-
-
-













-
+




-
-
+
+

















-
+







  assert( SQLITE_PTRSIZE==sizeof(char*) );

  /* If SQLite is already completely initialized, then this call
  ** to sqlite3_initialize() should be a no-op.  But the initialization
  ** must be complete.  So isInit must not be set until the very end
  ** of this routine.
  */
  if( sqlite3GlobalConfig.isInit ){
  if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
    sqlite3MemoryBarrier();
    return SQLITE_OK;
  }

  /* Make sure the mutex subsystem is initialized.  If unable to 
  ** initialize the mutex subsystem, return early with the error.
  ** If the system is so sick that we are unable to allocate a mutex,
  ** there is not much SQLite is going to be able to do.
  **
  ** The mutex subsystem must take care of serializing its own
  ** initialization.
  */
  rc = sqlite3MutexInit();
  if( rc ) return rc;

  /* Initialize the malloc() system and the recursive pInitMutex mutex.
  ** This operation is protected by the STATIC_MAIN mutex.  Note that
  ** This operation is protected by the STATIC_MASTER mutex.  Note that
  ** MutexAlloc() is called for a static mutex prior to initializing the
  ** malloc subsystem - this implies that the allocation of a static
  ** mutex must not require support from the malloc subsystem.
  */
  MUTEX_LOGIC( pMainMtx = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); )
  sqlite3_mutex_enter(pMainMtx);
  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  sqlite3_mutex_enter(pMaster);
  sqlite3GlobalConfig.isMutexInit = 1;
  if( !sqlite3GlobalConfig.isMallocInit ){
    rc = sqlite3MallocInit();
  }
  if( rc==SQLITE_OK ){
    sqlite3GlobalConfig.isMallocInit = 1;
    if( !sqlite3GlobalConfig.pInitMutex ){
      sqlite3GlobalConfig.pInitMutex =
           sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
      if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
        rc = SQLITE_NOMEM_BKPT;
      }
    }
  }
  if( rc==SQLITE_OK ){
    sqlite3GlobalConfig.nRefInitMutex++;
  }
  sqlite3_mutex_leave(pMainMtx);
  sqlite3_mutex_leave(pMaster);

  /* If rc is not SQLITE_OK at this point, then either the malloc
  ** subsystem could not be initialized or the system failed to allocate
  ** the pInitMutex mutex. Return an error in either case.  */
  if( rc!=SQLITE_OK ){
    return rc;
  }
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
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







-












-
+






-
+







    if( rc==SQLITE_OK ){
      rc = sqlite3MemdbInit();
    }
#endif
    if( rc==SQLITE_OK ){
      sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, 
          sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
      sqlite3MemoryBarrier();
      sqlite3GlobalConfig.isInit = 1;
#ifdef SQLITE_EXTRA_INIT
      bRunExtraInit = 1;
#endif
    }
    sqlite3GlobalConfig.inProgress = 0;
  }
  sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex);

  /* Go back under the static mutex and clean up the recursive
  ** mutex to prevent a resource leak.
  */
  sqlite3_mutex_enter(pMainMtx);
  sqlite3_mutex_enter(pMaster);
  sqlite3GlobalConfig.nRefInitMutex--;
  if( sqlite3GlobalConfig.nRefInitMutex<=0 ){
    assert( sqlite3GlobalConfig.nRefInitMutex==0 );
    sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex);
    sqlite3GlobalConfig.pInitMutex = 0;
  }
  sqlite3_mutex_leave(pMainMtx);
  sqlite3_mutex_leave(pMaster);

  /* The following is just a sanity check to make sure SQLite has
  ** been compiled correctly.  It is important to run this code, but
  ** we don't want to run it too often and soak up CPU cycles for no
  ** reason.  So we run it once during initialization.
  */
#ifndef NDEBUG
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
679
680
681
682
683
684
685



686
687
688
689
690
691
692







-
-
-







** space for the lookaside memory is obtained from sqlite3_malloc().
** If pStart is not NULL then it is sz*cnt bytes of memory to use for
** the lookaside memory.
*/
static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
#ifndef SQLITE_OMIT_LOOKASIDE
  void *pStart;
  sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt;
  int nBig;   /* Number of full-size slots */
  int nSm;    /* Number smaller LOOKASIDE_SMALL-byte slots */
  
  if( sqlite3LookasideUsed(db,0)>0 ){
    return SQLITE_BUSY;
  }
  /* Free any existing lookaside buffer for this handle before
  ** allocating a new one so we don't have to have space for 
  ** both at the same time.
771
772
773
774
775
776
777
778

779
780

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

808
809

810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
701
702
703
704
705
706
707

708
709

710
711
712
713















714
715
716
717

718
719
720
721
722
723

724
725
726
727
728











729
730
731

732
733





734
735

736
737
738

739
740
741
742
743
744
745







-
+

-
+



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




-




+

-
+




-
-
-
-
-
-
-
-
-
-
-



-


-
-
-
-
-


-



-







  if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
  if( cnt<0 ) cnt = 0;
  if( sz==0 || cnt==0 ){
    sz = 0;
    pStart = 0;
  }else if( pBuf==0 ){
    sqlite3BeginBenignMalloc();
    pStart = sqlite3Malloc( szAlloc );  /* IMP: R-61949-35727 */
    pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt );  /* IMP: R-61949-35727 */
    sqlite3EndBenignMalloc();
    if( pStart ) szAlloc = sqlite3MallocSize(pStart);
    if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
  }else{
    pStart = pBuf;
  }
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
  if( sz>=LOOKASIDE_SMALL*3 ){
    nBig = szAlloc/(3*LOOKASIDE_SMALL+sz);
    nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL;
  }else if( sz>=LOOKASIDE_SMALL*2 ){
    nBig = szAlloc/(LOOKASIDE_SMALL+sz);
    nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL;
  }else
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
  if( sz>0 ){
    nBig = szAlloc/sz;
    nSm = 0;
  }else{
    nBig = nSm = 0;
  }
  db->lookaside.pStart = pStart;
  db->lookaside.pInit = 0;
  db->lookaside.pFree = 0;
  db->lookaside.sz = (u16)sz;
  db->lookaside.szTrue = (u16)sz;
  if( pStart ){
    int i;
    LookasideSlot *p;
    assert( sz > (int)sizeof(LookasideSlot*) );
    db->lookaside.nSlot = cnt;
    p = (LookasideSlot*)pStart;
    for(i=0; i<nBig; i++){
    for(i=cnt-1; i>=0; i--){
      p->pNext = db->lookaside.pInit;
      db->lookaside.pInit = p;
      p = (LookasideSlot*)&((u8*)p)[sz];
    }
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
    db->lookaside.pSmallInit = 0;
    db->lookaside.pSmallFree = 0;
    db->lookaside.pMiddle = p;
    for(i=0; i<nSm; i++){
      p->pNext = db->lookaside.pSmallInit;
      db->lookaside.pSmallInit = p;
      p = (LookasideSlot*)&((u8*)p)[LOOKASIDE_SMALL];
    }
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
    assert( ((uptr)p)<=szAlloc + (uptr)pStart );
    db->lookaside.pEnd = p;
    db->lookaside.bDisable = 0;
    db->lookaside.bMalloced = pBuf==0 ?1:0;
    db->lookaside.nSlot = nBig+nSm;
  }else{
    db->lookaside.pStart = db;
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
    db->lookaside.pSmallInit = 0;
    db->lookaside.pSmallFree = 0;
    db->lookaside.pMiddle = db;
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
    db->lookaside.pEnd = db;
    db->lookaside.bDisable = 1;
    db->lookaside.sz = 0;
    db->lookaside.bMalloced = 0;
    db->lookaside.nSlot = 0;
  }
  assert( sqlite3LookasideUsed(db,0)==0 );
#endif /* SQLITE_OMIT_LOOKASIDE */
  return SQLITE_OK;
}

/*
** Return the mutex associated with a database connection.
*/
893
894
895
896
897
898
899
900

901
902
903
904
905
906
907
789
790
791
792
793
794
795

796
797
798
799
800
801
802
803







-
+







#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);
  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
    Btree *pBt = db->aDb[i].pBt;
    if( pBt && sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
    if( pBt && sqlite3BtreeIsInTrans(pBt) ){
      Pager *pPager = sqlite3BtreePager(pBt);
      rc = sqlite3PagerFlush(pPager);
      if( rc==SQLITE_BUSY ){
        bSeenBusy = 1;
        rc = SQLITE_OK;
      }
    }
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
832
833
834
835
836
837
838

839
840
841
842
843
844
845
846
847





848
849
850
851
852
853
854







-









-
-
-
-
-







    default: {
      static const struct {
        int op;      /* The opcode */
        u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
      } aFlagOp[] = {
        { SQLITE_DBCONFIG_ENABLE_FKEY,           SQLITE_ForeignKeys    },
        { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },
        { SQLITE_DBCONFIG_ENABLE_VIEW,           SQLITE_EnableView     },
        { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer  },
        { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension  },
        { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,      SQLITE_NoCkptOnClose  },
        { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
        { SQLITE_DBCONFIG_TRIGGER_EQP,           SQLITE_TriggerEQP     },
        { SQLITE_DBCONFIG_RESET_DATABASE,        SQLITE_ResetDatabase  },
        { SQLITE_DBCONFIG_DEFENSIVE,             SQLITE_Defensive      },
        { SQLITE_DBCONFIG_WRITABLE_SCHEMA,       SQLITE_WriteSchema|
                                                 SQLITE_NoSchemaError  },
        { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE,    SQLITE_LegacyAlter    },
        { SQLITE_DBCONFIG_DQS_DDL,               SQLITE_DqsDDL         },
        { SQLITE_DBCONFIG_DQS_DML,               SQLITE_DqsDML         },
        { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT,    SQLITE_LegacyFileFmt  },
        { SQLITE_DBCONFIG_TRUSTED_SCHEMA,        SQLITE_TrustedSchema  },
      };
      unsigned int i;
      rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
      for(i=0; i<ArraySize(aFlagOp); i++){
        if( aFlagOp[i].op==op ){
          int onoff = va_arg(ap, int);
          int *pRes = va_arg(ap, int*);
981
982
983
984
985
986
987









988
989
990



991
992
993

994
995
996
997
998
999
1000
1001
1002
1003
1004
1005










1006


1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032



1033
1034
1035
1036
1037
1038
1039
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







+
+
+
+
+
+
+
+
+



+
+
+


-
+




-







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




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




-
-
+
+
+







      break;
    }
  }
  va_end(ap);
  return rc;
}


/*
** Return true if the buffer z[0..n-1] contains all spaces.
*/
static int allSpaces(const char *z, int n){
  while( n>0 && z[n-1]==' ' ){ n--; }
  return n==0;
}

/*
** This is the default collating function named "BINARY" which is always
** available.
**
** If the padFlag argument is not NULL then space padding at the end
** of strings is ignored.  This implements the RTRIM collation.
*/
static int binCollFunc(
  void *NotUsed,
  void *padFlag,
  int nKey1, const void *pKey1,
  int nKey2, const void *pKey2
){
  int rc, n;
  UNUSED_PARAMETER(NotUsed);
  n = nKey1<nKey2 ? nKey1 : nKey2;
  /* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
  ** strings byte by byte using the memcmp() function from the standard C
  ** library. */
  assert( pKey1 && pKey2 );
  rc = memcmp(pKey1, pKey2, n);
  if( rc==0 ){
    if( padFlag
     && allSpaces(((char*)pKey1)+n, nKey1-n)
     && allSpaces(((char*)pKey2)+n, nKey2-n)
    ){
      /* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
      ** spaces at the end of either string do not change the result. In other
      ** words, strings will compare equal to one another as long as they
      ** differ only in the number of spaces at the end.
      */
    }else{
    rc = nKey1 - nKey2;
      rc = nKey1 - nKey2;
    }
  }
  return rc;
}

/*
** This is the collating function named "RTRIM" which is always
** available.  Ignore trailing spaces.
*/
static int rtrimCollFunc(
  void *pUser,
  int nKey1, const void *pKey1,
  int nKey2, const void *pKey2
){
  const u8 *pK1 = (const u8*)pKey1;
  const u8 *pK2 = (const u8*)pKey2;
  while( nKey1 && pK1[nKey1-1]==' ' ) nKey1--;
  while( nKey2 && pK2[nKey2-1]==' ' ) nKey2--;
  return binCollFunc(pUser, nKey1, pKey1, nKey2, pKey2);
}

/*
** Return true if CollSeq is the default built-in BINARY.
*/
int sqlite3IsBinary(const CollSeq *p){
  assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 );
  return p==0 || p->xCmp==binCollFunc;
  assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0
            || strcmp(p->zName,"BINARY")==0 );
  return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
}

/*
** Another built-in collating sequence: NOCASE. 
**
** This collating sequence is intended to be used for "case independent
** comparison". SQLite's knowledge of upper and lower case equivalents
1198
1199
1200
1201
1202
1203
1204
1205

1206
1207
1208
1209
1210
1211
1212
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109







-
+







    return SQLITE_OK;
  }
  if( !sqlite3SafetyCheckSickOrOk(db) ){
    return SQLITE_MISUSE_BKPT;
  }
  sqlite3_mutex_enter(db->mutex);
  if( db->mTrace & SQLITE_TRACE_CLOSE ){
    db->trace.xV2(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
    db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
  }

  /* Force xDisconnect calls on all virtual tables */
  disconnectAllVtab(db);

  /* If a transaction is open, the disconnectAllVtab() call above
  ** will not have called the xDisconnect() method on any virtual
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
1134
1135
1136
1137
1138
1139
1140






























1141
1142
1143
1144
1145
1146
1147







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







  /* Convert the connection into a zombie and then close it.
  */
  db->magic = SQLITE_MAGIC_ZOMBIE;
  sqlite3LeaveMutexAndCloseZombie(db);
  return SQLITE_OK;
}

/*
** Return the transaction state for a single databse, or the maximum
** transaction state over all attached databases if zSchema is null.
*/
int sqlite3_txn_state(sqlite3 *db, const char *zSchema){
  int iDb, nDb;
  int iTxn = -1;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return -1;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  if( zSchema ){
    nDb = iDb = sqlite3FindDbName(db, zSchema);
    if( iDb<0 ) nDb--;
  }else{
    iDb = 0;
    nDb = db->nDb-1;
  }
  for(; iDb<=nDb; iDb++){
    Btree *pBt = db->aDb[iDb].pBt;
    int x = pBt!=0 ? sqlite3BtreeTxnState(pBt) : SQLITE_TXN_NONE;
    if( x>iTxn ) iTxn = x;
  }
  sqlite3_mutex_leave(db->mutex);
  return iTxn;
}

/*
** Two variations on the public interface for closing a database
** connection. The sqlite3_close() version returns SQLITE_BUSY and
** leaves the connection option if there are unfinalized prepared
** statements or unfinished sqlite3_backups.  The sqlite3_close_v2()
** version forces the connection to become a zombie if there are
** unclosed resources, and arranges for deallocation when the last
1368
1369
1370
1371
1372
1373
1374



1375
1376

1377
1378
1379
1380
1381
1382
1383
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245

1246
1247
1248
1249
1250
1251
1252
1253







+
+
+

-
+







    }
    sqlite3DbFree(db, pColl);
  }
  sqlite3HashClear(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
    Module *pMod = (Module *)sqliteHashData(i);
    if( pMod->xDestroy ){
      pMod->xDestroy(pMod->pAux);
    }
    sqlite3VtabEponymousTableClear(db, pMod);
    sqlite3VtabModuleUnref(db, pMod);
    sqlite3DbFree(db, pMod);
  }
  sqlite3HashClear(&db->aModule);
#endif

  sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */
  sqlite3ValueFree(db->pErr);
  sqlite3CloseExtensions(db);
1427
1428
1429
1430
1431
1432
1433
1434

1435
1436
1437
1438
1439
1440
1441
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310
1311







-
+







  ** corruption reports in some cases.  */
  sqlite3BtreeEnterAll(db);
  schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0;

  for(i=0; i<db->nDb; i++){
    Btree *p = db->aDb[i].pBt;
    if( p ){
      if( sqlite3BtreeTxnState(p)==SQLITE_TXN_WRITE ){
      if( sqlite3BtreeIsInTrans(p) ){
        inTrans = 1;
      }
      sqlite3BtreeRollback(p, tripCode, !schemaChange);
    }
  }
  sqlite3VtabRollback(db);
  sqlite3EndBenignMalloc();
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402







-







      case SQLITE_NOTFOUND:           zName = "SQLITE_NOTFOUND";          break;
      case SQLITE_FULL:               zName = "SQLITE_FULL";              break;
      case SQLITE_CANTOPEN:           zName = "SQLITE_CANTOPEN";          break;
      case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
      case SQLITE_CANTOPEN_ISDIR:     zName = "SQLITE_CANTOPEN_ISDIR";    break;
      case SQLITE_CANTOPEN_FULLPATH:  zName = "SQLITE_CANTOPEN_FULLPATH"; break;
      case SQLITE_CANTOPEN_CONVPATH:  zName = "SQLITE_CANTOPEN_CONVPATH"; break;
      case SQLITE_CANTOPEN_SYMLINK:   zName = "SQLITE_CANTOPEN_SYMLINK";  break;
      case SQLITE_PROTOCOL:           zName = "SQLITE_PROTOCOL";          break;
      case SQLITE_EMPTY:              zName = "SQLITE_EMPTY";             break;
      case SQLITE_SCHEMA:             zName = "SQLITE_SCHEMA";            break;
      case SQLITE_TOOBIG:             zName = "SQLITE_TOOBIG";            break;
      case SQLITE_CONSTRAINT:         zName = "SQLITE_CONSTRAINT";        break;
      case SQLITE_CONSTRAINT_UNIQUE:  zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
      case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;
1641
1642
1643
1644
1645
1646
1647
1648


1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661













1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680

1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698

1699
1700








1701


1702
1703
1704
1705
1706
1707
1708
1510
1511
1512
1513
1514
1515
1516

1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581

1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592

1593
1594
1595
1596
1597
1598
1599
1600
1601







-
+
+













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



















+

















-
+


+
+
+
+
+
+
+
+
-
+
+







** argument.
**
** Return non-zero to retry the lock.  Return zero to stop trying
** and cause SQLite to return SQLITE_BUSY.
*/
static int sqliteDefaultBusyCallback(
  void *ptr,               /* Database connection */
  int count                /* Number of times table has been busy */
  int count,               /* Number of times table has been busy */
  sqlite3_file *pFile      /* The file on which the lock occurred */
){
#if SQLITE_OS_WIN || HAVE_USLEEP
  /* This case is for systems that have support for sleeping for fractions of
  ** a second.  Examples:  All windows systems, unix systems with usleep() */
  static const u8 delays[] =
     { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50, 100 };
  static const u8 totals[] =
     { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228 };
# define NDELAY ArraySize(delays)
  sqlite3 *db = (sqlite3 *)ptr;
  int tmout = db->busyTimeout;
  int delay, prior;

#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
  if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
    if( count ){
      tmout = 0;
      sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
      return 0;
    }else{
      return 1;
    }
  }
#else
  UNUSED_PARAMETER(pFile);
#endif
  assert( count>=0 );
  if( count < NDELAY ){
    delay = delays[count];
    prior = totals[count];
  }else{
    delay = delays[NDELAY-1];
    prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
  }
  if( prior + delay > tmout ){
    delay = tmout - prior;
    if( delay<=0 ) return 0;
  }
  sqlite3OsSleep(db->pVfs, delay*1000);
  return 1;
#else
  /* This case for unix systems that lack usleep() support.  Sleeping
  ** must be done in increments of whole seconds */
  sqlite3 *db = (sqlite3 *)ptr;
  int tmout = ((sqlite3 *)ptr)->busyTimeout;
  UNUSED_PARAMETER(pFile);
  if( (count+1)*1000 > tmout ){
    return 0;
  }
  sqlite3OsSleep(db->pVfs, 1000000);
  return 1;
#endif
}

/*
** Invoke the given busy handler.
**
** This routine is called when an operation failed to acquire a
** lock on VFS file pFile.
**
** If this routine returns non-zero, the lock is retried.  If it
** returns 0, the operation aborts with an SQLITE_BUSY error.
*/
int sqlite3InvokeBusyHandler(BusyHandler *p){
int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
  int rc;
  if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
  if( p->bExtraFileArg ){
    /* Add an extra parameter with the pFile pointer to the end of the
    ** callback argument list */
    int (*xTra)(void*,int,sqlite3_file*);
    xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
    rc = xTra(p->pBusyArg, p->nBusy, pFile);
  }else{
    /* Legacy style busy handler callback */
  rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
    rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
  }
  if( rc==0 ){
    p->nBusy = -1;
  }else{
    p->nBusy++;
  }
  return rc; 
}
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626







+







#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  db->busyHandler.xBusyHandler = xBusy;
  db->busyHandler.pBusyArg = pArg;
  db->busyHandler.nBusy = 0;
  db->busyHandler.bExtraFileArg = 0;
  db->busyTimeout = 0;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
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
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686

1687
1688
1689
1690
1691
1692
1693
1694







+
















-
+







#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  if( ms>0 ){
    sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
                             (void*)db);
    db->busyTimeout = ms;
    db->busyHandler.bExtraFileArg = 1;
  }else{
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*
** Cause any pending operation to stop at its earliest opportunity.
*/
void sqlite3_interrupt(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){
    (void)SQLITE_MISUSE_BKPT;
    return;
  }
#endif
  AtomicStore(&db->u1.isInterrupted, 1);
  db->u1.isInterrupted = 1;
}


/*
** This function is exactly the same as sqlite3_create_function(), except
** that it is designed to be called by internal code. The difference is
** that if a malloc() fails in sqlite3_create_function(), an error code
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
1720
1721
1722
1723
1724
1725
1726


1727

1728






1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741

1742

1743
1744

1745


1746
1747
1748
1749
1750
1751
1752
1753







-
-
+
-

-
-
-
-
-
-













-
+
-


-
+
-
-
+







   || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG)
   || (255<(nName = sqlite3Strlen30( zFunctionName)))
  ){
    return SQLITE_MISUSE_BKPT;
  }

  assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
  assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
  extraFlags = enc &  (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
  extraFlags = enc &  SQLITE_DETERMINISTIC;
                       SQLITE_SUBTYPE|SQLITE_INNOCUOUS);
  enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);

  /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE.  But
  ** the meaning is inverted.  So flip the bit. */
  assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS );
  extraFlags ^= SQLITE_FUNC_UNSAFE;

  
#ifndef SQLITE_OMIT_UTF16
  /* If SQLITE_UTF16 is specified as the encoding type, transform this
  ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
  ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
  **
  ** If SQLITE_ANY is specified, add three versions of the function
  ** to the hash table.
  */
  if( enc==SQLITE_UTF16 ){
    enc = SQLITE_UTF16NATIVE;
  }else if( enc==SQLITE_ANY ){
    int rc;
    rc = sqlite3CreateFunc(db, zFunctionName, nArg,
    rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
         (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE,
         pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
    if( rc==SQLITE_OK ){
      rc = sqlite3CreateFunc(db, zFunctionName, nArg,
      rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
           (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE,
           pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
          pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
    }
    if( rc!=SQLITE_OK ){
      return rc;
    }
    enc = SQLITE_UTF16BE;
  }
#else
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1783
1784
1785
1786
1787
1788
1789

1790
1791
1792
1793
1794
1795
1796







-








  if( pDestructor ){
    pDestructor->nRef++;
  }
  p->u.pDestructor = pDestructor;
  p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
  testcase( p->funcFlags & SQLITE_DETERMINISTIC );
  testcase( p->funcFlags & SQLITE_DIRECTONLY );
  p->xSFunc = xSFunc ? xSFunc : xStep;
  p->xFinalize = xFinal;
  p->xValue = xValue;
  p->xInverse = xInverse;
  p->pUserData = pUserData;
  p->nArg = (u16)nArg;
  return SQLITE_OK;
2117
2118
2119
2120
2121
2122
2123
2124

2125
2126
2127
2128
2129
2130
2131
2001
2002
2003
2004
2005
2006
2007

2008
2009
2010
2011
2012
2013
2014
2015







-
+







    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pOld = db->pTraceArg;
  db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
  db->trace.xLegacy = xTrace;
  db->xTrace = (int(*)(u32,void*,void*,void*))xTrace;
  db->pTraceArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pOld;
}
#endif /* SQLITE_OMIT_DEPRECATED */

/* Register a trace callback using the version-2 interface.
2141
2142
2143
2144
2145
2146
2147
2148

2149
2150
2151
2152
2153
2154
2155
2025
2026
2027
2028
2029
2030
2031

2032
2033
2034
2035
2036
2037
2038
2039







-
+







    return SQLITE_MISUSE_BKPT;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  if( mTrace==0 ) xTrace = 0;
  if( xTrace==0 ) mTrace = 0;
  db->mTrace = mTrace;
  db->trace.xV2 = xTrace;
  db->xTrace = xTrace;
  db->pTraceArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_DEPRECATED
/*
2370
2371
2372
2373
2374
2375
2376
2377

2378
2379
2380
2381
2382
2383
2384
2254
2255
2256
2257
2258
2259
2260

2261
2262
2263
2264
2265
2266
2267
2268







-
+







  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 */
  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;
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416

2417
2418
2419
2420
2421
2422
2423
2277
2278
2279
2280
2281
2282
2283


2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297

2298
2299
2300
2301
2302
2303
2304
2305







-
-














-
+







    ** 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);
    sqlite3Error(db, rc);
  }
  rc = sqlite3ApiExit(db, rc);

  /* If there are no active statements, clear the interrupt flag at this
  ** point.  */
  if( db->nVdbeActive==0 ){
    AtomicStore(&db->u1.isInterrupted, 0);
    db->u1.isInterrupted = 0;
  }

  sqlite3_mutex_leave(db->mutex);
  return rc;
#endif
}

2443
2444
2445
2446
2447
2448
2449
2450

2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469

2470
2471
2472
2473
2474
2475
2476
2325
2326
2327
2328
2329
2330
2331

2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346


2347
2348

2349
2350
2351
2352
2353
2354
2355
2356







-
+














-
-


-
+







** 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
** 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 );
  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 ){
    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;
      }
2821
2822
2823
2824
2825
2826
2827
2828

2829
2830
2831
2832


2833
2834
2835
2836
2837
2838
2839
2701
2702
2703
2704
2705
2706
2707

2708




2709
2710
2711
2712
2713
2714
2715
2716
2717







-
+
-
-
-
-
+
+







** itself. When this function is called the *pFlags variable should contain
** the default flags to open the database handle with. The value stored in
** *pFlags may be updated before returning if the URI filename contains 
** "cache=xxx" or "mode=xxx" query parameters.
**
** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to
** the VFS that should be used to open the database file. *pzFile is set to
** point to a buffer containing the name of the file to open.  The value
** point to a buffer containing the name of the file to open. It is the 
** stored in *pzFile is a database name acceptable to sqlite3_uri_parameter()
** and is in the same format as names created using sqlite3_create_filename().
** The caller must invoke sqlite3_free_filename() (not sqlite3_free()!) on
** the value returned in *pzFile to avoid a memory leak.
** responsibility of the caller to eventually call sqlite3_free() to release
** this buffer.
**
** If an error occurs, then an SQLite error code is returned and *pzErrMsg
** may be set to point to a buffer containing an English language error 
** message. It is the responsibility of the caller to eventually release
** this buffer by calling sqlite3_free().
*/
int sqlite3ParseUri(
2857
2858
2859
2860
2861
2862
2863
2864

2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2735
2736
2737
2738
2739
2740
2741

2742
2743
2744
2745
2746
2747
2748
2749
2750
2751



2752
2753
2754
2755
2756
2757
2758







-
+









-
-
-







            || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
   && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
  ){
    char *zOpt;
    int eState;                   /* Parser state when parsing URI */
    int iIn;                      /* Input character index */
    int iOut = 0;                 /* Output character index */
    u64 nByte = nUri+8;           /* Bytes of space to allocate */
    u64 nByte = nUri+2;           /* Bytes of space to allocate */

    /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen 
    ** method that there may be extra parameters following the file-name.  */
    flags |= SQLITE_OPEN_URI;

    for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
    zFile = sqlite3_malloc64(nByte);
    if( !zFile ) return SQLITE_NOMEM_BKPT;

    memset(zFile, 0, 4);  /* 4-byte of 0x00 is the start of DB name marker */
    zFile += 4;

    iIn = 5;
#ifdef SQLITE_ALLOW_URI_AUTHORITY
    if( strncmp(zUri+5, "///", 3)==0 ){
      iIn = 7;
      /* The following condition causes URIs with five leading / characters
      ** like file://///host/path to be converted into UNCs like //host/path.
      ** The correct URI for that UNC has only two or four leading / characters
2959
2960
2961
2962
2963
2964
2965
2966


2967
2968
2969
2970
2971
2972
2973
2834
2835
2836
2837
2838
2839
2840

2841
2842
2843
2844
2845
2846
2847
2848
2849







-
+
+







      }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){
        c = 0;
        eState = 1;
      }
      zFile[iOut++] = c;
    }
    if( eState==1 ) zFile[iOut++] = '\0';
    memset(zFile+iOut, 0, 4); /* end-of-options + empty journal filenames */
    zFile[iOut++] = '\0';
    zFile[iOut++] = '\0';

    /* Check if there were any options specified that should be interpreted 
    ** here. Options that are interpreted here include "vfs" and those that
    ** correspond to flags that may be passed to the sqlite3_open_v2()
    ** method. */
    zOpt = &zFile[sqlite3Strlen30(zFile)+1];
    while( zOpt[0] ){
3039
3040
3041
3042
3043
3044
3045
3046

3047
3048
3049
3050
3051
3052
3053


3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064

3065
3066
3067
3068
3069
3070
3071

3072
3073
3074



3075


3076
3077
3078
3079
3080
3081











3082
3083
3084
3085
3086














3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
2915
2916
2917
2918
2919
2920
2921

2922
2923


2924
2925
2926

2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938

2939
2940
2941
2942
2943
2944
2945
2946
2947
2948


2949
2950
2951
2952
2953
2954






2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965





2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997

2998
2999
3000
3001
3002
3003
3004







-
+

-
-



-
+
+










-
+







+

-
-
+
+
+

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


















-







        }
      }

      zOpt = &zVal[nVal+1];
    }

  }else{
    zFile = sqlite3_malloc64(nUri+8);
    zFile = sqlite3_malloc64(nUri+2);
    if( !zFile ) return SQLITE_NOMEM_BKPT;
    memset(zFile, 0, 4);
    zFile += 4;
    if( nUri ){
      memcpy(zFile, zUri, nUri);
    }
    memset(zFile+nUri, 0, 4);
    zFile[nUri] = '\0';
    zFile[nUri+1] = '\0';
    flags &= ~SQLITE_OPEN_URI;
  }

  *ppVfs = sqlite3_vfs_find(zVfs);
  if( *ppVfs==0 ){
    *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs);
    rc = SQLITE_ERROR;
  }
 parse_uri_out:
  if( rc!=SQLITE_OK ){
    sqlite3_free_filename(zFile);
    sqlite3_free(zFile);
    zFile = 0;
  }
  *pFlags = flags;
  *pzFile = zFile;
  return rc;
}

#if defined(SQLITE_HAS_CODEC)
/*
** This routine does the core work of extracting URI parameters from a
** database filename for the sqlite3_uri_parameter() interface.
** Process URI filename query parameters relevant to the SQLite Encryption
** Extension.  Return true if any of the relevant query parameters are
** seen and return false if not.
*/
int sqlite3CodecQueryParameters(
  sqlite3 *db,           /* Database connection */
static const char *uriParameter(const char *zFilename, const char *zParam){
  zFilename += sqlite3Strlen30(zFilename) + 1;
  while( zFilename[0] ){
    int x = strcmp(zFilename, zParam);
    zFilename += sqlite3Strlen30(zFilename) + 1;
    if( x==0 ) return zFilename;
  const char *zDb,       /* Which schema is being created/attached */
  const char *zUri       /* URI filename */
){
  const char *zKey;
  if( (zKey = sqlite3_uri_parameter(zUri, "hexkey"))!=0 && zKey[0] ){
    u8 iByte;
    int i;
    char zDecoded[40];
    for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
      iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
      if( (i&1)!=0 ) zDecoded[i/2] = iByte;
    zFilename += sqlite3Strlen30(zFilename) + 1;
  }
  return 0;
}

    }
    sqlite3_key_v2(db, zDb, zDecoded, i/2);
    return 1;
  }else if( (zKey = sqlite3_uri_parameter(zUri, "key"))!=0 ){
    sqlite3_key_v2(db, zDb, zKey, sqlite3Strlen30(zKey));
    return 1;
  }else if( (zKey = sqlite3_uri_parameter(zUri, "textkey"))!=0 ){
    sqlite3_key_v2(db, zDb, zKey, -1);
    return 1;
  }else{
    return 0;
  }
}
#endif


/*
** This routine does the work of opening a database on behalf of
** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
** is UTF-8 encoded.
*/
static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb,        /* OUT: Returned database handle */
  unsigned int flags,    /* Operational flags */
  const char *zVfs       /* Name of the VFS to use */
){
  sqlite3 *db;                    /* Store allocated handle here */
  int rc;                         /* Return code */
  int isThreadsafe;               /* True for threadsafe connections */
  char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */
  char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */
  int i;                          /* Loop counter */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
#endif
  *ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
  rc = sqlite3_initialize();
3142
3143
3144
3145
3146
3147
3148
3149

3150
3151
3152
3153
3154
3155
3156
3034
3035
3036
3037
3038
3039
3040

3041
3042
3043
3044
3045
3046
3047
3048







-
+







               SQLITE_OPEN_EXCLUSIVE |
               SQLITE_OPEN_MAIN_DB |
               SQLITE_OPEN_TEMP_DB | 
               SQLITE_OPEN_TRANSIENT_DB | 
               SQLITE_OPEN_MAIN_JOURNAL | 
               SQLITE_OPEN_TEMP_JOURNAL | 
               SQLITE_OPEN_SUBJOURNAL | 
               SQLITE_OPEN_SUPER_JOURNAL |
               SQLITE_OPEN_MASTER_JOURNAL |
               SQLITE_OPEN_NOMUTEX |
               SQLITE_OPEN_FULLMUTEX |
               SQLITE_OPEN_WAL
             );

  /* Allocate the sqlite data structure */
  db = sqlite3MallocZero( sizeof(sqlite3) );
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189

3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3064
3065
3066
3067
3068
3069
3070

3071
3072
3073
3074
3075
3076
3077
3078
3079

3080































3081
3082
3083
3084
3085
3086
3087







-









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







  }
  sqlite3_mutex_enter(db->mutex);
  db->errMask = 0xff;
  db->nDb = 2;
  db->magic = SQLITE_MAGIC_BUSY;
  db->aDb = db->aDbStatic;
  db->lookaside.bDisable = 1;
  db->lookaside.sz = 0;

  assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
  db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
  db->autoCommit = 1;
  db->nextAutovac = -1;
  db->szMmap = sqlite3GlobalConfig.szMmap;
  db->nextPagesize = 0;
  db->nMaxSorterMmap = 0x7FFFFFFF;
  db->flags |= SQLITE_ShortColNames
  db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
                 | SQLITE_EnableTrigger
                 | SQLITE_EnableView
                 | SQLITE_CacheSpill
#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0
                 | SQLITE_TrustedSchema
#endif
/* The SQLITE_DQS compile-time option determines the default settings
** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
**
**    SQLITE_DQS     SQLITE_DBCONFIG_DQS_DDL    SQLITE_DBCONFIG_DQS_DML
**    ----------     -----------------------    -----------------------
**     undefined               on                          on   
**         3                   on                          on
**         2                   on                         off
**         1                  off                          on
**         0                  off                         off
**
** Legacy behavior is 3 (double-quoted string literals are allowed anywhere)
** and so that is the default.  But developers are encouranged to use
** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible.
*/
#if !defined(SQLITE_DQS)
# define SQLITE_DQS 3
#endif
#if (SQLITE_DQS&1)==1
                 | SQLITE_DqsDML
#endif
#if (SQLITE_DQS&2)==2
                 | SQLITE_DqsDDL
#endif

#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
                 | SQLITE_AutoIndex
#endif
#if SQLITE_DEFAULT_CKPTFULLFSYNC
                 | SQLITE_CkptFullFSync
#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274

3275
3276
3277





3278
3279
3280
3281
3282
3283
3284
3107
3108
3109
3110
3111
3112
3113



3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130

3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146







-
-
-

















-
+



+
+
+
+
+







#endif
#if defined(SQLITE_ENABLE_QPSG)
                 | SQLITE_EnableQPSG
#endif
#if defined(SQLITE_DEFAULT_DEFENSIVE)
                 | SQLITE_Defensive
#endif
#if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE)
                 | SQLITE_LegacyAlter
#endif
      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif

  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.
  **
  ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
  ** functions:
  */
  createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
  createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
  createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
  createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
  createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
  createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
  if( db->mallocFailed ){
    goto opendb_out;
  }
  /* EVIDENCE-OF: R-08308-17224 The default collating function for all
  ** strings is BINARY. 
  */
  db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);
  assert( db->pDfltColl!=0 );

  /* Parse the filename/URI argument
  **
  ** Only allow sensible combinations of bits in the flags argument.  
  ** Throw an error if any non-sense combination is used.  If we
  ** do not block illegal combinations here, it could trigger
  ** assert() statements in deeper layers.  Sensible combinations
3292
3293
3294
3295
3296
3297
3298
3299

3300
3301
3302
3303
3304
3305
3306
3154
3155
3156
3157
3158
3159
3160

3161
3162
3163
3164
3165
3166
3167
3168







-
+







  assert( SQLITE_OPEN_READONLY  == 0x01 );
  assert( SQLITE_OPEN_READWRITE == 0x02 );
  assert( SQLITE_OPEN_CREATE    == 0x04 );
  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
  if( ((1<<(flags&7)) & 0x46)==0 ){
    rc = SQLITE_MISUSE_BKPT;  /* IMP: R-18321-05872 */
    rc = SQLITE_MISUSE_BKPT;  /* IMP: R-65497-44594 */
  }else{
    rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
  }
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
    sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
    sqlite3_free(zErrMsg);
3315
3316
3317
3318
3319
3320
3321
3322

3323
3324
3325
3326
3327
3328
3329
3330
3331
3177
3178
3179
3180
3181
3182
3183

3184


3185
3186
3187
3188
3189
3190
3191







-
+
-
-







      rc = SQLITE_NOMEM_BKPT;
    }
    sqlite3Error(db, rc);
    goto opendb_out;
  }
  sqlite3BtreeEnter(db->aDb[0].pBt);
  db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
  if( !db->mallocFailed ){
  if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
    sqlite3SetTextEncoding(db, SCHEMA_ENC(db));
  }
  sqlite3BtreeLeave(db->aDb[0].pBt);
  db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);

  /* The default safety_level for the main database is FULL; for the temp
  ** database it is OFF. This matches the pager layer defaults.  
  */
  db->aDb[0].zDbSName = "main";
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352






3353

3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370






















































3371
3372
3373
3374
3375
3376
3377
3202
3203
3204
3205
3206
3207
3208




3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228





3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289







-
-
-
-
+
+
+
+
+
+

+












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







  ** database schema yet. This is delayed until the first time the database
  ** is accessed.
  */
  sqlite3Error(db, SQLITE_OK);
  sqlite3RegisterPerConnectionBuiltinFunctions(db);
  rc = sqlite3_errcode(db);


  /* Load compiled-in extensions */
  for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
    rc = sqlite3BuiltinExtensions[i](db);
#ifdef SQLITE_ENABLE_FTS5
  /* Register any built-in FTS5 module before loading the automatic
  ** extensions. This allows automatic extensions to register FTS5 
  ** tokenizers and auxiliary functions.  */
  if( !db->mallocFailed && rc==SQLITE_OK ){
    rc = sqlite3Fts5Init(db);
  }
#endif

  /* Load automatic extensions - extensions that have been registered
  ** using the sqlite3_automatic_extension() API.
  */
  if( rc==SQLITE_OK ){
    sqlite3AutoLoadExtensions(db);
    rc = sqlite3_errcode(db);
    if( rc!=SQLITE_OK ){
      goto opendb_out;
    }
  }

#ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
  /* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
  ** option gives access to internal functions by default.  
  ** Testing use only!!! */
  db->mDbFlags |= DBFLAG_InternalFunc;
#ifdef SQLITE_ENABLE_FTS1
  if( !db->mallocFailed ){
    extern int sqlite3Fts1Init(sqlite3*);
    rc = sqlite3Fts1Init(db);
  }
#endif

#ifdef SQLITE_ENABLE_FTS2
  if( !db->mallocFailed && rc==SQLITE_OK ){
    extern int sqlite3Fts2Init(sqlite3*);
    rc = sqlite3Fts2Init(db);
  }
#endif

#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
  if( !db->mallocFailed && rc==SQLITE_OK ){
    rc = sqlite3Fts3Init(db);
  }
#endif

#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
  if( !db->mallocFailed && rc==SQLITE_OK ){
    rc = sqlite3IcuInit(db);
  }
#endif

#ifdef SQLITE_ENABLE_RTREE
  if( !db->mallocFailed && rc==SQLITE_OK){
    rc = sqlite3RtreeInit(db);
  }
#endif

#ifdef SQLITE_ENABLE_DBPAGE_VTAB
  if( !db->mallocFailed && rc==SQLITE_OK){
    rc = sqlite3DbpageRegister(db);
  }
#endif

#ifdef SQLITE_ENABLE_DBSTAT_VTAB
  if( !db->mallocFailed && rc==SQLITE_OK){
    rc = sqlite3DbstatRegister(db);
  }
#endif

#ifdef SQLITE_ENABLE_JSON1
  if( !db->mallocFailed && rc==SQLITE_OK){
    rc = sqlite3Json1Init(db);
  }
#endif

#ifdef SQLITE_ENABLE_STMTVTAB
  if( !db->mallocFailed && rc==SQLITE_OK){
    rc = sqlite3StmtVtabInit(db);
  }
#endif

  /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
  ** mode.  -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
  ** mode.  Doing nothing at all also makes NORMAL the default.
  */
#ifdef SQLITE_DEFAULT_LOCKING_MODE
3406
3407
3408
3409
3410
3411
3412



3413

3414
3415
3416
3417
3418
3419
3420
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327

3328
3329
3330
3331
3332
3333
3334
3335







+
+
+
-
+







#ifdef SQLITE_ENABLE_SQLLOG
  if( sqlite3GlobalConfig.xSqllog ){
    /* Opening a db handle. Fourth parameter is passed 0. */
    void *pArg = sqlite3GlobalConfig.pSqllogArg;
    sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
  }
#endif
#if defined(SQLITE_HAS_CODEC)
  if( rc==SQLITE_OK ) sqlite3CodecQueryParameters(db, 0, zOpen);
#endif
  sqlite3_free_filename(zOpen);
  sqlite3_free(zOpen);
  return rc & 0xff;
}


/*
** Open a new database handle.
*/
3633
3634
3635
3636
3637
3638
3639
3640

3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3548
3549
3550
3551
3552
3553
3554

3555
3556
3557
3558
3559
3560
3561


3562
3563
3564
3565
3566
3567
3568







-
+






-
-







  testcase( sqlite3GlobalConfig.xLog!=0 );
  return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse");
}
int sqlite3CantopenError(int lineno){
  testcase( sqlite3GlobalConfig.xLog!=0 );
  return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file");
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO)
#ifdef SQLITE_DEBUG
int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
  char zMsg[100];
  sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
  testcase( sqlite3GlobalConfig.xLog!=0 );
  return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
}
#endif
#ifdef SQLITE_DEBUG
int sqlite3NomemError(int lineno){
  testcase( sqlite3GlobalConfig.xLog!=0 );
  return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM");
}
int sqlite3IoerrnomemError(int lineno){
  testcase( sqlite3GlobalConfig.xLog!=0 );
  return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
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
3756
3757
3758
3759
3760
3761
3762
3763







3764

3765

3766
3767
3768
3769
3770
3771
3772








-
-
-
-
-
-
-

-

-







      *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager);
      rc = SQLITE_OK;
    }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
      *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
      rc = SQLITE_OK;
    }else if( op==SQLITE_FCNTL_DATA_VERSION ){
      *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
      rc = SQLITE_OK;
    }else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
      int iNew = *(int*)pArg;
      *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
      if( iNew>=0 && iNew<=255 ){
        sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
      }
      rc = SQLITE_OK;
    }else{
      int nSave = db->busyHandler.nBusy;
      rc = sqlite3OsFileControl(fd, op, pArg);
      db->busyHandler.nBusy = nSave;
    }
    sqlite3BtreeLeave(pBtree);
  }
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

3892
3893
3894
3895
3896
3897
3898
3899

3900
3901
3902
3903
3904
3905
3906
3907
3908
3909

3910
3911

3912
3913
3914

3915
3916
3917
3918
3919
3920

3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3796
3797
3798
3799
3800
3801
3802

3803










3804


3805



3806



3807


3808






3809
3810
3811

3812
3813
3814
3815
3816
3817
3818







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

-
-
+
-
-
-
-
-
-



-







    ** this verb acts like PRNG_RESET.
    */
    case SQLITE_TESTCTRL_PRNG_RESTORE: {
      sqlite3PrngRestoreState();
      break;
    }

    /*  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, sqlite3 *db);
    /*
    **
    ** Control the seed for the pseudo-random number generator (PRNG) that
    ** is built into SQLite.  Cases:
    **
    **    x!=0 && db!=0       Seed the PRNG to the current value of the
    **                        schema cookie in the main database for db, or
    **                        x if the schema cookie is zero.  This case
    **                        is convenient to use with database fuzzers
    **                        as it allows the fuzzer some control over the
    **                        the PRNG seed.
    ** Reset the PRNG back to its uninitialized state.  The next call
    **
    **    x!=0 && db==0       Seed the PRNG to the value of x.
    ** to sqlite3_randomness() will reseed the PRNG using a single call
    **
    **    x==0 && db==0       Revert to default behavior of using the
    **                        xRandomness method on the primary VFS.
    ** to the xRandomness method of the default VFS.
    **
    ** This test-control also resets the PRNG so that the new seed will
    ** be used for the next call to sqlite3_randomness().
    */
#ifndef SQLITE_OMIT_WSD
    case SQLITE_TESTCTRL_PRNG_SEED: {
    case SQLITE_TESTCTRL_PRNG_RESET: {
      int x = va_arg(ap, int);
      int y;
      sqlite3 *db = va_arg(ap, sqlite3*);
      assert( db==0 || db->aDb[0].pSchema!=0 );
      if( db && (y = db->aDb[0].pSchema->schema_cookie)!=0 ){ x = y; }
      sqlite3Config.iPrngSeed = x;
      sqlite3_randomness(0,0);
      break;
    }
#endif

    /*
    **  sqlite3_test_control(BITVEC_TEST, size, program)
    **
    ** Run a test against a Bitvec object of size.  The program argument
    ** is an array of integers that defines the test.  Return -1 on a
    ** memory allocation error, 0 on success, or non-zero for an error.
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
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
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981

3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995

3996
3997


3998
3999
4000
4001
4002
4003

4004

4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020

















4021
4022
4023
4024
4025
4026
4027







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












-
+













-
+

-
-
+
+
+
+


-
+
-
















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







    **  432101     big-endian,    determined at compile-time
    **  123410     little-endian, determined at compile-time
    */ 
    case SQLITE_TESTCTRL_BYTEORDER: {
      rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN;
      break;
    }

    /*   sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
    **
    ** Set the nReserve size to N for the main database on the database
    ** connection db.
    */
    case SQLITE_TESTCTRL_RESERVE: {
      sqlite3 *db = va_arg(ap, sqlite3*);
      int x = va_arg(ap,int);
      sqlite3_mutex_enter(db->mutex);
      sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0);
      sqlite3_mutex_leave(db->mutex);
      break;
    }

    /*  sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N)
    **
    ** Enable or disable various optimizations for testing purposes.  The 
    ** argument N is a bitmask of optimizations to be disabled.  For normal
    ** 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);
      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.
    */
    case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
      sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
      break;
    }

    /*   sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
    /*   sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff);
    **
    ** Toggle the ability to use internal functions on or off for
    ** the database connection given in the argument.
    ** If parameter onoff is non-zero, internal-use-only SQL functions
    ** are visible to ordinary SQL.  This is useful for testing but is
    ** unsafe because invalid parameters to those internal-use-only functions
    ** can result in crashes or segfaults.
    */
    case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
      sqlite3 *db = va_arg(ap, sqlite3*);
      sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int);
      db->mDbFlags ^= DBFLAG_InternalFunc;
      break;
    }

    /*   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
    **
    ** Set or clear a flag that indicates that the database file is always well-
    ** formed and never corrupt.  This flag is clear by default, indicating that
    ** database files might have arbitrary corruption.  Setting the flag during
    ** testing causes certain assert() statements in the code to be activated
    ** that demonstrat invariants on well-formed database files.
    */
    case SQLITE_TESTCTRL_NEVER_CORRUPT: {
      sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int);
      break;
    }

    /*   sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int);
    **
    ** Set or clear a flag that causes SQLite to verify that type, name,
    ** and tbl_name fields of the sqlite_schema table.  This is normally
    ** on, but it is sometimes useful to turn it off for testing.
    **
    ** 2020-07-22:  Disabling EXTRA_SCHEMA_CHECKS also disables the
    ** verification of rootpage numbers when parsing the schema.  This
    ** is useful to make it easier to reach strange internal error states
    ** during testing.  The EXTRA_SCHEMA_CHECKS setting is always enabled
    ** in production.
    */
    case SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS: {
      sqlite3GlobalConfig.bExtraSchemaChecks = va_arg(ap, int);
      break;
    }

    /* Set the threshold at which OP_Once counters reset back to zero.
    ** By default this is 0x7ffffffe (over 2 billion), but that value is
    ** too big to test in a reasonable amount of time, so this control is
    ** provided to set a small and easily reachable reset value.
    */
    case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: {
      sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int);
4221
4222
4223
4224
4225
4226
4227
4228

4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
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
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389


4390

4391
4392
4393

4394
4395
4396
4397
4398
4399
4400
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







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




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














-
-
-
-
-
-
-
-
-
-

-
+
+

+


-
+







    */
    case SQLITE_TESTCTRL_PARSER_COVERAGE: {
      FILE *out = va_arg(ap, FILE*);
      if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
      break;
    }
#endif /* defined(YYCOVERAGE) */

  }
    /*  sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
    **
    ** This test-control causes the most recent sqlite3_result_int64() value
    ** to be interpreted as a MEM_IntReal instead of as an MEM_Int.  Normally,
    ** MEM_IntReal values only arise during an INSERT operation of integer
    ** values into a REAL column, so they can be challenging to test.  This
    ** test-control enables us to write an intreal() SQL function that can
    ** inject an intreal() value at arbitrary places in an SQL statement,
    ** for testing purposes.
    */
    case SQLITE_TESTCTRL_RESULT_INTREAL: {
      sqlite3_context *pCtx = va_arg(ap, sqlite3_context*);
      sqlite3ResultIntReal(pCtx);
      break;
    }

    /*  sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT,
    **    sqlite3 *db,    // Database connection
    **    u64 *pnSeek     // Write seek count here
    **  );
    **
    ** This test-control queries the seek-counter on the "main" database
    ** file.  The seek-counter is written into *pnSeek and is then reset.
    ** The seek-count is only available if compiled with SQLITE_DEBUG.
    */
    case SQLITE_TESTCTRL_SEEK_COUNT: {
      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;
}

/*
** The Pager stores the Database filename, Journal filename, and WAL filename
** consecutively in memory, in that order.  The database filename is prefixed
** by four zero bytes.  Locate the start of the database filename by searching
** backwards for the first byte following four consecutive zero bytes.
**
** This only works if the filename passed in was obtained from the Pager.
*/
static const char *databaseName(const char *zName){
  while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
    zName--;
  }
  return zName;
}

/*
** Append text z[] to the end of p[].  Return a pointer to the first
** character after then zero terminator on the new text in p[].
*/
static char *appendText(char *p, const char *z){
  size_t n = strlen(z);
  memcpy(p, z, n+1);
  return p+n+1;
}

/*
** Allocate memory to hold names for a database, journal file, WAL file,
** and query parameters.  The pointer returned is valid for use by
** sqlite3_filename_database() and sqlite3_uri_parameter() and related
** functions.
**
** Memory layout must be compatible with that generated by the pager
** and expected by sqlite3_uri_parameter() and databaseName().
*/
char *sqlite3_create_filename(
  const char *zDatabase,
  const char *zJournal,
  const char *zWal,
  int nParam,
  const char **azParam
){
  sqlite3_int64 nByte;
  int i;
  char *pResult, *p;
  nByte = strlen(zDatabase) + strlen(zJournal) + strlen(zWal) + 10;
  for(i=0; i<nParam*2; i++){
    nByte += strlen(azParam[i])+1;
  }
  pResult = p = sqlite3_malloc64( nByte );
  if( p==0 ) return 0;
  memset(p, 0, 4);
  p += 4;
  p = appendText(p, zDatabase);
  for(i=0; i<nParam*2; i++){
    p = appendText(p, azParam[i]);
  }
  *(p++) = 0;
  p = appendText(p, zJournal);
  p = appendText(p, zWal);
  *(p++) = 0;
  *(p++) = 0;
  assert( (sqlite3_int64)(p - pResult)==nByte );
  return pResult + 4;
}

/*
** Free memory obtained from sqlite3_create_filename().  It is a severe
** error to call this routine with any parameter other than a pointer
** previously obtained from sqlite3_create_filename() or a NULL pointer.
*/
void sqlite3_free_filename(char *p){
  if( p==0 ) return;
  p = (char*)databaseName(p);
  sqlite3_free(p - 4);
}


/*
** This is a utility routine, useful to VFS implementations, that checks
** to see if a database file was a URI that contained a specific query 
** parameter, and if so obtains the value of the query parameter.
**
** The zFilename argument is the filename pointer passed into the xOpen()
** method of a VFS implementation.  The zParam argument is the name of the
** query parameter we seek.  This routine returns the value of the zParam
** parameter if it exists.  If the parameter does not exist, this routine
** returns a NULL pointer.
*/
const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
  if( zFilename==0 || zParam==0 ) return 0;
  zFilename = databaseName(zFilename);
  return uriParameter(zFilename, zParam);
}

/*
** Return a pointer to the name of Nth query parameter of the filename.
*/
const char *sqlite3_uri_key(const char *zFilename, int N){
  if( zFilename==0 || N<0 ) return 0;
  zFilename = databaseName(zFilename);
  zFilename += sqlite3Strlen30(zFilename) + 1;
  while( zFilename[0] && (N--)>0 ){
  while( zFilename[0] ){
    int x = strcmp(zFilename, zParam);
    zFilename += sqlite3Strlen30(zFilename) + 1;
    if( x==0 ) return zFilename;
    zFilename += sqlite3Strlen30(zFilename) + 1;
  }
  return zFilename[0] ? zFilename : 0;
  return 0;
}

/*
** Return a boolean value for a query parameter.
*/
int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
  const char *z = sqlite3_uri_parameter(zFilename, zParam);
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4154
4155
4156
4157
4158
4159
4160
































4161
4162
4163
4164
4165
4166
4167







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







  sqlite3_int64 v;
  if( z && sqlite3DecOrHexToI64(z, &v)==0 ){
    bDflt = v;
  }
  return bDflt;
}

/*
** Translate a filename that was handed to a VFS routine into the corresponding
** database, journal, or WAL file.
**
** It is an error to pass this routine a filename string that was not
** passed into the VFS from the SQLite core.  Doing so is similar to
** passing free() a pointer that was not obtained from malloc() - it is
** an error that we cannot easily detect but that will likely cause memory
** corruption.
*/
const char *sqlite3_filename_database(const char *zFilename){
  return databaseName(zFilename);
}
const char *sqlite3_filename_journal(const char *zFilename){
  zFilename = databaseName(zFilename);
  zFilename += sqlite3Strlen30(zFilename) + 1;
  while( zFilename[0] ){
    zFilename += sqlite3Strlen30(zFilename) + 1;
    zFilename += sqlite3Strlen30(zFilename) + 1;
  }
  return zFilename + 1;
}
const char *sqlite3_filename_wal(const char *zFilename){
#ifdef SQLITE_OMIT_WAL
  return 0;
#else
  zFilename = sqlite3_filename_journal(zFilename);
  zFilename += sqlite3Strlen30(zFilename) + 1;
  return zFilename;
#endif
}

/*
** Return the Btree pointer identified by zDbName.  Return NULL if not found.
*/
Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
  int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
  return iDb<0 ? 0 : db->aDb[iDb].pBt;
}
4510
4511
4512
4513
4514
4515
4516
4517

4518
4519
4520
4521
4522
4523
4524
4218
4219
4220
4221
4222
4223
4224

4225
4226
4227
4228
4229
4230
4231
4232







-
+







#endif
  sqlite3_mutex_enter(db->mutex);

  if( db->autoCommit==0 ){
    int iDb = sqlite3FindDbName(db, zDb);
    if( iDb==0 || iDb>1 ){
      Btree *pBt = db->aDb[iDb].pBt;
      if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){
      if( 0==sqlite3BtreeIsInTrans(pBt) ){
        rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
        if( rc==SQLITE_OK ){
          rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
        }
      }
    }
  }
4546
4547
4548
4549
4550
4551
4552
4553

4554
4555
4556

4557
4558
4559
4560
4561
4562
4563
4254
4255
4256
4257
4258
4259
4260

4261
4262
4263

4264
4265
4266
4267
4268
4269
4270
4271







-
+


-
+







#endif
  sqlite3_mutex_enter(db->mutex);
  if( db->autoCommit==0 ){
    int iDb;
    iDb = sqlite3FindDbName(db, zDb);
    if( iDb==0 || iDb>1 ){
      Btree *pBt = db->aDb[iDb].pBt;
      if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ){
      if( sqlite3BtreeIsInTrans(pBt)==0 ){
        Pager *pPager = sqlite3BtreePager(pBt);
        int bUnlock = 0;
        if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_NONE ){
        if( sqlite3BtreeIsInReadTrans(pBt) ){
          if( db->nVdbeActive==0 ){
            rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot);
            if( rc==SQLITE_OK ){
              bUnlock = 1;
              rc = sqlite3BtreeCommit(pBt);
            }
          }
4598
4599
4600
4601
4602
4603
4604
4605

4606
4607
4608
4609
4610
4611
4612
4306
4307
4308
4309
4310
4311
4312

4313
4314
4315
4316
4317
4318
4319
4320







-
+







  }
#endif

  sqlite3_mutex_enter(db->mutex);
  iDb = sqlite3FindDbName(db, zDb);
  if( iDb==0 || iDb>1 ){
    Btree *pBt = db->aDb[iDb].pBt;
    if( SQLITE_TXN_NONE==sqlite3BtreeTxnState(pBt) ){
    if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
      rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
      if( rc==SQLITE_OK ){
        rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
        sqlite3BtreeCommit(pBt);
      }
    }
  }

Changes to src/malloc.c.

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







-
-
-
-
-
-
-






-






-
+







  ** is a no-op returning zero if SQLite is not compiled with
  ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */
  UNUSED_PARAMETER(n);
  return 0;
#endif
}

/*
** Default value of the hard heap limit.  0 means "no limit".
*/
#ifndef SQLITE_MAX_MEMORY
# define SQLITE_MAX_MEMORY 0
#endif

/*
** State information local to the memory allocation subsystem.
*/
static SQLITE_WSD struct Mem0Global {
  sqlite3_mutex *mutex;         /* Mutex to serialize access */
  sqlite3_int64 alarmThreshold; /* The soft heap limit */
  sqlite3_int64 hardLimit;      /* The hard upper bound on memory */

  /*
  ** True if heap is nearly "full" where "full" is defined by the
  ** sqlite3_soft_heap_limit() setting.
  */
  int nearlyFull;
} mem0 = { 0, SQLITE_MAX_MEMORY, SQLITE_MAX_MEMORY, 0 };
} mem0 = { 0, 0, 0 };

#define mem0 GLOBAL(struct Mem0Global, mem0)

/*
** Return the memory allocator mutex. sqlite3_status() needs it.
*/
sqlite3_mutex *sqlite3MallocMutex(void){
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
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







-
-
+
+
-
-
-
-
-
-
-















-
-
-


-
+









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







  (void)pArg;
  (void)iThreshold;
  return SQLITE_OK;
}
#endif

/*
** Set the soft heap-size limit for the library.  An argument of
** zero disables the limit.  A negative argument is a no-op used to
** Set the soft heap-size limit for the library. Passing a zero or 
** negative value indicates no limit.
** obtain the return value.
**
** The return value is the value of the heap limit just before this
** interface was called.
**
** If the hard heap limit is enabled, then the soft heap limit cannot
** be disabled nor raised above the hard heap limit.
*/
sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
  sqlite3_int64 priorLimit;
  sqlite3_int64 excess;
  sqlite3_int64 nUsed;
#ifndef SQLITE_OMIT_AUTOINIT
  int rc = sqlite3_initialize();
  if( rc ) return -1;
#endif
  sqlite3_mutex_enter(mem0.mutex);
  priorLimit = mem0.alarmThreshold;
  if( n<0 ){
    sqlite3_mutex_leave(mem0.mutex);
    return priorLimit;
  }
  if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
    n = mem0.hardLimit;
  }
  mem0.alarmThreshold = n;
  nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
  AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed);
  mem0.nearlyFull = (n>0 && n<=nUsed);
  sqlite3_mutex_leave(mem0.mutex);
  excess = sqlite3_memory_used() - n;
  if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
  return priorLimit;
}
void sqlite3_soft_heap_limit(int n){
  if( n<0 ) n = 0;
  sqlite3_soft_heap_limit64(n);
}

/*
** Set the hard heap-size limit for the library. An argument of zero
** disables the hard heap limit.  A negative argument is a no-op used
** to obtain the return value without affecting the hard heap limit.
**
** The return value is the value of the hard heap limit just prior to
** calling this interface.
**
** Setting the hard heap limit will also activate the soft heap limit
** and constrain the soft heap limit to be no more than the hard heap
** limit.
*/
sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){
  sqlite3_int64 priorLimit;
#ifndef SQLITE_OMIT_AUTOINIT
  int rc = sqlite3_initialize();
  if( rc ) return -1;
#endif
  sqlite3_mutex_enter(mem0.mutex);
  priorLimit = mem0.hardLimit;
  if( n>=0 ){
    mem0.hardLimit = n;
    if( n<mem0.alarmThreshold || mem0.alarmThreshold==0 ){
      mem0.alarmThreshold = n;
    }
  }
  sqlite3_mutex_leave(mem0.mutex);
  return priorLimit;
}


/*
** Initialize the memory allocation subsystem.
*/
int sqlite3MallocInit(void){
  int rc;
  if( sqlite3GlobalConfig.m.xMalloc==0 ){
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140







-
+








/*
** Return true if the heap is currently under memory pressure - in other
** words if the amount of heap used is close to the limit set by
** sqlite3_soft_heap_limit().
*/
int sqlite3HeapNearlyFull(void){
  return AtomicLoad(&mem0.nearlyFull);
  return mem0.nearlyFull;
}

/*
** Deinitialize the memory allocation subsystem.
*/
void sqlite3MallocEnd(void){
  if( sqlite3GlobalConfig.m.xShutdown ){
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
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







+
+
+
+
+
+
+





-
+

-
-
-
-
-
-
-

-
+








  /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
  ** implementation of malloc_good_size(), which must be called in debug
  ** mode and specifically when the DMD "Dark Matter Detector" is enabled
  ** or else a crash results.  Hence, do not attempt to optimize out the
  ** following xRoundup() call. */
  nFull = sqlite3GlobalConfig.m.xRoundup(n);

#ifdef SQLITE_MAX_MEMORY
  if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){
    *pp = 0;
    return;
  }
#endif

  sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
  if( mem0.alarmThreshold>0 ){
    sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
    if( nUsed >= mem0.alarmThreshold - nFull ){
      AtomicStore(&mem0.nearlyFull, 1);
      mem0.nearlyFull = 1;
      sqlite3MallocAlarm(nFull);
      if( mem0.hardLimit ){
        nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
        if( nUsed >= mem0.hardLimit - nFull ){
          *pp = 0;
          return;
        }
      }
    }else{
      AtomicStore(&mem0.nearlyFull, 0);
      mem0.nearlyFull = 0;
    }
  }
  p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  if( p==0 && mem0.alarmThreshold>0 ){
    sqlite3MallocAlarm(nFull);
    p = sqlite3GlobalConfig.m.xMalloc(nFull);
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
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







-
-
-
-
-
-
-


-

+







-

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







** Return the size of a memory allocation previously obtained from
** sqlite3Malloc() or sqlite3_malloc().
*/
int sqlite3MallocSize(void *p){
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  return sqlite3GlobalConfig.m.xSize(p);
}
static int lookasideMallocSize(sqlite3 *db, void *p){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE    
  return p<db->lookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL;
#else
  return db->lookaside.szTrue;
#endif  
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
  assert( p!=0 );
#ifdef SQLITE_DEBUG
  if( db==0 || !isLookaside(db,p) ){
#ifdef SQLITE_DEBUG
    if( db==0 ){
      assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
      assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
    }else{
      assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
      assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
    }
  }
#endif
  if( db ){
    if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
      if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){
        assert( sqlite3_mutex_held(db->mutex) );
        return LOOKASIDE_SMALL;
      }
    return sqlite3GlobalConfig.m.xSize(p);
  }else{
#endif
      if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){
        assert( sqlite3_mutex_held(db->mutex) );
        return db->lookaside.szTrue;
      }
    assert( sqlite3_mutex_held(db->mutex) );
    return db->lookaside.sz;
  }
    }
  }
  return sqlite3GlobalConfig.m.xSize(p);
}
sqlite3_uint64 sqlite3_msize(void *p){
  assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
}

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
342
343
344
345
346
347
348

349



350
351

352










353
354



355
356
357

358
359
360
361
362
363
364







-
+
-
-
-
+

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

-
-
-
+
+
+
-







  assert( db==0 || sqlite3_mutex_held(db->mutex) );
  assert( p!=0 );
  if( db ){
    if( db->pnBytesFreed ){
      measureAllocationSize(db, p);
      return;
    }
    if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){
    if( isLookaside(db, p) ){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
      if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){
        LookasideSlot *pBuf = (LookasideSlot*)p;
      LookasideSlot *pBuf = (LookasideSlot*)p;
#ifdef SQLITE_DEBUG
        memset(p, 0xaa, LOOKASIDE_SMALL);  /* Trash freed content */
      /* Trash all content in the buffer being freed */
#endif
        pBuf->pNext = db->lookaside.pSmallFree;
        db->lookaside.pSmallFree = pBuf;
        return;
      }
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
      if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){
        LookasideSlot *pBuf = (LookasideSlot*)p;
#ifdef SQLITE_DEBUG
        memset(p, 0xaa, db->lookaside.szTrue);  /* Trash freed content */
      memset(p, 0xaa, db->lookaside.sz);
#endif
        pBuf->pNext = db->lookaside.pFree;
        db->lookaside.pFree = pBuf;
        return;
      pBuf->pNext = db->lookaside.pFree;
      db->lookaside.pFree = pBuf;
      return;
      }
    }
  }
  assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
  assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
  assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
  sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
  sqlite3_free(p);
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
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







-



-
+


-
-
-
-
+
-

-




-







  /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second
  ** argument to xRealloc is always a value returned by a prior call to
  ** xRoundup. */
  nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes);
  if( nOld==nNew ){
    pNew = pOld;
  }else if( sqlite3GlobalConfig.bMemstat ){
    sqlite3_int64 nUsed;
    sqlite3_mutex_enter(mem0.mutex);
    sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
    nDiff = nNew - nOld;
    if( nDiff>0 && (nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)) >= 
    if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= 
          mem0.alarmThreshold-nDiff ){
      sqlite3MallocAlarm(nDiff);
      if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){
        sqlite3_mutex_leave(mem0.mutex);
        return 0;
      }
    }
    }
    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
    if( pNew==0 && mem0.alarmThreshold>0 ){
      sqlite3MallocAlarm((int)nBytes);
      pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
    }
#endif
    if( pNew ){
      nNew = sqlite3MallocSize(pNew);
      sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
    }
    sqlite3_mutex_leave(mem0.mutex);
  }else{
    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
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
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







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







}
void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
#ifndef SQLITE_OMIT_LOOKASIDE
  LookasideSlot *pBuf;
  assert( db!=0 );
  assert( sqlite3_mutex_held(db->mutex) );
  assert( db->pnBytesFreed==0 );
  if( n>db->lookaside.sz ){
    if( !db->lookaside.bDisable ){
  if( db->lookaside.bDisable==0 ){
      db->lookaside.anStat[1]++;      
    }else if( db->mallocFailed ){
    assert( db->mallocFailed==0 );
      return 0;
    }
    return dbMallocRawFinish(db, n);
  }
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
  if( n<=LOOKASIDE_SMALL ){
    if( (pBuf = db->lookaside.pSmallFree)!=0 ){
      db->lookaside.pSmallFree = pBuf->pNext;
      db->lookaside.anStat[0]++;
    if( n>db->lookaside.sz ){
      return (void*)pBuf;
    }else if( (pBuf = db->lookaside.pSmallInit)!=0 ){
      db->lookaside.pSmallInit = pBuf->pNext;
      db->lookaside.anStat[0]++;
      db->lookaside.anStat[1]++;
      return (void*)pBuf;
    }
  }
#endif
  if( (pBuf = db->lookaside.pFree)!=0 ){
    db->lookaside.pFree = pBuf->pNext;
    db->lookaside.anStat[0]++;
    return (void*)pBuf;
  }else if( (pBuf = db->lookaside.pInit)!=0 ){
    db->lookaside.pInit = pBuf->pNext;
    db->lookaside.anStat[0]++;
    return (void*)pBuf;
  }else{
    db->lookaside.anStat[2]++;
    }else if( (pBuf = db->lookaside.pFree)!=0 ){
      db->lookaside.pFree = pBuf->pNext;
      db->lookaside.anStat[0]++;
      return (void*)pBuf;
    }else if( (pBuf = db->lookaside.pInit)!=0 ){
      db->lookaside.pInit = pBuf->pNext;
      db->lookaside.anStat[0]++;
      return (void*)pBuf;
    }else{
      db->lookaside.anStat[2]++;
    }
  }else if( db->mallocFailed ){
    return 0;
  }
#else
  assert( db!=0 );
  assert( sqlite3_mutex_held(db->mutex) );
  assert( db->pnBytesFreed==0 );
  if( db->mallocFailed ){
    return 0;
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
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







-
-
-
-
-
-
-
-
+
-
-










-
+






-
+







** Resize the block of memory pointed to by p to n bytes. If the
** resize fails, set the mallocFailed flag in the connection object.
*/
void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
  assert( db!=0 );
  if( p==0 ) return sqlite3DbMallocRawNN(db, n);
  assert( sqlite3_mutex_held(db->mutex) );
  if( ((uptr)p)<(uptr)db->lookaside.pEnd ){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
    if( ((uptr)p)>=(uptr)db->lookaside.pMiddle ){
      if( n<=LOOKASIDE_SMALL ) return p;
    }else
#endif
    if( ((uptr)p)>=(uptr)db->lookaside.pStart ){
      if( n<=db->lookaside.szTrue ) return p;
  if( isLookaside(db,p) && n<=db->lookaside.sz ) return p;
    }
  }
  return dbReallocFinish(db, p, n);
}
static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
  void *pNew = 0;
  assert( db!=0 );
  assert( p!=0 );
  if( db->mallocFailed==0 ){
    if( isLookaside(db, p) ){
      pNew = sqlite3DbMallocRawNN(db, n);
      if( pNew ){
        memcpy(pNew, p, lookasideMallocSize(db, p));
        memcpy(pNew, p, db->lookaside.sz);
        sqlite3DbFree(db, p);
      }
    }else{
      assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
      assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
      pNew = sqlite3Realloc(p, n);
      pNew = sqlite3_realloc64(p, n);
      if( !pNew ){
        sqlite3OomFault(db);
      }
      sqlite3MemdebugSetType(pNew,
            (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
    }
  }
720
721
722
723
724
725
726
727



728
729

730
731
732
733
734
735
736
611
612
613
614
615
616
617

618
619
620
621

622
623
624
625
626
627
628
629







-
+
+
+

-
+







    memcpy(zNew, z, n);
  }
  return zNew;
}
char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
  char *zNew;
  assert( db!=0 );
  assert( z!=0 || n==0 );
  if( z==0 ){
    return 0;
  }
  assert( (n&0x7fffffff)==n );
  zNew = z ? sqlite3DbMallocRawNN(db, n+1) : 0;
  zNew = sqlite3DbMallocRawNN(db, n+1);
  if( zNew ){
    memcpy(zNew, z, (size_t)n);
    zNew[n] = 0;
  }
  return zNew;
}

761
762
763
764
765
766
767
768

769
770

771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787

788
789

790
791
792
793
794

795
796

797
798
799
800



801
802
803
804
805
806
807
808
809
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







-
+

-
+
















-
+

-
+




-
+

-
+
-
-
-
-
+
+
+
-
-







** temporarily disable the lookaside memory allocator and interrupt
** any running VDBEs.
*/
void sqlite3OomFault(sqlite3 *db){
  if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
    db->mallocFailed = 1;
    if( db->nVdbeExec>0 ){
      AtomicStore(&db->u1.isInterrupted, 1);
      db->u1.isInterrupted = 1;
    }
    DisableLookaside;
    db->lookaside.bDisable++;
    if( db->pParse ){
      db->pParse->rc = SQLITE_NOMEM_BKPT;
    }
  }
}

/*
** This routine reactivates the memory allocator and clears the
** db->mallocFailed flag as necessary.
**
** The memory allocator is not restarted if there are running
** VDBEs.
*/
void sqlite3OomClear(sqlite3 *db){
  if( db->mallocFailed && db->nVdbeExec==0 ){
    db->mallocFailed = 0;
    AtomicStore(&db->u1.isInterrupted, 0);
    db->u1.isInterrupted = 0;
    assert( db->lookaside.bDisable>0 );
    EnableLookaside;
    db->lookaside.bDisable--;
  }
}

/*
** Take actions at the end of an API call to deal with error codes.
** Take actions at the end of an API call to indicate an OOM error
*/
static SQLITE_NOINLINE int apiHandleError(sqlite3 *db, int rc){
static SQLITE_NOINLINE int apiOomError(sqlite3 *db){
  if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){
    sqlite3OomClear(db);
    sqlite3Error(db, SQLITE_NOMEM);
    return SQLITE_NOMEM_BKPT;
  sqlite3OomClear(db);
  sqlite3Error(db, SQLITE_NOMEM);
  return SQLITE_NOMEM_BKPT;
  }
  return rc & db->errMask;
}

/*
** This function must be called before exiting any API function (i.e. 
** returning control to the user) that has called sqlite3_malloc or
** sqlite3_realloc.
**
817
818
819
820
821
822
823
824
825


826
827
828
707
708
709
710
711
712
713


714
715
716
717
718







-
-
+
+



int sqlite3ApiExit(sqlite3* db, int rc){
  /* If the db handle must hold the connection handle mutex here.
  ** Otherwise the read (and possible write) of db->mallocFailed 
  ** is unsafe, as is the call to sqlite3Error().
  */
  assert( db!=0 );
  assert( sqlite3_mutex_held(db->mutex) );
  if( db->mallocFailed || rc ){
    return apiHandleError(db, rc);
  if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){
    return apiOomError(db);
  }
  return rc & db->errMask;
}

Changes to src/mem2.c.

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







-
+


















-
+







  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
}

/*
** Set the "type" of an allocation.
*/
void sqlite3MemdebugSetType(void *p, u8 eType){
  if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );
    pHdr->eType = eType;
  }
}

/*
** Return TRUE if the mask of type in eType matches the type of the
** allocation p.  Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
*/
int sqlite3MemdebugHasType(void *p, u8 eType){
  int rc = 1;
  if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
    if( (pHdr->eType&eType)==0 ){
      rc = 0;
    }
  }
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430







-
+







** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
*/
int sqlite3MemdebugNoType(void *p, u8 eType){
  int rc = 1;
  if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
    if( (pHdr->eType&eType)!=0 ){
      rc = 0;
    }
  }

Changes to src/mem3.c.

114
115
116
117
118
119
120
121

122
123
124
125
126
127




128
129
130


131
132
133
134
135
136
137
114
115
116
117
118
119
120

121
122
123




124
125
126
127
128


129
130
131
132
133
134
135
136
137







-
+


-
-
-
-
+
+
+
+

-
-
+
+







  ** Mutex to control access to the memory allocation subsystem.
  */
  sqlite3_mutex *mutex;
  
  /*
  ** The minimum amount of free space that we have seen.
  */
  u32 mnKeyBlk;
  u32 mnMaster;

  /*
  ** iKeyBlk is the index of the key chunk.  Most new allocations
  ** occur off of this chunk.  szKeyBlk is the size (in Mem3Blocks)
  ** of the current key chunk.  iKeyBlk is 0 if there is no key chunk.
  ** The key chunk is not in either the aiHash[] or aiSmall[].
  ** iMaster is the index of the master chunk.  Most new allocations
  ** occur off of this chunk.  szMaster is the size (in Mem3Blocks)
  ** of the current master.  iMaster is 0 if there is not master chunk.
  ** The master chunk is not in either the aiHash[] or aiSmall[].
  */
  u32 iKeyBlk;
  u32 szKeyBlk;
  u32 iMaster;
  u32 szMaster;

  /*
  ** Array of lists of free blocks according to the block size 
  ** for smaller chunks, or a hash on the block size for larger
  ** chunks.
  */
  u32 aiSmall[MX_SMALL-1];   /* For sizes 2 through MX_SMALL, inclusive */
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
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







-
-
+
+


-
+

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


-
+

-
-
-
-
+
+
+
+

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













-
-
-
+
+
+

-
+

-
+







  mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2);
  mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock;
  mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2;
  return &mem3.aPool[i];
}

/*
** Carve a piece off of the end of the mem3.iKeyBlk free chunk.
** Return a pointer to the new allocation.  Or, if the key chunk
** Carve a piece off of the end of the mem3.iMaster free chunk.
** Return a pointer to the new allocation.  Or, if the master chunk
** is not large enough, return 0.
*/
static void *memsys3FromKeyBlk(u32 nBlock){
static void *memsys3FromMaster(u32 nBlock){
  assert( sqlite3_mutex_held(mem3.mutex) );
  assert( mem3.szKeyBlk>=nBlock );
  if( nBlock>=mem3.szKeyBlk-1 ){
    /* Use the entire key chunk */
    void *p = memsys3Checkout(mem3.iKeyBlk, mem3.szKeyBlk);
    mem3.iKeyBlk = 0;
    mem3.szKeyBlk = 0;
    mem3.mnKeyBlk = 0;
  assert( mem3.szMaster>=nBlock );
  if( nBlock>=mem3.szMaster-1 ){
    /* Use the entire master */
    void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster);
    mem3.iMaster = 0;
    mem3.szMaster = 0;
    mem3.mnMaster = 0;
    return p;
  }else{
    /* Split the key block.  Return the tail. */
    /* Split the master block.  Return the tail. */
    u32 newi, x;
    newi = mem3.iKeyBlk + mem3.szKeyBlk - nBlock;
    assert( newi > mem3.iKeyBlk+1 );
    mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.prevSize = nBlock;
    mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.size4x |= 2;
    newi = mem3.iMaster + mem3.szMaster - nBlock;
    assert( newi > mem3.iMaster+1 );
    mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock;
    mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2;
    mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1;
    mem3.szKeyBlk -= nBlock;
    mem3.aPool[newi-1].u.hdr.prevSize = mem3.szKeyBlk;
    x = mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x & 2;
    mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x = mem3.szKeyBlk*4 | x;
    if( mem3.szKeyBlk < mem3.mnKeyBlk ){
      mem3.mnKeyBlk = mem3.szKeyBlk;
    mem3.szMaster -= nBlock;
    mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster;
    x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
    mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
    if( mem3.szMaster < mem3.mnMaster ){
      mem3.mnMaster = mem3.szMaster;
    }
    return (void*)&mem3.aPool[newi];
  }
}

/*
** *pRoot is the head of a list of free chunks of the same size
** or same size hash.  In other words, *pRoot is an entry in either
** mem3.aiSmall[] or mem3.aiHash[].  
**
** This routine examines all entries on the given list and tries
** to coalesce each entries with adjacent free chunks.  
**
** If it sees a chunk that is larger than mem3.iKeyBlk, it replaces 
** the current mem3.iKeyBlk with the new larger chunk.  In order for
** this mem3.iKeyBlk replacement to work, the key chunk must be
** If it sees a chunk that is larger than mem3.iMaster, it replaces 
** the current mem3.iMaster with the new larger chunk.  In order for
** this mem3.iMaster replacement to work, the master chunk must be
** linked into the hash tables.  That is not the normal state of
** affairs, of course.  The calling routine must link the key
** affairs, of course.  The calling routine must link the master
** chunk before invoking this routine, then must unlink the (possibly
** changed) key chunk once this routine has finished.
** changed) master chunk once this routine has finished.
*/
static void memsys3Merge(u32 *pRoot){
  u32 iNext, prev, size, i, x;

  assert( sqlite3_mutex_held(mem3.mutex) );
  for(i=*pRoot; i>0; i=iNext){
    iNext = mem3.aPool[i].u.list.next;
333
334
335
336
337
338
339
340
341
342



343
344
345
346
347
348
349
333
334
335
336
337
338
339



340
341
342
343
344
345
346
347
348
349







-
-
-
+
+
+







      mem3.aPool[prev-1].u.hdr.size4x = size*4 | x;
      mem3.aPool[prev+size-1].u.hdr.prevSize = size;
      memsys3Link(prev);
      i = prev;
    }else{
      size /= 4;
    }
    if( size>mem3.szKeyBlk ){
      mem3.iKeyBlk = i;
      mem3.szKeyBlk = size;
    if( size>mem3.szMaster ){
      mem3.iMaster = i;
      mem3.szMaster = size;
    }
  }
}

/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable.
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
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







-
+

-
-
+
+





-
+

-
+




-
-
-
-
+
+
+
+







-
-
-
-
+
+
+
+







        return memsys3Checkout(i, nBlock);
      }
    }
  }

  /* STEP 2:
  ** Try to satisfy the allocation by carving a piece off of the end
  ** of the key chunk.  This step usually works if step 1 fails.
  ** of the master chunk.  This step usually works if step 1 fails.
  */
  if( mem3.szKeyBlk>=nBlock ){
    return memsys3FromKeyBlk(nBlock);
  if( mem3.szMaster>=nBlock ){
    return memsys3FromMaster(nBlock);
  }


  /* STEP 3:  
  ** Loop through the entire memory pool.  Coalesce adjacent free
  ** chunks.  Recompute the key chunk as the largest free chunk.
  ** chunks.  Recompute the master chunk as the largest free chunk.
  ** Then try again to satisfy the allocation by carving a piece off
  ** of the end of the key chunk.  This step happens very
  ** of the end of the master chunk.  This step happens very
  ** rarely (we hope!)
  */
  for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){
    memsys3OutOfMemory(toFree);
    if( mem3.iKeyBlk ){
      memsys3Link(mem3.iKeyBlk);
      mem3.iKeyBlk = 0;
      mem3.szKeyBlk = 0;
    if( mem3.iMaster ){
      memsys3Link(mem3.iMaster);
      mem3.iMaster = 0;
      mem3.szMaster = 0;
    }
    for(i=0; i<N_HASH; i++){
      memsys3Merge(&mem3.aiHash[i]);
    }
    for(i=0; i<MX_SMALL-1; i++){
      memsys3Merge(&mem3.aiSmall[i]);
    }
    if( mem3.szKeyBlk ){
      memsys3Unlink(mem3.iKeyBlk);
      if( mem3.szKeyBlk>=nBlock ){
        return memsys3FromKeyBlk(nBlock);
    if( mem3.szMaster ){
      memsys3Unlink(mem3.iMaster);
      if( mem3.szMaster>=nBlock ){
        return memsys3FromMaster(nBlock);
      }
    }
  }

  /* If none of the above worked, then we fail. */
  return 0;
}
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
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







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

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







  size = mem3.aPool[i-1].u.hdr.size4x/4;
  assert( i+size<=mem3.nPool+1 );
  mem3.aPool[i-1].u.hdr.size4x &= ~1;
  mem3.aPool[i+size-1].u.hdr.prevSize = size;
  mem3.aPool[i+size-1].u.hdr.size4x &= ~2;
  memsys3Link(i);

  /* Try to expand the key using the newly freed chunk */
  if( mem3.iKeyBlk ){
    while( (mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x&2)==0 ){
      size = mem3.aPool[mem3.iKeyBlk-1].u.hdr.prevSize;
      mem3.iKeyBlk -= size;
      mem3.szKeyBlk += size;
      memsys3Unlink(mem3.iKeyBlk);
      x = mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x & 2;
      mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x = mem3.szKeyBlk*4 | x;
      mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.prevSize = mem3.szKeyBlk;
  /* Try to expand the master using the newly freed chunk */
  if( mem3.iMaster ){
    while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){
      size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize;
      mem3.iMaster -= size;
      mem3.szMaster += size;
      memsys3Unlink(mem3.iMaster);
      x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
      mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
      mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
    }
    x = mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x & 2;
    while( (mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.size4x&1)==0 ){
      memsys3Unlink(mem3.iKeyBlk+mem3.szKeyBlk);
      mem3.szKeyBlk += mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.size4x/4;
      mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x = mem3.szKeyBlk*4 | x;
      mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.prevSize = mem3.szKeyBlk;
    x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
    while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){
      memsys3Unlink(mem3.iMaster+mem3.szMaster);
      mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4;
      mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
      mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
    }
  }
}

/*
** Return the size of an outstanding allocation, in bytes.  The
** size returned omits the 8-byte header overhead.  This only
556
557
558
559
560
561
562
563
564
565
566
567





568
569
570
571
572
573
574
556
557
558
559
560
561
562





563
564
565
566
567
568
569
570
571
572
573
574







-
-
-
-
-
+
+
+
+
+







  }

  /* Store a pointer to the memory block in global structure mem3. */
  assert( sizeof(Mem3Block)==8 );
  mem3.aPool = (Mem3Block *)sqlite3GlobalConfig.pHeap;
  mem3.nPool = (sqlite3GlobalConfig.nHeap / sizeof(Mem3Block)) - 2;

  /* Initialize the key block. */
  mem3.szKeyBlk = mem3.nPool;
  mem3.mnKeyBlk = mem3.szKeyBlk;
  mem3.iKeyBlk = 1;
  mem3.aPool[0].u.hdr.size4x = (mem3.szKeyBlk<<2) + 2;
  /* Initialize the master block. */
  mem3.szMaster = mem3.nPool;
  mem3.mnMaster = mem3.szMaster;
  mem3.iMaster = 1;
  mem3.aPool[0].u.hdr.size4x = (mem3.szMaster<<2) + 2;
  mem3.aPool[mem3.nPool].u.hdr.prevSize = mem3.nPool;
  mem3.aPool[mem3.nPool].u.hdr.size4x = 1;

  return SQLITE_OK;
}

/*
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
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







-
+




















-
-
-
+
+
+







      assert( 0 );
      break;
    }
    if( size&1 ){
      fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8);
    }else{
      fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8,
                  i==mem3.iKeyBlk ? " **key**" : "");
                  i==mem3.iMaster ? " **master**" : "");
    }
  }
  for(i=0; i<MX_SMALL-1; i++){
    if( mem3.aiSmall[i]==0 ) continue;
    fprintf(out, "small(%2d):", i);
    for(j = mem3.aiSmall[i]; j>0; j=mem3.aPool[j].u.list.next){
      fprintf(out, " %p(%d)", &mem3.aPool[j],
              (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
    }
    fprintf(out, "\n"); 
  }
  for(i=0; i<N_HASH; i++){
    if( mem3.aiHash[i]==0 ) continue;
    fprintf(out, "hash(%2d):", i);
    for(j = mem3.aiHash[i]; j>0; j=mem3.aPool[j].u.list.next){
      fprintf(out, " %p(%d)", &mem3.aPool[j],
              (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
    }
    fprintf(out, "\n"); 
  }
  fprintf(out, "key=%d\n", mem3.iKeyBlk);
  fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szKeyBlk*8);
  fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnKeyBlk*8);
  fprintf(out, "master=%d\n", mem3.iMaster);
  fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8);
  fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8);
  sqlite3_mutex_leave(mem3.mutex);
  if( out==stdout ){
    fflush(stdout);
  }else{
    fclose(out);
  }
#else

Changes to src/memdb.c.

122
123
124
125
126
127
128
129

130
131
132
133
134

135
136
137
138
139
140
141
142
143
122
123
124
125
126
127
128

129

130
131
132

133


134
135
136
137
138
139
140







-
+
-



-
+
-
-










/*
** Close an memdb-file.
**
** The pData pointer is owned by the application, so there is nothing
** to free.  Unless the SQLITE_DESERIALIZE_FREEONCLOSE flag is set,
** to free.
** in which case we own the pData pointer and need to free it.
*/
static int memdbClose(sqlite3_file *pFile){
  MemFile *p = (MemFile *)pFile;
  if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
  if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
    sqlite3_free(p->aData);
  }
  return SQLITE_OK;
}

/*
** Read data from an memdb-file.
*/
static int memdbRead(
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176







-
+







    return SQLITE_FULL;
  }
  if( newSz>p->szMax ){
    return SQLITE_FULL;
  }
  newSz *= 2;
  if( newSz>p->szMax ) newSz = p->szMax;
  pNew = sqlite3Realloc(p->aData, newSz);
  pNew = sqlite3_realloc64(p->aData, newSz);
  if( pNew==0 ) return SQLITE_NOMEM;
  p->aData = pNew;
  p->szAlloc = newSz;
  return SQLITE_OK;
}

/*
338
339
340
341
342
343
344
345

346
347
348
349
350

351
352
353
354
355
356
357
335
336
337
338
339
340
341

342
343
344
345
346

347
348
349
350
351
352
353
354







-
+




-
+







  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
    return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags);
  }
  memset(p, 0, sizeof(*p));
  p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
  assert( pOutFlags!=0 );  /* True because flags==SQLITE_OPEN_MAIN_DB */
  *pOutFlags = flags | SQLITE_OPEN_MEMORY;
  pFile->pMethods = &memdb_io_methods;
  p->base.pMethods = &memdb_io_methods;
  p->szMax = sqlite3GlobalConfig.mxMemdbSize;
  return SQLITE_OK;
}

#if 0 /* Only used to delete rollback journals, super-journals, and WAL
#if 0 /* Only used to delete rollback journals, master journals, and WAL
      ** files, none of which exist in memdb.  So this routine is never used */
/*
** Delete the file located at zPath. If the dirSync argument is true,
** ensure the file-system modifications are synced to disk before
** returning.
*/
static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
572
573
574
575
576
577
578
579
580
581
582
583


584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629



630
631

632
633
634
635
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







-
-
-
-
-
+
+
-














-












-
-
-












-
-
-
+
+
+
-
-
+




  if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
  iDb = sqlite3FindDbName(db, zSchema);
  if( iDb<0 ){
    rc = SQLITE_ERROR;
    goto end_deserialize;
  }    
  zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
  if( zSql==0 ){
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
    sqlite3_free(zSql);
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  sqlite3_free(zSql);
  }
  if( rc ) goto end_deserialize;
  db->init.iDb = (u8)iDb;
  db->init.reopenMemdb = 1;
  rc = sqlite3_step(pStmt);
  db->init.reopenMemdb = 0;
  if( rc!=SQLITE_DONE ){
    rc = SQLITE_ERROR;
    goto end_deserialize;
  }
  p = memdbFromDbSchema(db, zSchema);
  if( p==0 ){
    rc = SQLITE_ERROR;
  }else{
    p->aData = pData;
    pData = 0;
    p->sz = szDb;
    p->szAlloc = szBuf;
    p->szMax = szBuf;
    if( p->szMax<sqlite3GlobalConfig.mxMemdbSize ){
      p->szMax = sqlite3GlobalConfig.mxMemdbSize;
    }
    p->mFlags = mFlags;
    rc = SQLITE_OK;
  }

end_deserialize:
  sqlite3_finalize(pStmt);
  if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){
    sqlite3_free(pData);
  }
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

/* 
** This routine is called when the extension is loaded.
** Register the new VFS.
*/
int sqlite3MemdbInit(void){
  sqlite3_vfs *pLower = sqlite3_vfs_find(0);
  int sz = pLower->szOsFile;
  memdb_vfs.pAppData = pLower;
  /* The following conditional can only be true when compiled for
  ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0.  We always leave
  ** it in, to be safe, but it is marked as NO_TEST since there
  /* In all known configurations of SQLite, the size of a default
  ** sqlite3_file is greater than the size of a memdb sqlite3_file.
  ** Should that ever change, remove the following NEVER() */
  ** is no way to reach it under most builds. */
  if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
  if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
  memdb_vfs.szOsFile = sz;
  return sqlite3_vfs_register(&memdb_vfs, 0);
}
#endif /* SQLITE_ENABLE_DESERIALIZE */

Changes to src/memjournal.c.

66
67
68
69
70
71
72

73
74
75
76
77
78
79
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 */
91
92
93
94
95
96
97


98
99
100



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







+
+



+
+
+







){
  MemJournal *p = (MemJournal *)pJfd;
  u8 *zOut = zBuf;
  int nRead = iAmt;
  int iChunkOffset;
  FileChunk *pChunk;

#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
 || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
  if( (iAmt+iOfst)>p->endpoint.iOffset ){
    return SQLITE_IOERR_SHORT_READ;
  }
#endif

  assert( (iAmt+iOfst)<=p->endpoint.iOffset );
  assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
  if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
    sqlite3_int64 iOff = 0;
    for(pChunk=p->pFirst; 
        ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
        pChunk=pChunk->pNext
    ){
126
127
128
129
130
131
132
133

134
135
136

137
138
139

140
141
142
143
144
145
146
132
133
134
135
136
137
138

139
140
141

142
143
144
145
146
147
148
149
150
151
152
153







-
+


-
+



+








  return SQLITE_OK;
}

/*
** Free the list of FileChunk structures headed at MemJournal.pFirst.
*/
static void memjrnlFreeChunks(FileChunk *pFirst){
static void memjrnlFreeChunks(MemJournal *p){
  FileChunk *pIter;
  FileChunk *pNext;
  for(pIter=pFirst; pIter; pIter=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;
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180







-
+







      }
      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);
      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.  */
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
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;
      }
      p->nSize = iAmt + iOfst;
    }
  }

  return SQLITE_OK;
}

/*
** Truncate the in-memory file.
** 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;
  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;
  if( ALWAYS(size==0) ){
    memjrnlFreeChunks(p);
    p->nSize = 0;
    }
  }

  p->endpoint.pChunk = pIter;
  p->endpoint.iOffset = size;
  p->readpoint.pChunk = 0;
  p->readpoint.iOffset = 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->pFirst);
  memjrnlFreeChunks(p);
  return SQLITE_OK;
}

/*
** Sync the file.
**
** If the real file has been created, call its xSync method. Otherwise, 
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381







-
+







  if( nSpill>0 ){
    p->nChunkSize = nSpill;
  }else{
    p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk);
    assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) );
  }

  pJfd->pMethods = (const sqlite3_io_methods*)&MemJournalMethods;
  p->pMethod = (const sqlite3_io_methods*)&MemJournalMethods;
  p->nSpill = nSpill;
  p->flags = flags;
  p->zJournal = zName;
  p->pVfs = pVfs;
  return SQLITE_OK;
}

393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407







-
+







** in-memory-only journal file (i.e. is one that was opened with a +ve
** nSpill parameter or as SQLITE_OPEN_MAIN_JOURNAL), and the underlying 
** file has not yet been created, create it now.
*/
int sqlite3JournalCreate(sqlite3_file *pJfd){
  int rc = SQLITE_OK;
  MemJournal *p = (MemJournal*)pJfd;
  if( pJfd->pMethods==&MemJournalMethods && (
  if( p->pMethod==&MemJournalMethods && (
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
     p->nSpill>0
#else
     /* While this appears to not be possible without ATOMIC_WRITE, the
     ** paths are complex, so it seems prudent to leave the test in as
     ** a NEVER(), in case our analysis is subtly flawed. */
     NEVER(p->nSpill>0)

Changes to src/msvc.h.

29
30
31
32
33
34
35
36
37
38
39
40
41
29
30
31
32
33
34
35





36







-
-
-
-
-

#pragma warning(disable : 4244)
#pragma warning(disable : 4305)
#pragma warning(disable : 4306)
#pragma warning(disable : 4702)
#pragma warning(disable : 4706)
#endif /* defined(_MSC_VER) */

#if defined(_MSC_VER) && !defined(_WIN64)
#undef SQLITE_4_BYTE_ALIGNED_MALLOC
#define SQLITE_4_BYTE_ALIGNED_MALLOC
#endif /* defined(_MSC_VER) && !defined(_WIN64) */

#endif /* SQLITE_MSVC_H */

Changes to src/mutex.c.

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
250
251
252
253
254
255
256

257
258
259
260
261
262
263







-







  assert( sqlite3GlobalConfig.mutex.xMutexInit );
  rc = sqlite3GlobalConfig.mutex.xMutexInit();

#ifdef SQLITE_DEBUG
  GLOBAL(int, mutexIsInit) = 1;
#endif

  sqlite3MemoryBarrier();
  return rc;
}

/*
** Shutdown the mutex system. This call frees resources allocated by
** sqlite3MutexInit().
*/

Changes to src/mutex.h.

63
64
65
66
67
68
69
70
71
63
64
65
66
67
68
69

70







-

#define sqlite3_mutex_notheld(X)  ((void)(X),1)
#define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
#define sqlite3MutexInit()        SQLITE_OK
#define sqlite3MutexEnd()
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X)            X
int sqlite3_mutex_held(sqlite3_mutex*);
#endif /* defined(SQLITE_MUTEX_OMIT) */

Changes to src/mutex_unix.c.

108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122







-
+







** that means that a mutex could not be allocated.  SQLite
** will unwind its stack and return an error.  The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MAIN
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_OPEN
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_PMEM
** <li>  SQLITE_MUTEX_STATIC_APP1
** <li>  SQLITE_MUTEX_STATIC_APP2

Changes to src/mutex_w32.c.

167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181







-
+







** that means that a mutex could not be allocated.  SQLite
** will unwind its stack and return an error.  The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MAIN
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_OPEN
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_PMEM
** <li>  SQLITE_MUTEX_STATIC_APP1
** <li>  SQLITE_MUTEX_STATIC_APP2

Changes to src/notify.c.

25
26
27
28
29
30
31
32

33
34
35
36
37

38
39
40
41
42
43
44
25
26
27
28
29
30
31

32
33
34
35
36

37
38
39
40
41
42
43
44







-
+




-
+







**   sqlite3ConnectionBlocked()
**   sqlite3ConnectionUnlocked()
**   sqlite3ConnectionClosed()
**   sqlite3_unlock_notify()
*/

#define assertMutexHeld() \
  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)) )
  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) )

/*
** Head of a linked list of all sqlite3 objects created by this process
** for which either sqlite3.pBlockingConnection or sqlite3.pUnlockConnection
** is not NULL. This variable may only accessed while the STATIC_MAIN
** is not NULL. This variable may only accessed while the STATIC_MASTER
** mutex is held.
*/
static sqlite3 *SQLITE_WSD sqlite3BlockedList = 0;

#ifndef NDEBUG
/*
** This function is a complex assert() that verifies the following 
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
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







-
+


-
+




-
+




-
+







    pp=&(*pp)->pNextBlocked
  );
  db->pNextBlocked = *pp;
  *pp = db;
}

/*
** Obtain the STATIC_MAIN mutex.
** Obtain the STATIC_MASTER mutex.
*/
static void enterMutex(void){
  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN));
  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  checkListProperties(0);
}

/*
** Release the STATIC_MAIN mutex.
** Release the STATIC_MASTER mutex.
*/
static void leaveMutex(void){
  assertMutexHeld();
  checkListProperties(0);
  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN));
  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}

/*
** Register an unlock-notify callback.
**
** This is called after connection "db" has attempted some operation
** but has received an SQLITE_LOCKED error because another connection
228
229
230
231
232
233
234
235

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

235
236
237
238
239
240
241
242







-
+







  int nArg = 0;                            /* Number of entries in aArg[] */
  sqlite3 **pp;                            /* Iterator variable */
  void **aArg;               /* Arguments to the unlock callback */
  void **aDyn = 0;           /* Dynamically allocated space for aArg[] */
  void *aStatic[16];         /* Starter space for aArg[].  No malloc required */

  aArg = aStatic;
  enterMutex();         /* Enter STATIC_MAIN mutex */
  enterMutex();         /* Enter STATIC_MASTER mutex */

  /* This loop runs once for each entry in the blocked-connections list. */
  for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){
    sqlite3 *p = *pp;

    /* Step 1. */
    if( p->pBlockingConnection==db ){
311
312
313
314
315
316
317
318

319
320
321
322
323
324
325
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325







-
+







    }
  }

  if( nArg!=0 ){
    xUnlockNotify(aArg, nArg);
  }
  sqlite3_free(aDyn);
  leaveMutex();         /* Leave STATIC_MAIN mutex */
  leaveMutex();         /* Leave STATIC_MASTER mutex */
}

/*
** This is called when the database connection passed as an argument is 
** being closed. The connection is removed from the blocked list.
*/
void sqlite3ConnectionClosed(sqlite3 *db){

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
150
151
152
153
154
155
156
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
   && 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.
    ** 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);
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225







-
+







){
  int rc;
  DO_OS_MALLOC_TEST(0);
  /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
  ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
  ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
  ** reaching the VFS. */
  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut);
  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
  assert( rc==SQLITE_OK || pFile->pMethods==0 );
  return rc;
}
int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  DO_OS_MALLOC_TEST(0);
  assert( dirSync==0 || dirSync==1 );
  return pVfs->xDelete(pVfs, zPath, dirSync);
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
254
255
256
257
258
259
260







261


262
263
264
265
266
267
268







-
-
-
-
-
-
-
+
-
-







  return pVfs->xDlSym(pVfs, pHdle, zSym);
}
void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
  pVfs->xDlClose(pVfs, pHandle);
}
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
  if( sqlite3Config.iPrngSeed ){
    memset(zBufOut, 0, nByte);
    if( ALWAYS(nByte>(signed)sizeof(unsigned)) ) nByte = sizeof(unsigned int);
    memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte);
    return SQLITE_OK;
  }else{
    return pVfs->xRandomness(pVfs, nByte, zBufOut);
  return pVfs->xRandomness(pVfs, nByte, zBufOut);
  }
  
}
int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
  return pVfs->xSleep(pVfs, nMicro);
}
int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
  return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0;
}
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
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







-
+














-
+







  sqlite3_mutex *mutex;
#endif
#ifndef SQLITE_OMIT_AUTOINIT
  int rc = sqlite3_initialize();
  if( rc ) return 0;
#endif
#if SQLITE_THREADSAFE
  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
  sqlite3_mutex_enter(mutex);
  for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
    if( zVfs==0 ) break;
    if( strcmp(zVfs, pVfs->zName)==0 ) break;
  }
  sqlite3_mutex_leave(mutex);
  return pVfs;
}

/*
** Unlink a VFS from the linked list
*/
static void vfsUnlink(sqlite3_vfs *pVfs){
  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)) );
  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
  if( pVfs==0 ){
    /* No-op */
  }else if( vfsList==pVfs ){
    vfsList = pVfs->pNext;
  }else if( vfsList ){
    sqlite3_vfs *p = vfsList;
    while( p->pNext && p->pNext!=pVfs ){
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401







-
+







  int rc = sqlite3_initialize();
  if( rc ) return rc;
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
  if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
#endif

  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); )
  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  sqlite3_mutex_enter(mutex);
  vfsUnlink(pVfs);
  if( makeDflt || vfsList==0 ){
    pVfs->pNext = vfsList;
    vfsList = pVfs;
  }else{
    pVfs->pNext = vfsList->pNext;
426
427
428
429
430
431
432
433

434
435
436
437
438
411
412
413
414
415
416
417

418
419
420
421
422
423







-
+





*/
int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
  MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
  int rc = sqlite3_initialize();
  if( rc ) return rc;
#endif
  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); )
  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  sqlite3_mutex_enter(mutex);
  vfsUnlink(pVfs);
  sqlite3_mutex_leave(mutex);
  return SQLITE_OK;
}

Changes to src/os_unix.c.

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
101
102
103
104
105
106
107


















108
109
110
111





112
113
114

115
116
117
118
119
120
121







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








#if SQLITE_ENABLE_LOCKING_STYLE
# include <sys/ioctl.h>
# include <sys/file.h>
# include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */

/*
** Try to determine if gethostuuid() is available based on standard
** macros.  This might sometimes compute the wrong value for some
** obscure platforms.  For those cases, simply compile with one of
** the following:
**
**    -DHAVE_GETHOSTUUID=0
**    -DHAVE_GETHOSTUUID=1
**
** None if this matters except when building on Apple products with
** -DSQLITE_ENABLE_LOCKING_STYLE.
*/
#ifndef HAVE_GETHOSTUUID
# define HAVE_GETHOSTUUID 0
# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
                            (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
#    if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
        && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))\
#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
                           (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
#  if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
       && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
        && (!defined(TARGET_OS_MACCATALYST) || (TARGET_OS_MACCATALYST==0))
#      undef HAVE_GETHOSTUUID
#      define HAVE_GETHOSTUUID 1
#    else
#      warning "gethostuuid() is disabled."
#    define HAVE_GETHOSTUUID 1
#  else
#    warning "gethostuuid() is disabled."
#    endif
#  endif
#endif


#if OS_VXWORKS
# include <sys/ioctl.h>
# include <semaphore.h>
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
517
518
519
520
521
522
523

524
525

526
527
528
529
530
531
532
533
534
535
536
537







-


-




+







  { "lstat",         (sqlite3_syscall_ptr)0,              0 },
#endif
#define osLstat      ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)

#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
# ifdef __ANDROID__
  { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 },
#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
# else
  { "ioctl",         (sqlite3_syscall_ptr)ioctl,          0 },
#define osIoctl ((int(*)(int,unsigned long,...))aSyscall[28].pCurrent)
# endif
#else
  { "ioctl",         (sqlite3_syscall_ptr)0,              0 },
#endif
#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)

}; /* End of the overrideable system calls */


/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes.  So avoid calling fchown() if
686
687
688
689
690
691
692
693

694
695
696
697
698
699
700
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682







-
+







      break;
    }
    if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break;
    osClose(fd);
    sqlite3_log(SQLITE_WARNING, 
                "attempt to open \"%s\" as file descriptor %d", z, fd);
    fd = -1;
    if( osOpen("/dev/null", O_RDONLY, m)<0 ) break;
    if( osOpen("/dev/null", f, m)<0 ) break;
  }
  if( fd>=0 ){
    if( m!=0 ){
      struct stat statbuf;
      if( osFstat(fd, &statbuf)==0 
       && statbuf.st_size==0
       && (statbuf.st_mode&0777)!=m 
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1523
1524
1525
1526
1527
1528
1529



1530
1531
1532
1533
1534
1535
1536







-
-
-







  sqlite3_mutex_leave(pFile->pInode->pLockMutex);
  OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));

  *pResOut = reserved;
  return rc;
}

/* Forward declaration*/
static int unixSleep(sqlite3_vfs*,int);

/*
** Set a posix-advisory-lock.
**
** There are two versions of this routine.  If compiled with
** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter
** which is a pointer to a unixFile.  If the unixFile->iBusyTimeout
** value is set, then it is the number of milliseconds to wait before
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574

1575
1576
1577
1578
1579
1580

1581
1582

1583
1584
1585
1586
1587
1588
1589
1544
1545
1546
1547
1548
1549
1550

1551

1552
1553
1554
1555
1556
1557

1558
1559

1560
1561
1562
1563
1564
1565
1566
1567







-

-
+





-
+

-
+







# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
#else
static int osSetPosixAdvisoryLock(
  int h,                /* The file descriptor on which to take the lock */
  struct flock *pLock,  /* The description of the lock */
  unixFile *pFile       /* Structure holding timeout value */
){
  int tm = pFile->iBusyTimeout;
  int rc = osFcntl(h,F_SETLK,pLock);
  while( rc<0 && tm>0 ){
  while( rc<0 && pFile->iBusyTimeout>0 ){
    /* On systems that support some kind of blocking file lock with a timeout,
    ** make appropriate changes here to invoke that blocking file lock.  On
    ** generic posix, however, there is no such API.  So we simply try the
    ** lock once every millisecond until either the timeout expires, or until
    ** the lock is obtained. */
    unixSleep(0,1000);
    usleep(1000);
    rc = osFcntl(h,F_SETLK,pLock);
    tm--;
    pFile->iBusyTimeout--;
  }
  return rc;
}
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */


/*
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2122
2123
2124
2125
2126
2127
2128

2129
2130
2131
2132
2133
2134
2135







-







    ** descriptor to pInode->pUnused list.  It will be automatically closed 
    ** when the last lock is cleared.
    */
    setPendingFd(pFile);
  }
  sqlite3_mutex_leave(pInode->pLockMutex);
  releaseInodeInfo(pFile);
  assert( pFile->pShm==0 );
  rc = closeUnixFile(id);
  unixLeaveMutex();
  return rc;
}

/************** End of the posix advisory lock implementation *****************
******************************************************************************/
3341
3342
3343
3344
3345
3346
3347
3348

3349
3350
3351
3352
3353
3354
3355
3318
3319
3320
3321
3322
3323
3324

3325
3326
3327
3328
3329
3330
3331
3332







-
+







){
  unixFile *pFile = (unixFile *)id;
  int got;
  assert( id );
  assert( offset>=0 );
  assert( amt>0 );

  /* If this is a database file (not a journal, super-journal or temp
  /* If this is a database file (not a journal, master-journal or temp
  ** file), the bytes in the locking range should never be read or written. */
#if 0
  assert( pFile->pPreallocatedUnused==0
       || offset>=PENDING_BYTE+512
       || offset+amt<=PENDING_BYTE 
  );
#endif
3371
3372
3373
3374
3375
3376
3377
3378

3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3348
3349
3350
3351
3352
3353
3354

3355

















3356
3357
3358
3359
3360
3361
3362







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







  }
#endif

  got = seekAndRead(pFile, offset, pBuf, amt);
  if( got==amt ){
    return SQLITE_OK;
  }else if( got<0 ){
    /* pFile->lastErrno has been set by seekAndRead().
    /* lastErrno set by seekAndRead */
    ** Usually we return SQLITE_IOERR_READ here, though for some
    ** kinds of errors we return SQLITE_IOERR_CORRUPTFS.  The
    ** SQLITE_IOERR_CORRUPTFS will be converted into SQLITE_CORRUPT
    ** prior to returning to the application by the sqlite3ApiExit()
    ** routine.
    */
    switch( pFile->lastErrno ){
      case ERANGE:
      case EIO:
#ifdef ENXIO
      case ENXIO:
#endif
#ifdef EDEVERR
      case EDEVERR:
#endif
        return SQLITE_IOERR_CORRUPTFS;
    }
    return SQLITE_IOERR_READ;
  }else{
    storeLastErrno(pFile, 0);   /* not a system error */
    /* Unread parts of the buffer must be zero-filled */
    memset(&((char*)pBuf)[got], 0, amt-got);
    return SQLITE_IOERR_SHORT_READ;
  }
3471
3472
3473
3474
3475
3476
3477
3478

3479
3480
3481
3482
3483
3484
3485
3431
3432
3433
3434
3435
3436
3437

3438
3439
3440
3441
3442
3443
3444
3445







-
+







  sqlite3_int64 offset 
){
  unixFile *pFile = (unixFile*)id;
  int wrote = 0;
  assert( id );
  assert( amt>0 );

  /* If this is a database file (not a journal, super-journal or temp
  /* If this is a database file (not a journal, master-journal or temp
  ** file), the bytes in the locking range should never be read or written. */
#if 0
  assert( pFile->pPreallocatedUnused==0
       || offset>=PENDING_BYTE+512
       || offset+amt<=PENDING_BYTE 
  );
#endif
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
3974
3975
3976
3977
3978
3979
3980

3981

3982
3983
3984
3985
3986
3987
3988







-

-







    }
    case SQLITE_FCNTL_HAS_MOVED: {
      *(int*)pArg = fileHasMoved(pFile);
      return SQLITE_OK;
    }
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
    case SQLITE_FCNTL_LOCK_TIMEOUT: {
      int iOld = pFile->iBusyTimeout;
      pFile->iBusyTimeout = *(int*)pArg;
      *(int*)pArg = iOld;
      return SQLITE_OK;
    }
#endif
#if SQLITE_MAX_MMAP_SIZE>0
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4230
4231
4232
4233
4234
4235
4236

4237
4238
4239
4240
4241
4242
4243







-







  int szRegion;              /* Size of shared-memory regions */
  u16 nRegion;               /* Size of array apRegion */
  u8 isReadonly;             /* True if read-only */
  u8 isUnlocked;             /* True if no DMS lock held */
  char **apRegion;           /* Array of mapped shared-memory regions */
  int nRef;                  /* Number of unixShm objects pointing to this */
  unixShm *pFirst;           /* All unixShm objects pointing to this */
  int aLock[SQLITE_SHM_NLOCK];  /* # shared locks on slot, -1==excl lock */
#ifdef SQLITE_DEBUG
  u8 exclMask;               /* Mask of exclusive locks held */
  u8 sharedMask;             /* Mask of shared locks held */
  u8 nextShmId;              /* Next available unixShm.id value */
#endif
};

4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349

4350
4351
4352
4353
4354

4355
4356
4357
4358
4359
4360
4361
4362
4363
4293
4294
4295
4296
4297
4298
4299

4300
4301
4302
4303
4304

4305





4306


4307
4308
4309
4310
4311
4312
4313







-





-
+
-
-
-
-
-
+
-
-







  /* Shared locks never span more than one byte */
  assert( n==1 || lockType!=F_RDLCK );

  /* Locks are within range */
  assert( n>=1 && n<=SQLITE_SHM_NLOCK );

  if( pShmNode->hShm>=0 ){
    int res;
    /* Initialize the locking parameters */
    f.l_type = lockType;
    f.l_whence = SEEK_SET;
    f.l_start = ofst;
    f.l_len = n;
    res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
    rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
    if( res==-1 ){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
      rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
#else
      rc = SQLITE_BUSY;
    rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
#endif
    }
  }

  /* Update the global lock state and do debug tracing */
#ifdef SQLITE_DEBUG
  { u16 mask;
  OSTRACE(("SHM-LOCK "));
  mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
4605
4606
4607
4608
4609
4610
4611
4612

4613
4614
4615
4616

4617
4618
4619
4620
4621
4622
4623
4624
4555
4556
4557
4558
4559
4560
4561

4562

4563
4564

4565

4566
4567
4568
4569
4570
4571
4572







-
+
-


-
+
-







        rc = SQLITE_NOMEM_BKPT;
        goto shm_open_err;
      }
    }

    if( pInode->bProcessLock==0 ){
      if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
        pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
        pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
                                     (sStat.st_mode&0777));
      }
      if( pShmNode->hShm<0 ){
        pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW,
        pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
                                     (sStat.st_mode&0777));
        if( pShmNode->hShm<0 ){
          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
          goto shm_open_err;
        }
        pShmNode->isReadonly = 1;
      }

4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867

4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914

4915

4916
4917
4918
4919
4920
4921
4922
4923
4924











4925
4926

4927
4928
4929
4930

4931
4932
4933
4934
4935
4936
4937
4938
4939













4940
4941

4942
4943




4944




4945


4946
4947
4948
4949
4950





4951
4952
4953
4954
4955
4956

4957
4958
4959



4960
4961
4962
4963
4964
4965
4966
4967




4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
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
4877
4878
4879
4880
4881
4882







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
















+



-













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



-

-
-
-
+

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

+
+
+
+
-
+
+
+
+

+
+

-
-
-
-
+
+
+
+
+
-
-



-
+
-
-
-
+
+
+
-




-
-
-
+
+
+
+





-
-
-



-







    *pp = 0;
  }
  if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
  sqlite3_mutex_leave(pShmNode->pShmMutex);
  return rc;
}

/*
** Check that the pShmNode->aLock[] array comports with the locking bitmasks
** held by each client. Return true if it does, or false otherwise. This
** is to be used in an assert(). e.g.
**
**     assert( assertLockingArrayOk(pShmNode) );
*/
#ifdef SQLITE_DEBUG
static int assertLockingArrayOk(unixShmNode *pShmNode){
  unixShm *pX;
  int aLock[SQLITE_SHM_NLOCK];
  assert( sqlite3_mutex_held(pShmNode->pShmMutex) );

  memset(aLock, 0, sizeof(aLock));
  for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
    int i;
    for(i=0; i<SQLITE_SHM_NLOCK; i++){
      if( pX->exclMask & (1<<i) ){
        assert( aLock[i]==0 );
        aLock[i] = -1;
      }else if( pX->sharedMask & (1<<i) ){
        assert( aLock[i]>=0 );
        aLock[i]++;
      }
    }
  }

  assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
  return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
}
#endif

/*
** Change the lock state for a shared-memory segment.
**
** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
** different here than in posix.  In xShmLock(), one can go from unlocked
** to shared and back or from unlocked to exclusive and back.  But one may
** not go from shared to exclusive or from exclusive to shared.
*/
static int unixShmLock(
  sqlite3_file *fd,          /* Database file holding the shared memory */
  int ofst,                  /* First lock to acquire or release */
  int n,                     /* Number of locks to acquire or release */
  int flags                  /* What to do with the lock */
){
  unixFile *pDbFd = (unixFile*)fd;      /* Connection holding shared memory */
  unixShm *p = pDbFd->pShm;             /* The shared memory being locked */
  unixShm *pX;                          /* For looping over all siblings */
  unixShmNode *pShmNode = p->pShmNode;  /* The underlying file iNode */
  int rc = SQLITE_OK;                   /* Result code */
  u16 mask;                             /* Mask of locks to take or release */
  int *aLock = pShmNode->aLock;

  assert( pShmNode==pDbFd->pInode->pShmNode );
  assert( pShmNode->pInode==pDbFd->pInode );
  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
  assert( n>=1 );
  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
  assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
  assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );

  /* Check that, if this to be a blocking lock, no locks that occur later
  ** in the following list than the lock being obtained are already held:
  **
  **   1. Checkpointer lock (ofst==1).
  **   2. Write lock (ofst==0).
  **   3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
  **
  ** In other words, if this is a blocking lock, none of the locks that
  ** occur later in the above list than the lock being obtained may be
  ** held.  
  **
  ** It is not permitted to block on the RECOVER lock.
  */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
  assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
         (ofst!=2)                                   /* not RECOVER */
      && (ofst!=1 || (p->exclMask|p->sharedMask)==0)
      && (ofst!=0 || (p->exclMask|p->sharedMask)<3)
      && (ofst<3  || (p->exclMask|p->sharedMask)<(1<<ofst))
  ));
#endif

  mask = (1<<(ofst+n)) - (1<<ofst);
  assert( n>1 || mask==(1<<ofst) );
  sqlite3_mutex_enter(pShmNode->pShmMutex);
  assert( assertLockingArrayOk(pShmNode) );
  if( flags & SQLITE_SHM_UNLOCK ){
    if( (p->exclMask|p->sharedMask) & mask ){
      int ii;
      int bUnlock = 1;
    u16 allMask = 0; /* Mask of locks held by siblings */

    /* See if any siblings hold this same lock */
      for(ii=ofst; ii<ofst+n; ii++){
        if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){
          bUnlock = 0;
        }
      }

      if( bUnlock ){
        rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
        if( rc==SQLITE_OK ){
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
      if( pX==p ) continue;
      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
      allMask |= pX->sharedMask;
    }

    /* Unlock the system-level locks */
    if( (mask & allMask)==0 ){
      rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
    }else{
      rc = SQLITE_OK;
          memset(&aLock[ofst], 0, sizeof(int)*n);
        }
    }
      }else if( ALWAYS(p->sharedMask & (1<<ofst)) ){
        assert( n==1 && aLock[ofst]>1 );
        aLock[ofst]--;
      }


      /* Undo the local locks */
      if( rc==SQLITE_OK ){
        p->exclMask &= ~mask;
        p->sharedMask &= ~mask;
      } 
    }
  }else if( flags & SQLITE_SHM_SHARED ){
    assert( n==1 );
    /* Undo the local locks */
    if( rc==SQLITE_OK ){
      p->exclMask &= ~mask;
      p->sharedMask &= ~mask;
    } 
  }else if( flags & SQLITE_SHM_SHARED ){
    u16 allShared = 0;  /* Union of locks held by connections other than "p" */

    /* Find out which shared locks are already held by sibling connections.
    ** If any sibling already holds an exclusive lock, go ahead and return
    ** SQLITE_BUSY.
    */
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
    assert( (p->exclMask & (1<<ofst))==0 );
    if( (p->sharedMask & mask)==0 ){
      if( (pX->exclMask & mask)!=0 ){
      if( aLock[ofst]<0 ){
        rc = SQLITE_BUSY;
        break;
      }
      allShared |= pX->sharedMask;
    }
      }else if( aLock[ofst]==0 ){

    /* Get shared locks at the system level, if necessary */
    if( rc==SQLITE_OK ){
      if( (allShared & mask)==0 ){
        rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
      }else{
        rc = SQLITE_OK;
      }

      /* Get the local shared locks */
      if( rc==SQLITE_OK ){
        p->sharedMask |= mask;
    }

    /* Get the local shared locks */
    if( rc==SQLITE_OK ){
      p->sharedMask |= mask;
        aLock[ofst]++;
      }
    }
  }else{
    /* Make sure no sibling connections hold locks that will block this
    ** lock.  If any do, return SQLITE_BUSY right away.  */
    ** lock.  If any do, return SQLITE_BUSY right away.
    int ii;
    for(ii=ofst; ii<ofst+n; ii++){
      assert( (p->sharedMask & mask)==0 );
    */
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
      if( ALWAYS((p->exclMask & (1<<ii))==0) && aLock[ii] ){
        rc = SQLITE_BUSY;
        break;
      }
    }

    /* Get the exclusive locks at the system level. Then if successful
    ** also update the in-memory values. */
  
    /* Get the exclusive locks at the system level.  Then if successful
    ** also mark the local connection as being locked.
    */
    if( rc==SQLITE_OK ){
      rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
      if( rc==SQLITE_OK ){
        assert( (p->sharedMask & mask)==0 );
        p->exclMask |= mask;
        for(ii=ofst; ii<ofst+n; ii++){
          aLock[ii] = -1;
        }
      }
    }
  }
  assert( assertLockingArrayOk(pShmNode) );
  sqlite3_mutex_leave(pShmNode->pShmMutex);
  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
           p->id, osGetpid(0), p->sharedMask, p->exclMask));
  return rc;
}

/*
5741
5742
5743
5744
5745
5746
5747
5748

5749
5750
5751
5752
5753
5754
5755
5637
5638
5639
5640
5641
5642
5643

5644
5645
5646
5647
5648
5649
5650
5651







-
+







    osUnlink(zFilename);
    pNew->ctrlFlags |= UNIXFILE_DELETE;
  }
#endif
  if( rc!=SQLITE_OK ){
    if( h>=0 ) robust_close(pNew, h, __LINE__);
  }else{
    pId->pMethods = pLockingStyle;
    pNew->pMethod = pLockingStyle;
    OpenCounter(+1);
    verifyDbFile(pNew);
  }
  return rc;
}

/*
5822
5823
5824
5825
5826
5827
5828
5829

5830
5831
5832
5833
5834
5835
5836
5718
5719
5720
5721
5722
5723
5724

5725
5726
5727
5728
5729
5730
5731
5732







-
+







** if SQLITE_PREFER_PROXY_LOCKING is defined.
*/
static int proxyTransformUnixFile(unixFile*, const char*);
#endif

/*
** Search for an unused file descriptor that was opened on the database 
** file (not a journal or super-journal file) identified by pathname
** file (not a journal or master-journal file) identified by pathname
** zPath with SQLITE_OPEN_XXX flags matching those passed as the second
** argument to this function.
**
** Such a file descriptor may exist if a database connection was closed
** but the associated file descriptor could not be closed because some
** other file descriptor open on the same file is holding a file-lock.
** Refer to comments in the unixClose() function and the lengthy comment
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5765
5766
5767
5768
5769
5770
5771

5772
5773
5774
5775
5776
5777
5778







-







                     || pInode->fileId.ino!=(u64)sStat.st_ino) ){
       pInode = pInode->pNext;
    }
    if( pInode ){
      UnixUnusedFd **pp;
      assert( sqlite3_mutex_notheld(pInode->pLockMutex) );
      sqlite3_mutex_enter(pInode->pLockMutex);
      flags &= (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE);
      for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
      pUnused = *pp;
      if( pUnused ){
        *pp = pUnused->pNext;
      }
      sqlite3_mutex_leave(pInode->pLockMutex);
    }
5923
5924
5925
5926
5927
5928
5929
5930

5931
5932
5933
5934
5935
5936
5937
5818
5819
5820
5821
5822
5823
5824

5825
5826
5827
5828
5829
5830
5831
5832







-
+







** corresponding database file and sets *pMode to this value. Whenever 
** possible, WAL and journal files are created using the same permissions 
** as the associated database file.
**
** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
** original filename is unavailable.  But 8_3_NAMES is only used for
** FAT filesystems and permissions do not matter there, so just use
** the default permissions.  In 8_3_NAMES mode, leave *pMode set to zero.
** the default permissions.
*/
static int findCreateFileMode(
  const char *zPath,              /* Path of file (possibly) being created */
  int flags,                      /* Flags passed as 4th argument to xOpen() */
  mode_t *pMode,                  /* OUT: Permissions to open file with */
  uid_t *pUid,                    /* OUT: uid to set on the file */
  gid_t *pGid                     /* OUT: gid to set on the file */
5956
5957
5958
5959
5960
5961
5962
5963

5964
5965
5966
5967
5968
5969
5970
5851
5852
5853
5854
5855
5856
5857

5858
5859
5860
5861
5862
5863
5864
5865







-
+







    ** where NN is a decimal number. The NN naming schemes are 
    ** used by the test_multiplex.c module.
    */
    nDb = sqlite3Strlen30(zPath) - 1; 
    while( zPath[nDb]!='-' ){
      /* In normal operation, the journal file name will always contain
      ** a '-' character.  However in 8+3 filename mode, or if a corrupt
      ** rollback journal specifies a super-journal with a goofy name, then
      ** rollback journal specifies a master journal with a goofy name, then
      ** the '-' might be missing. */
      if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
      nDb--;
    }
    memcpy(zDb, zPath, nDb);
    zDb[nDb] = '\0';

6012
6013
6014
6015
6016
6017
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
5907
5908
5909
5910
5911
5912
5913

5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930

5931
5932
5933
5934
5935

5936
5937
5938
5939
5940
5941
5942
5943







-
+
















-
+




-
+







  sqlite3_file *pFile,         /* The file descriptor to be filled in */
  int flags,                   /* Input flags to control the opening */
  int *pOutFlags               /* Output flags returned to SQLite core */
){
  unixFile *p = (unixFile *)pFile;
  int fd = -1;                   /* File descriptor returned by open() */
  int openFlags = 0;             /* Flags to pass to open() */
  int eType = flags&0x0FFF00;  /* Type of file to open */
  int eType = flags&0xFFFFFF00;  /* Type of file to open */
  int noLock;                    /* True to omit locking primitives */
  int rc = SQLITE_OK;            /* Function Return Code */
  int ctrlFlags = 0;             /* UNIXFILE_* flags */

  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
  int isCreate     = (flags & SQLITE_OPEN_CREATE);
  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
#if SQLITE_ENABLE_LOCKING_STYLE
  int isAutoProxy  = (flags & SQLITE_OPEN_AUTOPROXY);
#endif
#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
  struct statfs fsInfo;
#endif

  /* If creating a super- or main-file journal, this function will open
  /* If creating a master or main-file journal, this function will open
  ** a file-descriptor on the directory too. The first time unixSync()
  ** is called the directory file descriptor will be fsync()ed and close()d.
  */
  int isNewJrnl = (isCreate && (
        eType==SQLITE_OPEN_SUPER_JOURNAL 
        eType==SQLITE_OPEN_MASTER_JOURNAL 
     || eType==SQLITE_OPEN_MAIN_JOURNAL 
     || eType==SQLITE_OPEN_WAL
  ));

  /* If argument zPath is a NULL pointer, this function is required to open
  ** a temporary file. Use this buffer to store the file name in.
  */
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
5952
5953
5954
5955
5956
5957
5958

5959
5960
5961
5962

5963
5964
5965
5966
5967
5968

5969
5970
5971
5972
5973
5974
5975
5976







-
+



-
+





-
+







  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
  */
  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
  assert(isCreate==0 || isReadWrite);
  assert(isExclusive==0 || isCreate);
  assert(isDelete==0 || isCreate);

  /* The main DB, main journal, WAL file and super-journal are never 
  /* The main DB, main journal, WAL file and master journal are never 
  ** automatically deleted. Nor are they ever temporary files.  */
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_SUPER_JOURNAL );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );

  /* Assert that the upper layer has set one of the "file-type" flags. */
  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB 
       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 
       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_SUPER_JOURNAL 
       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
  );

  /* Detect a pid change and reset the PRNG.  There is a race condition
  ** here such that two or more threads all trying to open databases at
  ** the same instant might all reset the PRNG.  But multiple resets
  ** are harmless.
6122
6123
6124
6125
6126
6127
6128
6129

6130
6131
6132
6133
6134
6135
6136
6017
6018
6019
6020
6021
6022
6023

6024
6025
6026
6027
6028
6029
6030
6031







-
+







  ** open(). These must be calculated even if open() is not called, as
  ** they may be stored as part of the file handle and used by the 
  ** 'conch file' locking functions later on.  */
  if( isReadonly )  openFlags |= O_RDONLY;
  if( isReadWrite ) openFlags |= O_RDWR;
  if( isCreate )    openFlags |= O_CREAT;
  if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
  openFlags |= (O_LARGEFILE|O_BINARY|O_NOFOLLOW);
  openFlags |= (O_LARGEFILE|O_BINARY);

  if( fd<0 ){
    mode_t openMode;              /* Permissions to create file with */
    uid_t uid;                    /* Userid for the file */
    gid_t gid;                    /* Groupid for the file */
    rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
    if( rc!=SQLITE_OK ){
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
6053
6054
6055
6056
6057
6058
6059
6060


6061
6062









6063

6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074

6075

6076
6077
6078
6079
6080
6081
6082







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

-
+










-
+
-







    }
    if( fd<0 ){
      int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
      if( rc==SQLITE_OK ) rc = rc2;
      goto open_finished;
    }

    /* If this process is running as root and if creating a new rollback
    /* The owner of the rollback journal or WAL file should always be the
    ** same as the owner of the database file.  Try to ensure that this is
    ** journal or WAL file, set the ownership of the journal or WAL to be
    ** the same as the original database.
    ** the case.  The chown() system call will be a no-op if the current
    ** process lacks root privileges, be we should at least try.  Without
    ** this step, if a root process opens a database file, it can leave
    ** behinds a journal/WAL that is owned by root and hence make the
    ** database inaccessible to unprivileged processes.
    **
    ** If openMode==0, then that means uid and gid are not set correctly
    ** (probably because SQLite is configured to use 8+3 filename mode) and
    ** in that case we do not want to attempt the chown().
    */
    if( openMode && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL))!=0 ){
    if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
      robustFchown(fd, uid, gid);
    }
  }
  assert( fd>=0 );
  if( pOutFlags ){
    *pOutFlags = flags;
  }

  if( p->pPreallocatedUnused ){
    p->pPreallocatedUnused->fd = fd;
    p->pPreallocatedUnused->flags = 
    p->pPreallocatedUnused->flags = flags;
                          flags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE);
  }

  if( isDelete ){
#if OS_VXWORKS
    zPath = zName;
#elif defined(SQLITE_UNLINK_AFTER_CLOSE)
    zPath = sqlite3_mprintf("%s", zName);
6260
6261
6262
6263
6264
6265
6266
6267

6268
6269
6270
6271
6272
6273
6274
6146
6147
6148
6149
6150
6151
6152

6153
6154
6155
6156
6157
6158
6159
6160







-
+







      }
      goto open_finished;
    }
  }
#endif
  
  assert( zPath==0 || zPath[0]=='/' 
      || eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL 
      || eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL 
  );
  rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);

open_finished:
  if( rc!=SQLITE_OK ){
    sqlite3_free(p->pPreallocatedUnused);
  }
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
6437
6438
6439
6440
6441
6226
6227
6228
6229
6230
6231
6232

6233

6234
6235
6236
6237
6238
6239
6240


















6241


6242
6243
6244
6245
6246
6247
6248
6249

6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263



































6264
6265
6266
6267
6268
6269
6270







-
+
-







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

-
-








-














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








  /* The spec says there are three possible values for flags.  But only
  ** two of them are actually used */
  assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );

  if( flags==SQLITE_ACCESS_EXISTS ){
    struct stat buf;
    *pResOut = 0==osStat(zPath, &buf) &&
    *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
                (!S_ISREG(buf.st_mode) || buf.st_size>0);
  }else{
    *pResOut = osAccess(zPath, W_OK|R_OK)==0;
  }
  return SQLITE_OK;
}

/*
** If the last component of the pathname in z[0]..z[j-1] is something
** other than ".." then back it out and return true.  If the last
** component is empty or if it is ".." then return false.
*/
static int unixBackupDir(const char *z, int *pJ){
  int j = *pJ;
  int i;
  if( j<=0 ) return 0;
  for(i=j-1; i>0 && z[i-1]!='/'; i--){}
  if( i==0 ) return 0;
  if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0;
  *pJ = i-1;
  return 1;
}

/*
** Convert a relative pathname into a full pathname.  Also
** simplify the pathname as follows:
**
**    Remove all instances of /./
**    Remove all isntances of /X/../ for any X
*/
static int mkFullPathname(
  const char *zPath,              /* Input path */
  char *zOut,                     /* Output buffer */
  int nOut                        /* Allocated size of buffer zOut */
){
  int nPath = sqlite3Strlen30(zPath);
  int iOff = 0;
  int i, j;
  if( zPath[0]!='/' ){
    if( osGetcwd(zOut, nOut-2)==0 ){
      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
    }
    iOff = sqlite3Strlen30(zOut);
    zOut[iOff++] = '/';
  }
  if( (iOff+nPath+1)>nOut ){
    /* SQLite assumes that xFullPathname() nul-terminates the output buffer
    ** even if it returns an error.  */
    zOut[iOff] = '\0';
    return SQLITE_CANTOPEN_BKPT;
  }
  sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);

  /* Remove duplicate '/' characters.  Except, two // at the beginning
  ** of a pathname is allowed since this is important on windows. */
  for(i=j=1; zOut[i]; i++){
    zOut[j++] = zOut[i];
    while( zOut[i]=='/' && zOut[i+1]=='/' ) i++;
  }
  zOut[j] = 0;

  assert( zOut[0]=='/' );
  for(i=j=0; zOut[i]; i++){
    if( zOut[i]=='/' ){
      /* Skip over internal "/." directory components */
      if( zOut[i+1]=='.' && zOut[i+2]=='/' ){
        i += 1;
        continue;
      }

      /* If this is a "/.." directory component then back out the
      ** previous term of the directory if it is something other than "..".
      */
      if( zOut[i+1]=='.'
       && zOut[i+2]=='.'
       && zOut[i+3]=='/'
       && unixBackupDir(zOut, &j)
      ){
        i += 2;
        continue;
      }
    }
    if( ALWAYS(j>=0) ) zOut[j] = zOut[i];
    j++;
  }
  if( NEVER(j==0) ) zOut[j++] = '/';
  zOut[j] = 0;
  return SQLITE_OK;
}

/*
** Turn a relative pathname into a full pathname. The relative path
** is stored as a nul-terminated string in the buffer pointed to by
** zPath. 
6451
6452
6453
6454
6455
6456
6457
6458

6459
6460
6461
6462
6463
6464
6465
6280
6281
6282
6283
6284
6285
6286

6287
6288
6289
6290
6291
6292
6293
6294







-
+







  char *zOut                    /* Output buffer */
){
#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
  return mkFullPathname(zPath, zOut, nOut);
#else
  int rc = SQLITE_OK;
  int nByte;
  int nLink = 0;                /* Number of symbolic links followed so far */
  int nLink = 1;                /* Number of symbolic links followed so far */
  const char *zIn = zPath;      /* Input path for each iteration of loop */
  char *zDel = 0;

  assert( pVfs->mxPathname==MAX_PATHNAME );
  UNUSED_PARAMETER(pVfs);

  /* It's odd to simulate an io-error here, but really this is just
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491

6492
6493
6494
6495
6496
6497
6498
6309
6310
6311
6312
6313
6314
6315

6316
6317
6318

6319
6320
6321
6322
6323
6324
6325
6326







-



-
+







        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
      }
    }else{
      bLink = S_ISLNK(buf.st_mode);
    }

    if( bLink ){
      nLink++;
      if( zDel==0 ){
        zDel = sqlite3_malloc(nOut);
        if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
      }else if( nLink>=SQLITE_MAX_SYMLINKS ){
      }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
        rc = SQLITE_CANTOPEN_BKPT;
      }

      if( rc==SQLITE_OK ){
        nByte = osReadlink(zIn, zDel, nOut-1);
        if( nByte<0 ){
          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6348
6349
6350
6351
6352
6353
6354

6355
6356
6357
6358
6359
6360
6361







-







      rc = mkFullPathname(zIn, zOut, nOut);
    }
    if( bLink==0 ) break;
    zIn = zOut;
  }while( rc==SQLITE_OK );

  sqlite3_free(zDel);
  if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
  return rc;
#endif   /* HAVE_READLINK && HAVE_LSTAT */
}


#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
6648
6649
6650
6651
6652
6653
6654
6655
6656

6657
6658
6659
6660
6661
6662
6663
6475
6476
6477
6478
6479
6480
6481


6482
6483
6484
6485
6486
6487
6488
6489







-
-
+








  sp.tv_sec = microseconds / 1000000;
  sp.tv_nsec = (microseconds % 1000000) * 1000;
  nanosleep(&sp, NULL);
  UNUSED_PARAMETER(NotUsed);
  return microseconds;
#elif defined(HAVE_USLEEP) && HAVE_USLEEP
  if( microseconds>=1000000 ) sleep(microseconds/1000000);
  if( microseconds%1000000 ) usleep(microseconds%1000000);
  usleep(microseconds);
  UNUSED_PARAMETER(NotUsed);
  return microseconds;
#else
  int seconds = (microseconds+999999)/1000000;
  sleep(seconds);
  UNUSED_PARAMETER(NotUsed);
  return seconds*1000000;
7007
7008
7009
7010
7011
7012
7013
7014

7015
7016
7017
7018
7019
7020
7021
6833
6834
6835
6836
6837
6838
6839

6840
6841
6842
6843
6844
6845
6846
6847







-
+







    const char *path,        /* path for the new unixFile */
    unixFile **ppFile,       /* unixFile created and returned by ref */
    int islockfile           /* if non zero missing dirs will be created */
) {
  int fd = -1;
  unixFile *pNew;
  int rc = SQLITE_OK;
  int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW;
  int openFlags = O_RDWR | O_CREAT;
  sqlite3_vfs dummyVfs;
  int terrno = 0;
  UnixUnusedFd *pUnused = NULL;

  /* 1. first try to open/create the file
  ** 2. if that fails, and this is a lock file (not-conch), try creating
  ** the parent directories and then try again.
7037
7038
7039
7040
7041
7042
7043
7044

7045
7046
7047
7048
7049
7050
7051
6863
6864
6865
6866
6867
6868
6869

6870
6871
6872
6873
6874
6875
6876
6877







-
+







    if( fd<0 && errno==ENOENT && islockfile ){
      if( proxyCreateLockPath(path) == SQLITE_OK ){
        fd = robust_open(path, openFlags, 0);
      }
    }
  }
  if( fd<0 ){
    openFlags = O_RDONLY | O_NOFOLLOW;
    openFlags = O_RDONLY;
    fd = robust_open(path, openFlags, 0);
    terrno = errno;
  }
  if( fd<0 ){
    if( islockfile ){
      return SQLITE_BUSY;
    }
7088
7089
7090
7091
7092
7093
7094
7095

7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106

7107
7108
7109
7110
7111
7112
7113
6914
6915
6916
6917
6918
6919
6920

6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931

6932
6933
6934
6935
6936
6937
6938
6939







-
+










-
+







#ifdef SQLITE_TEST
/* simulate multiple hosts by creating unique hostid file paths */
int sqlite3_hostid_num = 0;
#endif

#define PROXY_HOSTIDLEN    16  /* conch file host id length */

#if HAVE_GETHOSTUUID
#ifdef HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
#endif

/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN 
** bytes of writable memory.
*/
static int proxyGetHostID(unsigned char *pHostID, int *pError){
  assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
  memset(pHostID, 0, PROXY_HOSTIDLEN);
#if HAVE_GETHOSTUUID
#ifdef HAVE_GETHOSTUUID
  {
    struct timespec timeout = {1, 0}; /* 1 sec timeout */
    if( gethostuuid(pHostID, &timeout) ){
      int err = errno;
      if( pError ){
        *pError = err;
      }
7163
7164
7165
7166
7167
7168
7169
7170

7171
7172
7173
7174
7175
7176
7177
6989
6990
6991
6992
6993
6994
6995

6996
6997
6998
6999
7000
7001
7002
7003







-
+







  /* read the conch content */
  readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0);
  if( readLen<PROXY_PATHINDEX ){
    sqlite3_snprintf(sizeof(errmsg),errmsg,"read error (len %d)",(int)readLen);
    goto end_breaklock;
  }
  /* write it out to the temporary break file */
  fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW), 0);
  fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0);
  if( fd<0 ){
    sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
    goto end_breaklock;
  }
  if( osPwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
    sqlite3_snprintf(sizeof(errmsg), errmsg, "write failed (%d)", errno);
    goto end_breaklock;
7222
7223
7224
7225
7226
7227
7228
7229

7230
7231
7232
7233
7234
7235
7236
7048
7049
7050
7051
7052
7053
7054

7055
7056
7057
7058
7059
7060
7061
7062







-
+







      if( osFstat(conchFile->h, &buf) ){
        storeLastErrno(pFile, errno);
        return SQLITE_IOERR_LOCK;
      }
      
      if( nTries==1 ){
        conchModTime = buf.st_mtimespec;
        unixSleep(0,500000); /* wait 0.5 sec and try the lock again*/
        usleep(500000); /* wait 0.5 sec and try the lock again*/
        continue;  
      }

      assert( nTries>1 );
      if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || 
         conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){
        return SQLITE_BUSY;
7248
7249
7250
7251
7252
7253
7254
7255

7256
7257
7258
7259
7260
7261
7262
7074
7075
7076
7077
7078
7079
7080

7081
7082
7083
7084
7085
7086
7087
7088







-
+







          if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){
            return SQLITE_BUSY;
          }
        }else{
          /* don't break the lock on short read or a version mismatch */
          return SQLITE_BUSY;
        }
        unixSleep(0,10000000); /* wait 10 sec and try the lock again */
        usleep(10000000); /* wait 10 sec and try the lock again */
        continue; 
      }
      
      assert( nTries==3 );
      if( 0==proxyBreakConchLock(pFile, myHostID) ){
        rc = SQLITE_OK;
        if( lockType==EXCLUSIVE_LOCK ){
7773
7774
7775
7776
7777
7778
7779
7780

7781
7782
7783
7784
7785
7786
7787
7599
7600
7601
7602
7603
7604
7605

7606
7607
7608
7609
7610
7611
7612
7613







-
+







      }
      return rc;
    }
    default: {
      assert( 0 );  /* The call assures that only valid opcodes are sent */
    }
  }
  /*NOTREACHED*/ assert(0);
  /*NOTREACHED*/
  return SQLITE_ERROR;
}

/*
** Within this division (the proxying locking implementation) the procedures
** above this point are all utilities.  The lock-related methods of the
** proxy-locking sqlite3_io_method object follow.

Changes to src/os_win.c.

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







-
+

-
+

-
+





-
+







** If a Win32 native heap has been configured, this function will attempt to
** destroy and recreate it.  If the Win32 native heap is not isolated and/or
** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
** be returned and no changes will be made to the Win32 native heap.
*/
int sqlite3_win32_reset_heap(){
  int rc;
  MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */
  MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
  MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
  MUTEX_LOGIC( pMainMtx = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); )
  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
  sqlite3_mutex_enter(pMainMtx);
  sqlite3_mutex_enter(pMaster);
  sqlite3_mutex_enter(pMem);
  winMemAssertMagic();
  if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
    /*
    ** At this point, there should be no outstanding memory allocations on
    ** the heap.  Also, since both the main and memsys locks are currently
    ** the heap.  Also, since both the master and memsys locks are currently
    ** being held by us, no other function (i.e. from another thread) should
    ** be able to even access the heap.  Attempt to destroy and recreate our
    ** isolated Win32 native heap now.
    */
    assert( winMemGetHeap()!=NULL );
    assert( winMemGetOwned() );
    assert( sqlite3_memory_used()==0 );
1319
1320
1321
1322
1323
1324
1325
1326

1327
1328
1329
1330
1331
1332
1333
1319
1320
1321
1322
1323
1324
1325

1326
1327
1328
1329
1330
1331
1332
1333







-
+







  }else{
    /*
    ** The Win32 native heap cannot be modified because it may be in use.
    */
    rc = SQLITE_BUSY;
  }
  sqlite3_mutex_leave(pMem);
  sqlite3_mutex_leave(pMainMtx);
  sqlite3_mutex_leave(pMaster);
  return rc;
}
#endif /* SQLITE_WIN32_MALLOC */

/*
** This function outputs the specified (ANSI) string to the Win32 debugger
** (if available).
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3498
3499
3500
3501
3502
3503
3504

3505
3506
3507
3508
3509
3510
3511







-







    pFile->ctrlFlags |= mask;
  }
}

/* Forward references to VFS helper methods used for temporary files */
static int winGetTempname(sqlite3_vfs *, char **);
static int winIsDir(const void *);
static BOOL winIsLongPathPrefix(const char *);
static BOOL winIsDriveLetterAndColon(const char *);

/*
** Control and query of the open file handle.
*/
static int winFileControl(sqlite3_file *id, int op, void *pArg){
  winFile *pFile = (winFile*)id;
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4211
4212
4213
4214
4215
4216
4217

4218
4219
4220
4221
4222
4223
4224







-







  DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ;
  int rc = SQLITE_OK;

  if( !pShm ){
    rc = winOpenSharedMemory(pDbFd);
    if( rc!=SQLITE_OK ) return rc;
    pShm = pDbFd->pShm;
    assert( pShm!=0 );
  }
  pShmNode = pShm->pShmNode;

  sqlite3_mutex_enter(pShmNode->mutex);
  if( pShmNode->isUnlocked ){
    rc = winLockSharedMemory(pShmNode);
    if( rc!=SQLITE_OK ) goto shmpage_out;
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4513
4514
4515
4516
4517
4518
4519

4520
4521
4522
4523
4524
4525
4526







-







      if( rc!=SQLITE_OK ){
        OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n",
                 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
        return rc;
      }
    }
    if( pFd->mmapSize >= iOff+nAmt ){
      assert( pFd->pMapRegion!=0 );
      *pp = &((u8 *)pFd->pMapRegion)[iOff];
      pFd->nFetchOut++;
    }
  }
#endif

  OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
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
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







-
+




















-
+



-
+





-
+







  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
  int isCreate     = (flags & SQLITE_OPEN_CREATE);
  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);

#ifndef NDEBUG
  int isOpenJournal = (isCreate && (
        eType==SQLITE_OPEN_SUPER_JOURNAL
        eType==SQLITE_OPEN_MASTER_JOURNAL
     || eType==SQLITE_OPEN_MAIN_JOURNAL
     || eType==SQLITE_OPEN_WAL
  ));
#endif

  OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n",
           zUtf8Name, id, flags, pOutFlags));

  /* Check the following statements are true:
  **
  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and
  **   (b) if CREATE is set, then READWRITE must also be set, and
  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
  */
  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
  assert(isCreate==0 || isReadWrite);
  assert(isExclusive==0 || isCreate);
  assert(isDelete==0 || isCreate);

  /* The main DB, main journal, WAL file and super-journal are never
  /* The main DB, main journal, WAL file and master journal are never
  ** automatically deleted. Nor are they ever temporary files.  */
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_SUPER_JOURNAL );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );

  /* Assert that the upper layer has set one of the "file-type" flags. */
  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB
       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_SUPER_JOURNAL
       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL
       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
  );

  assert( pFile!=0 );
  memset(pFile, 0, sizeof(winFile));
  pFile->h = INVALID_HANDLE_VALUE;

5122
5123
5124
5125
5126
5127
5128
5129
5130

5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5119
5120
5121
5122
5123
5124
5125


5126



5127
5128
5129
5130
5131
5132
5133







-
-
+
-
-
-







    /* Open existing file, or create if it doesn't exist */
    dwCreationDisposition = OPEN_ALWAYS;
  }else{
    /* Opens a file, only if it exists. */
    dwCreationDisposition = OPEN_EXISTING;
  }

  if( 0==sqlite3_uri_boolean(zName, "exclusive", 0) ){
    dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
  dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
  }else{
    dwShareMode = 0;
  }

  if( isDelete ){
#if SQLITE_OS_WINCE
    dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
    isTemp = 1;
#else
    dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
5266
5267
5268
5269
5270
5271
5272
5273

5274
5275
5276
5277
5278
5279
5280

5281
5282
5283
5284
5285
5286
5287
5288
5259
5260
5261
5262
5263
5264
5265

5266
5267
5268
5269
5270
5271


5272

5273
5274
5275
5276
5277
5278
5279







-
+





-
-
+
-







  }else
#endif
  {
    sqlite3_free(zConverted);
  }

  sqlite3_free(zTmpname);
  id->pMethods = pAppData ? pAppData->pMethod : &winIoMethod;
  pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod;
  pFile->pVfs = pVfs;
  pFile->h = h;
  if( isReadonly ){
    pFile->ctrlFlags |= WINFILE_RDONLY;
  }
  if( (flags & SQLITE_OPEN_MAIN_DB)
   && sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) 
  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
  ){
    pFile->ctrlFlags |= WINFILE_PSOW;
  }
  pFile->lastErrno = NO_ERROR;
  pFile->zPath = zName;
#if SQLITE_MAX_MMAP_SIZE>0
  pFile->hMap = NULL;
  pFile->pMapRegion = 0;
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5475
5476
5477
5478
5479
5480
5481











5482
5483
5484
5485
5486
5487
5488







-
-
-
-
-
-
-
-
-
-
-







  }
  *pResOut = rc;
  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
           zFilename, pResOut, *pResOut));
  return SQLITE_OK;
}

/*
** Returns non-zero if the specified path name starts with the "long path"
** prefix.
*/
static BOOL winIsLongPathPrefix(
  const char *zPathname
){
  return ( zPathname[0]=='\\' && zPathname[1]=='\\'
        && zPathname[2]=='?'  && zPathname[3]=='\\' );
}

/*
** Returns non-zero if the specified path name starts with a drive letter
** followed by a colon character.
*/
static BOOL winIsDriveLetterAndColon(
  const char *zPathname
){
5559
5560
5561
5562
5563
5564
5565
5566
5567


5568
5569

5570
5571
5572
5573
5574
5575
5576
5577
5539
5540
5541
5542
5543
5544
5545


5546
5547
5548

5549

5550
5551
5552
5553
5554
5555
5556







-
-
+
+

-
+
-







){
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  DWORD nByte;
  void *zConverted;
  char *zOut;
#endif

  /* If this path name begins with "/X:" or "\\?\", where "X" is any
  ** alphabetic character, discard the initial "/" from the pathname.
  /* If this path name begins with "/X:", where "X" is any alphabetic
  ** character, discard the initial "/" from the pathname.
  */
  if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1)
  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
       || winIsLongPathPrefix(zRelative+1)) ){
    zRelative++;
  }

#if defined(__CYGWIN__)
  SimulateIOError( return SQLITE_ERROR );
  UNUSED_PARAMETER(nFull);
  assert( nFull>=pVfs->mxPathname );

Changes to src/pager.c.

66
67
68
69
70
71
72
73
74


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


73
74
75
76
77
78
79
80
81







-
-
+
+







** (4) Reads from the database file are either aligned on a page boundary and
**     an integer multiple of the page size in length or are taken from the
**     first 100 bytes of the database file.
** 
** (5) All writes to the database file are synced prior to the rollback journal
**     being deleted, truncated, or zeroed.
** 
** (6) If a super-journal file is used, then all writes to the database file
**     are synced prior to the super-journal being deleted.
** (6) If a master journal file is used, then all writes to the database file
**     are synced prior to the master journal being deleted.
** 
** Definition: Two databases (or the same database at two points it time)
** are said to be "logically equivalent" if they give the same answer to
** all queries.  Note in particular the content of freelist leaf
** pages can be changed arbitrarily without affecting the logical equivalence
** of the database.
** 
402
403
404
405
406
407
408














409
410
411
412
413
414
415
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







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







** PagerSharedLock() for more detail.
**
** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in 
** PAGER_OPEN state.
*/
#define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)

/*
** A macro used for invoking the codec if there is one
*/
#ifdef SQLITE_HAS_CODEC
# define CODEC1(P,D,N,X,E) \
    if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
# define CODEC2(P,D,N,X,E,O) \
    if( P->xCodec==0 ){ O=(char*)D; }else \
    if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
#else
# define CODEC1(P,D,N,X,E)   /* NO-OP */
# define CODEC2(P,D,N,X,E,O) O=(char*)D
#endif

/*
** The maximum allowed sector size. 64KiB. If the xSectorsize() method 
** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
** This could conceivably cause corruption following a power failure on
** such a system. This is currently an undocumented limit.
*/
#define MAX_SECTOR_SIZE 0x10000
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
445
446
447
448
449
450
451

452
453
454
455
456
457
458







-







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







-
+


-
+


-
+


-
+

-
+



-
+

-
+




-
+







**   The changeCountDone flag is inspected. If it is true, the work of
**   updating the change-counter is omitted for the current transaction.
**
**   This mechanism means that when running in exclusive mode, a connection 
**   need only update the change-counter once, for the first transaction
**   committed.
**
** setSuper
** setMaster
**
**   When PagerCommitPhaseOne() is called to commit a transaction, it may
**   (or may not) specify a super-journal name to be written into the 
**   (or may not) specify a master-journal name to be written into the 
**   journal file before it is synced to disk.
**
**   Whether or not a journal file contains a super-journal pointer affects 
**   Whether or not a journal file contains a master-journal pointer affects 
**   the way in which the journal file is finalized after the transaction is 
**   committed or rolled back when running in "journal_mode=PERSIST" mode.
**   If a journal file does not contain a super-journal pointer, it is
**   If a journal file does not contain a master-journal pointer, it is
**   finalized by overwriting the first journal header with zeroes. If
**   it does contain a super-journal pointer the journal file is finalized 
**   it does contain a master-journal pointer the journal file is finalized 
**   by truncating it to zero bytes, just as if the connection were 
**   running in "journal_mode=truncate" mode.
**
**   Journal files that contain super-journal pointers cannot be finalized
**   Journal files that contain master journal pointers cannot be finalized
**   simply by overwriting the first journal-header with zeroes, as the
**   super-journal pointer could interfere with hot-journal rollback of any
**   master journal pointer could interfere with hot-journal rollback of any
**   subsequently interrupted transaction that reuses the journal file.
**
**   The flag is cleared as soon as the journal file is finalized (either
**   by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
**   journal file from being successfully finalized, the setSuper flag
**   journal file from being successfully finalized, the setMaster flag
**   is cleared anyway (and the pager will move to ERROR state).
**
** doNotSpill
**
**   This variables control the behavior of cache-spills  (calls made by
**   the pcache module to the pagerStress() routine to write cached data
**   to the file-system in order to free up memory).
639
640
641
642
643
644
645
646

647
648
649
650
651
652
653
652
653
654
655
656
657
658

659
660
661
662
663
664
665
666







-
+







  ** or the journal_mode).  From another view, these class members describe
  ** the "state" of the pager, while other class members describe the
  ** "configuration" of the pager.
  */
  u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
  u8 eLock;                   /* Current lock held on database file */
  u8 changeCountDone;         /* Set after incrementing the change-counter */
  u8 setSuper;                /* Super-jrnl name is written into jrnl */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSpill;              /* Do not spill the cache when non-zero */
  u8 subjInMemory;            /* True to use in-memory sub-journals */
  u8 bUseFetch;               /* True to use xFetch() */
  u8 hasHeldSharedLock;       /* True if a shared lock has ever been held */
  Pgno dbSize;                /* Number of pages in the database */
  Pgno dbOrigSize;            /* dbSize before the current transaction */
  Pgno dbFileSize;            /* Number of pages in the database file */
688
689
690
691
692
693
694






695
696
697
698
699
700
701
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720







+
+
+
+
+
+







  void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
  int aStat[4];               /* Total cache hits, misses, writes, spills */
#ifdef SQLITE_TEST
  int nRead;                  /* Database pages read */
#endif
  void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
  int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
#ifdef SQLITE_HAS_CODEC
  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
  void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
  void (*xCodecFree)(void*);             /* Destructor for the codec */
  void *pCodec;               /* First argument to xCodec... methods */
#endif
  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
  PCache *pPCache;            /* Pointer to page cache object */
#ifndef SQLITE_OMIT_WAL
  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
  char *zWal;                 /* File name for write-ahead log */
#endif
};
783
784
785
786
787
788
789





790
791
792
793
794
795
796
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820







+
+
+
+
+







*/
#if SQLITE_MAX_MMAP_SIZE>0
# define USEFETCH(x) ((x)->bUseFetch)
#else
# define USEFETCH(x) 0
#endif

/*
** The maximum legal page number is (2^31 - 1).
*/
#define PAGER_MAX_PGNO 2147483647

/*
** The argument to this macro is a file descriptor (type sqlite3_file*).
** Return 0 if it is not open, or non-zero (but not 1) if it is.
**
** This is so that expressions can be written as:
**
**   if( isOpen(pPager->jfd) ){ ...
809
810
811
812
813
814
815



816
817
818
819
820
821
822
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849







+
+
+







**   * the database file is open,
**   * there are no dirty pages in the cache, and
**   * the desired page is not currently in the wal file.
*/
int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
  if( pPager->fd->pMethods==0 ) return 0;
  if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
#ifdef SQLITE_HAS_CODEC
  if( pPager->xCodec!=0 ) return 0;
#endif
#ifndef SQLITE_OMIT_WAL
  if( pPager->pWal ){
    u32 iRead = 0;
    int rc;
    rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
    return (rc==SQLITE_OK && iRead==0);
  }
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
939
940
941
942
943
944
945

946
947
948
949
950
951
952
953







-
+







      assert( pPager->errCode==SQLITE_OK );
      if( !pagerUseWal(pPager) ){
        assert( p->eLock>=RESERVED_LOCK );
      }
      assert( pPager->dbSize==pPager->dbOrigSize );
      assert( pPager->dbOrigSize==pPager->dbFileSize );
      assert( pPager->dbOrigSize==pPager->dbHintSize );
      assert( pPager->setSuper==0 );
      assert( pPager->setMaster==0 );
      break;

    case PAGER_WRITER_CACHEMOD:
      assert( p->eLock!=UNKNOWN_LOCK );
      assert( pPager->errCode==SQLITE_OK );
      if( !pagerUseWal(pPager) ){
        /* It is possible that if journal_mode=wal here that neither the
1042
1043
1044
1045
1046
1047
1048
1049





1050
1051
1052
1053
1054
1055
1056
1069
1070
1071
1072
1073
1074
1075

1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087







-
+
+
+
+
+







** Set the Pager.xGet method for the appropriate routine used to fetch
** content from the pager.
*/
static void setGetterMethod(Pager *pPager){
  if( pPager->errCode ){
    pPager->xGet = getPageError;
#if SQLITE_MAX_MMAP_SIZE>0
  }else if( USEFETCH(pPager) ){
  }else if( USEFETCH(pPager)
#ifdef SQLITE_HAS_CODEC
   && pPager->xCodec==0
#endif
  ){
    pPager->xGet = getPageMMap;
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
  }else{
    pPager->xGet = getPageNormal;
  }
}

1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1098
1099
1100
1101
1102
1103
1104



1105
1106
1107
1108
1109
1110
1111







-
-
-







  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
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1168
1169
1170
1171
1172
1173
1174

1175
1176
1177
1178
1179
1180
1181







-







    assert( pPager->eLock>=eLock );
    rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
    if( pPager->eLock!=UNKNOWN_LOCK ){
      pPager->eLock = (u8)eLock;
    }
    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
  }
  pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */
  return rc;
}

/*
** Lock the database file to level eLock, which must be either SHARED_LOCK,
** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the
** Pager.eLock variable to the new locking state. 
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
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







-
+

-
-
+
+

-
+

-
-
-
+
+
+


-
-
-
-
+
+
+
+

-
-
+
+




-
+

-
+




-
+




-
+





-
+




-
+

-
+



-
+

-
+



-
+
-







#define pager_pagehash(X)  0
#define pager_set_pagehash(X)
#define CHECK_PAGE(x)
#endif  /* SQLITE_CHECK_PAGES */

/*
** When this is called the journal file for pager pPager must be open.
** This function attempts to read a super-journal file name from the 
** This function attempts to read a master journal file name from the 
** end of the file and, if successful, copies it into memory supplied 
** by the caller. See comments above writeSuperJournal() for the format
** used to store a super-journal file name at the end of a journal file.
** by the caller. See comments above writeMasterJournal() for the format
** used to store a master journal file name at the end of a journal file.
**
** zSuper must point to a buffer of at least nSuper bytes allocated by
** zMaster must point to a buffer of at least nMaster bytes allocated by
** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
** enough space to write the super-journal name). If the super-journal
** name in the journal is longer than nSuper bytes (including a
** nul-terminator), then this is handled as if no super-journal name
** enough space to write the master journal name). If the master journal
** name in the journal is longer than nMaster bytes (including a
** nul-terminator), then this is handled as if no master journal name
** were present in the journal.
**
** If a super-journal file name is present at the end of the journal
** file, then it is copied into the buffer pointed to by zSuper. A
** nul-terminator byte is appended to the buffer following the
** super-journal file name.
** If a master journal file name is present at the end of the journal
** file, then it is copied into the buffer pointed to by zMaster. A
** nul-terminator byte is appended to the buffer following the master
** journal file name.
**
** If it is determined that no super-journal file name is present 
** zSuper[0] is set to 0 and SQLITE_OK returned.
** If it is determined that no master journal file name is present 
** zMaster[0] is set to 0 and SQLITE_OK returned.
**
** If an error occurs while reading from the journal file, an SQLite
** error code is returned.
*/
static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u32 nSuper){
static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
  int rc;                    /* Return code */
  u32 len;                   /* Length in bytes of super-journal name */
  u32 len;                   /* Length in bytes of master journal name */
  i64 szJ;                   /* Total size in bytes of journal file pJrnl */
  u32 cksum;                 /* MJ checksum value read from journal */
  u32 u;                     /* Unsigned loop counter */
  unsigned char aMagic[8];   /* A buffer to hold the magic header */
  zSuper[0] = '\0';
  zMaster[0] = '\0';

  if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
   || szJ<16
   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
   || len>=nSuper 
   || len>=nMaster 
   || len>szJ-16
   || len==0 
   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
   || memcmp(aMagic, aJournalMagic, 8)
   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zSuper, len, szJ-16-len))
   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len))
  ){
    return rc;
  }

  /* See if the checksum matches the super-journal name */
  /* See if the checksum matches the master journal name */
  for(u=0; u<len; u++){
    cksum -= zSuper[u];
    cksum -= zMaster[u];
  }
  if( cksum ){
    /* If the checksum doesn't add up, then one or more of the disk sectors
    ** containing the super-journal filename is corrupted. This means
    ** containing the master journal filename is corrupted. This means
    ** definitely roll back, so just return SQLITE_OK and report a (nul)
    ** super-journal filename.
    ** master-journal filename.
    */
    len = 0;
  }
  zSuper[len] = '\0';
  zMaster[len] = '\0';
  zSuper[len+1] = '\0';
   
  return SQLITE_OK;
}

/*
** Return the offset of the sector boundary at or immediately 
** following the value in pPager->journalOff, assuming a sector 
1656
1657
1658
1659
1660
1661
1662
1663
1664


1665
1666
1667
1668
1669
1670
1671
1672



1673
1674
1675
1676


1677
1678

1679
1680
1681

1682
1683

1684
1685
1686

1687
1688

1689
1690
1691

1692
1693
1694
1695
1696
1697

1698
1699
1700
1701
1702



1703
1704
1705
1706

1707
1708
1709
1710
1711
1712
1713
1714

1715
1716
1717
1718
1719
1720



1721
1722

1723
1724
1725
1726

1727
1728
1729

1730
1731
1732

1733
1734
1735
1736
1737
1738
1739
1682
1683
1684
1685
1686
1687
1688


1689
1690
1691
1692
1693
1694
1695



1696
1697
1698
1699
1700


1701
1702
1703

1704
1705
1706

1707
1708

1709
1710
1711

1712
1713

1714
1715
1716

1717
1718
1719
1720
1721
1722

1723
1724
1725



1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737
1738
1739

1740
1741
1742
1743



1744
1745
1746
1747

1748
1749
1750
1751

1752
1753
1754

1755
1756
1757

1758
1759
1760
1761
1762
1763
1764
1765







-
-
+
+





-
-
-
+
+
+


-
-
+
+

-
+


-
+

-
+


-
+

-
+


-
+





-
+


-
-
-
+
+
+



-
+







-
+



-
-
-
+
+
+

-
+



-
+


-
+


-
+








  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
  return rc;
}


/*
** Write the supplied super-journal name into the journal file for pager
** pPager at the current location. The super-journal name must be the last
** Write the supplied master journal name into the journal file for pager
** pPager at the current location. The master journal name must be the last
** thing written to a journal file. If the pager is in full-sync mode, the
** journal file descriptor is advanced to the next sector boundary before
** anything is written. The format is:
**
**   + 4 bytes: PAGER_MJ_PGNO.
**   + N bytes: super-journal filename in utf-8.
**   + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
**   + 4 bytes: super-journal name checksum.
**   + N bytes: Master journal filename in utf-8.
**   + 4 bytes: N (length of master journal name in bytes, no nul-terminator).
**   + 4 bytes: Master journal name checksum.
**   + 8 bytes: aJournalMagic[].
**
** The super-journal page checksum is the sum of the bytes in thesuper-journal
** name, where each byte is interpreted as a signed 8-bit integer.
** The master journal page checksum is the sum of the bytes in the master
** journal name, where each byte is interpreted as a signed 8-bit integer.
**
** If zSuper is a NULL pointer (occurs for a single database transaction), 
** If zMaster is a NULL pointer (occurs for a single database transaction), 
** this call is a no-op.
*/
static int writeSuperJournal(Pager *pPager, const char *zSuper){
static int writeMasterJournal(Pager *pPager, const char *zMaster){
  int rc;                          /* Return code */
  int nSuper;                      /* Length of string zSuper */
  int nMaster;                     /* Length of string zMaster */
  i64 iHdrOff;                     /* Offset of header in journal file */
  i64 jrnlSize;                    /* Size of journal file on disk */
  u32 cksum = 0;                   /* Checksum of string zSuper */
  u32 cksum = 0;                   /* Checksum of string zMaster */

  assert( pPager->setSuper==0 );
  assert( pPager->setMaster==0 );
  assert( !pagerUseWal(pPager) );

  if( !zSuper 
  if( !zMaster 
   || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
   || !isOpen(pPager->jfd)
  ){
    return SQLITE_OK;
  }
  pPager->setSuper = 1;
  pPager->setMaster = 1;
  assert( pPager->journalHdr <= pPager->journalOff );

  /* Calculate the length in bytes and the checksum of zSuper */
  for(nSuper=0; zSuper[nSuper]; nSuper++){
    cksum += zSuper[nSuper];
  /* Calculate the length in bytes and the checksum of zMaster */
  for(nMaster=0; zMaster[nMaster]; nMaster++){
    cksum += zMaster[nMaster];
  }

  /* If in full-sync mode, advance to the next disk sector before writing
  ** the super-journal name. This is in case the previous page written to
  ** the master journal name. This is in case the previous page written to
  ** the journal has already been synced.
  */
  if( pPager->fullSync ){
    pPager->journalOff = journalHdrOffset(pPager);
  }
  iHdrOff = pPager->journalOff;

  /* Write the super-journal data to the end of the journal file. If
  /* Write the master journal data to the end of the journal file. If
  ** an error occurs, return the error code to the caller.
  */
  if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
   || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4)))
   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper)))
   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum)))
   || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
   || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
                                 iHdrOff+4+nSuper+8)))
                                 iHdrOff+4+nMaster+8)))
  ){
    return rc;
  }
  pPager->journalOff += (nSuper+20);
  pPager->journalOff += (nMaster+20);

  /* If the pager is in peristent-journal mode, then the physical 
  ** journal-file may extend past the end of the super-journal name
  ** journal-file may extend past the end of the master-journal name
  ** and 8 bytes of magic data just written to the file. This is 
  ** dangerous because the code to rollback a hot-journal file
  ** will not be able to find the super-journal name to determine 
  ** will not be able to find the master-journal name to determine 
  ** whether or not the journal is hot. 
  **
  ** Easiest thing to do in this scenario is to truncate the journal 
  ** file to the required size.
  */ 
  if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))
   && jrnlSize>pPager->journalOff
1862
1863
1864
1865
1866
1867
1868

1869
1870
1871
1872
1873
1874
1875
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902







+







    }

    /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here
    ** without clearing the error code. This is intentional - the error
    ** code is cleared and the cache reset in the block below.
    */
    assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
    pPager->changeCountDone = 0;
    pPager->eState = PAGER_OPEN;
  }

  /* If Pager.errCode is set, the contents of the pager cache cannot be
  ** trusted. Now that there are no outstanding references to the pager,
  ** it can safely move back to PAGER_OPEN state. This happens in both
  ** normal and exclusive-locking mode.
1886
1887
1888
1889
1890
1891
1892
1893

1894
1895
1896
1897
1898
1899
1900
1913
1914
1915
1916
1917
1918
1919

1920
1921
1922
1923
1924
1925
1926
1927







-
+







    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
    pPager->errCode = SQLITE_OK;
    setGetterMethod(pPager);
  }

  pPager->journalOff = 0;
  pPager->journalHdr = 0;
  pPager->setSuper = 0;
  pPager->setMaster = 0;
}

/*
** This function is called whenever an IOERR or FULL error that requires
** the pager to transition into the ERROR state may ahve occurred.
** The first argument is a pointer to the pager structure, the second 
** the error-code about to be returned by a pager API function. The 
2002
2003
2004
2005
2006
2007
2008
2009

2010
2011
2012
2013
2014
2015
2016
2029
2030
2031
2032
2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
2043







-
+







** database then the IO error code is returned to the user. If the 
** operation to finalize the journal file fails, then the code still
** tries to unlock the database file if not in exclusive mode. If the
** unlock operation fails as well, then the first error code related
** to the first error encountered (the journal finalization one) is
** returned.
*/
static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){
static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
  int rc = SQLITE_OK;      /* Error code from journal finalization operation */
  int rc2 = SQLITE_OK;     /* Error code from db file unlock operation */

  /* Do nothing if the pager does not have an open write transaction
  ** or at least a RESERVED lock. This function may be called when there
  ** is no write-transaction active but a RESERVED or greater lock is
  ** held under two circumstances:
2054
2055
2056
2057
2058
2059
2060
2061

2062
2063
2064
2065
2066
2067
2068
2081
2082
2083
2084
2085
2086
2087

2088
2089
2090
2091
2092
2093
2094
2095







-
+







          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
        }
      }
      pPager->journalOff = 0;
    }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
      || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
    ){
      rc = zeroJournalHdr(pPager, hasSuper||pPager->tempFile);
      rc = zeroJournalHdr(pPager, hasMaster||pPager->tempFile);
      pPager->journalOff = 0;
    }else{
      /* This branch may be executed with Pager.journalMode==MEMORY if
      ** a hot-journal was just rolled back. In this case the journal
      ** file should be closed and deleted. If this connection writes to
      ** the database file, it will do so using an in-memory journal.
      */
2125
2126
2127
2128
2129
2130
2131

2132
2133
2134

2135
2136
2137
2138
2139
2140
2141
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161

2162
2163
2164
2165
2166
2167
2168
2169







+


-
+







    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
  }

  if( !pPager->exclusiveMode 
   && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
  ){
    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
    pPager->changeCountDone = 0;
  }
  pPager->eState = PAGER_READER;
  pPager->setSuper = 0;
  pPager->setMaster = 0;

  return (rc==SQLITE_OK?rc2:rc);
}

/*
** Execute a rollback if a transaction is active and unlock the 
** database file. 
2193
2194
2195
2196
2197
2198
2199





























2200
2201
2202
2203
2204
2205
2206
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







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







  while( i>0 ){
    cksum += aData[i];
    i -= 200;
  }
  return cksum;
}

/*
** Report the current page size and number of reserved bytes back
** to the codec.
*/
#ifdef SQLITE_HAS_CODEC
static void pagerReportSize(Pager *pPager){
  if( pPager->xCodecSizeChng ){
    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
                           (int)pPager->nReserve);
  }
}
#else
# define pagerReportSize(X)     /* No-op if we do not support a codec */
#endif

#ifdef SQLITE_HAS_CODEC
/*
** Make sure the number of reserved bits is the same in the destination
** pager as it is in the source.  This comes up when a VACUUM changes the
** number of reserved bits to the "optimal" amount.
*/
void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
  if( pDest->nReserve!=pSrc->nReserve ){
    pDest->nReserve = pSrc->nReserve;
    pagerReportSize(pDest);
  }
}
#endif

/*
** Read a single page from either the journal file (if isMainJrnl==1) or
** from the sub-journal (if isMainJrnl==0) and playback that page.
** The page begins at offset *pOffset into the file. The *pOffset
** value is increased to the start of the next page in the journal.
**
** The main rollback journal uses checksums - the statement journal does 
2244
2245
2246
2247
2248
2249
2250





2251
2252
2253
2254
2255
2256
2257
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319







+
+
+
+
+







  int rc;
  PgHdr *pPg;                   /* An existing page in the cache */
  Pgno pgno;                    /* The page number of a page in journal */
  u32 cksum;                    /* Checksum used for sanity checking */
  char *aData;                  /* Temporary storage for the page */
  sqlite3_file *jfd;            /* The file descriptor for the journal file */
  int isSynced;                 /* True if journal page is synced */
#ifdef SQLITE_HAS_CODEC
  /* The jrnlEnc flag is true if Journal pages should be passed through
  ** the codec.  It is false for pure in-memory journals. */
  const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
#endif

  assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
  assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
  assert( isMainJrnl || pDone );     /* pDone always used on sub-journals */
  assert( isSavepnt || pDone==0 );   /* pDone never used on non-savepoint */

  aData = pPager->pTmpSpace;
2306
2307
2308
2309
2310
2311
2312

2313
2314
2315
2316
2317
2318
2319
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382







+







    return rc;
  }

  /* When playing back page 1, restore the nReserve setting
  */
  if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
    pPager->nReserve = ((u8*)aData)[20];
    pagerReportSize(pPager);
  }

  /* If the pager is in CACHEMOD state, then there must be a copy of this
  ** page in the pager cache. In this case just update the pager cache,
  ** not the database file. The page is left marked dirty in this case.
  **
  ** An exception to the above rule: If the database is in no-sync mode
2373
2374
2375
2376
2377
2378
2379







2380
2381
2382
2383
2384
2385







2386
2387
2388
2389
2390
2391
2392
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469







+
+
+
+
+
+
+






+
+
+
+
+
+
+








    /* Write the data read from the journal back into the database file.
    ** This is usually safe even for an encrypted database - as the data
    ** was encrypted before it was written to the journal file. The exception
    ** is if the data was just read from an in-memory sub-journal. In that
    ** case it must be encrypted here before it is copied into the database
    ** file.  */
#ifdef SQLITE_HAS_CODEC
    if( !jrnlEnc ){
      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
      rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
    }else
#endif
    rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);

    if( pgno>pPager->dbFileSize ){
      pPager->dbFileSize = pgno;
    }
    if( pPager->pBackup ){
#ifdef SQLITE_HAS_CODEC
      if( jrnlEnc ){
        CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
        sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
        CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
      }else
#endif
      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
    }
  }else if( !isMainJrnl && pPg==0 ){
    /* If this is a rollback of a savepoint and data was not written to
    ** the database and the page is not in-memory, there is a potential
    ** problem. When the page is next fetched by the b-tree layer, it 
    ** will be read from the database file, which may or may not be 
2429
2430
2431
2432
2433
2434
2435





2436
2437
2438
2439
2440
2441
2442
2443
2444



2445
2446
2447

2448
2449
2450

2451
2452
2453

2454
2455
2456
2457
2458

2459
2460
2461

2462
2463
2464
2465
2466
2467


2468
2469
2470
2471

2472
2473
2474
2475
2476
2477
2478
2479
2480

2481
2482
2483
2484

2485
2486
2487

2488
2489
2490


2491
2492

2493
2494

2495
2496
2497


2498
2499
2500



2501
2502
2503
2504
2505


2506
2507
2508

2509
2510
2511
2512
2513




2514
2515
2516
2517
2518
2519





2520
2521

2522
2523
2524

2525
2526
2527
2528



2529
2530
2531
2532


2533
2534
2535
2536

2537
2538
2539
2540
2541



2542
2543
2544
2545
2546
2547

2548
2549
2550

2551
2552
2553

2554
2555
2556

2557
2558
2559

2560
2561
2562


2563
2564
2565
2566
2567
2568
2569


2570
2571
2572
2573
2574




2575
2576

2577
2578
2579
2580
2581
2582
2583
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523



2524
2525
2526
2527
2528

2529
2530
2531

2532
2533
2534

2535
2536
2537
2538
2539

2540
2541
2542

2543
2544
2545
2546
2547


2548
2549
2550
2551
2552

2553
2554
2555
2556
2557
2558
2559
2560
2561

2562
2563
2564
2565

2566
2567
2568

2569
2570


2571
2572
2573

2574


2575
2576


2577
2578
2579


2580
2581
2582
2583

2584


2585
2586

2587

2588
2589




2590
2591
2592
2593
2594





2595
2596
2597
2598
2599
2600

2601
2602


2603




2604
2605
2606

2607


2608
2609
2610
2611
2612

2613
2614
2615



2616
2617
2618



2619
2620

2621
2622
2623

2624
2625
2626

2627
2628
2629

2630
2631
2632

2633
2634


2635
2636
2637
2638
2639
2640
2641


2642
2643
2644




2645
2646
2647
2648
2649

2650
2651
2652
2653
2654
2655
2656
2657







+
+
+
+
+






-
-
-
+
+
+


-
+


-
+


-
+




-
+


-
+




-
-
+
+



-
+








-
+



-
+


-
+

-
-
+
+

-
+
-
-
+

-
-
+
+

-
-
+
+
+

-

-
-
+
+
-

-
+

-
-
-
-
+
+
+
+

-
-
-
-
-
+
+
+
+
+

-
+

-
-
+
-
-
-
-
+
+
+
-

-
-
+
+



-
+


-
-
-
+
+
+
-
-
-


-
+


-
+


-
+


-
+


-
+

-
-
+
+





-
-
+
+

-
-
-
-
+
+
+
+

-
+







    pager_set_pagehash(pPg);

    /* If this was page 1, then restore the value of Pager.dbFileVers.
    ** Do this before any decoding. */
    if( pgno==1 ){
      memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
    }

    /* Decode the page just read from disk */
#if SQLITE_HAS_CODEC
    if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
#endif
    sqlite3PcacheRelease(pPg);
  }
  return rc;
}

/*
** Parameter zSuper is the name of a super-journal file. A single journal
** file that referred to the super-journal file has just been rolled back.
** This routine checks if it is possible to delete the super-journal file,
** Parameter zMaster is the name of a master journal file. A single journal
** file that referred to the master journal file has just been rolled back.
** This routine checks if it is possible to delete the master journal file,
** and does so if it is.
**
** Argument zSuper may point to Pager.pTmpSpace. So that buffer is not 
** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not 
** available for use within this function.
**
** When a super-journal file is created, it is populated with the names 
** When a master journal file is created, it is populated with the names 
** of all of its child journals, one after another, formatted as utf-8 
** encoded text. The end of each child journal file is marked with a 
** nul-terminator byte (0x00). i.e. the entire contents of a super-journal
** nul-terminator byte (0x00). i.e. the entire contents of a master journal
** file for a transaction involving two databases might be:
**
**   "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
**
** A super-journal file may only be deleted once all of its child 
** A master journal file may only be deleted once all of its child 
** journals have been rolled back.
**
** This function reads the contents of the super-journal file into 
** This function reads the contents of the master-journal file into 
** memory and loops through each of the child journal names. For
** each child journal, it checks if:
**
**   * if the child journal exists, and if so
**   * if the child journal contains a reference to super-journal 
**     file zSuper
**   * if the child journal contains a reference to master journal 
**     file zMaster
**
** If a child journal can be found that matches both of the criteria
** above, this function returns without doing anything. Otherwise, if
** no such child journal can be found, file zSuper is deleted from
** no such child journal can be found, file zMaster is deleted from
** the file-system using sqlite3OsDelete().
**
** If an IO error within this function, an error code is returned. This
** function allocates memory by calling sqlite3Malloc(). If an allocation
** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors 
** occur, SQLITE_OK is returned.
**
** TODO: This function allocates a single block of memory to load
** the entire contents of the super-journal file. This could be
** the entire contents of the master journal file. This could be
** a couple of kilobytes or so - potentially larger than the page 
** size.
*/
static int pager_delsuper(Pager *pPager, const char *zSuper){
static int pager_delmaster(Pager *pPager, const char *zMaster){
  sqlite3_vfs *pVfs = pPager->pVfs;
  int rc;                   /* Return code */
  sqlite3_file *pSuper;     /* Malloc'd super-journal file descriptor */
  sqlite3_file *pMaster;    /* Malloc'd master-journal file descriptor */
  sqlite3_file *pJournal;   /* Malloc'd child-journal file descriptor */
  char *zSuperJournal = 0;  /* Contents of super-journal file */
  i64 nSuperJournal;        /* Size of super-journal file */
  char *zMasterJournal = 0; /* Contents of master journal file */
  i64 nMasterJournal;       /* Size of master journal file */
  char *zJournal;           /* Pointer to one journal within MJ file */
  char *zSuperPtr;          /* Space to hold super-journal filename */
  char *zMasterPtr;         /* Space to hold MJ filename from a journal file */
  char *zFree = 0;          /* Free this buffer */
  int nSuperPtr;            /* Amount of space allocated to zSuperPtr[] */
  int nMasterPtr;           /* Amount of space allocated to zMasterPtr[] */

  /* Allocate space for both the pJournal and pSuper file descriptors.
  ** If successful, open the super-journal file for reading.
  /* Allocate space for both the pJournal and pMaster file descriptors.
  ** If successful, open the master journal file for reading.
  */
  pSuper = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
  if( !pSuper ){
  pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
  pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
  if( !pMaster ){
    rc = SQLITE_NOMEM_BKPT;
    pJournal = 0;
  }else{
    const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL);
    rc = sqlite3OsOpen(pVfs, zSuper, pSuper, flags, 0);
    const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
    rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
    pJournal = (sqlite3_file *)(((u8 *)pSuper) + pVfs->szOsFile);
  }
  if( rc!=SQLITE_OK ) goto delsuper_out;
  if( rc!=SQLITE_OK ) goto delmaster_out;

  /* Load the entire super-journal file into space obtained from
  ** sqlite3_malloc() and pointed to by zSuperJournal.   Also obtain
  ** sufficient space (in zSuperPtr) to hold the names of super-journal
  ** files extracted from regular rollback-journals.
  /* Load the entire master journal file into space obtained from
  ** sqlite3_malloc() and pointed to by zMasterJournal.   Also obtain
  ** sufficient space (in zMasterPtr) to hold the names of master
  ** journal files extracted from regular rollback-journals.
  */
  rc = sqlite3OsFileSize(pSuper, &nSuperJournal);
  if( rc!=SQLITE_OK ) goto delsuper_out;
  nSuperPtr = pVfs->mxPathname+1;
  zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2);
  if( !zFree ){
  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
  if( rc!=SQLITE_OK ) goto delmaster_out;
  nMasterPtr = pVfs->mxPathname+1;
  zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
  if( !zMasterJournal ){
    rc = SQLITE_NOMEM_BKPT;
    goto delsuper_out;
    goto delmaster_out;
  }
  zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0;
  zSuperJournal = &zFree[4];
  zMasterPtr = &zMasterJournal[nMasterJournal+1];
  zSuperPtr = &zSuperJournal[nSuperJournal+2];
  rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0);
  if( rc!=SQLITE_OK ) goto delsuper_out;
  zSuperJournal[nSuperJournal] = 0;
  rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
  if( rc!=SQLITE_OK ) goto delmaster_out;
  zMasterJournal[nMasterJournal] = 0;
  zSuperJournal[nSuperJournal+1] = 0;

  zJournal = zSuperJournal;
  while( (zJournal-zSuperJournal)<nSuperJournal ){
  zJournal = zMasterJournal;
  while( (zJournal-zMasterJournal)<nMasterJournal ){
    int exists;
    rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
    if( rc!=SQLITE_OK ){
      goto delsuper_out;
      goto delmaster_out;
    }
    if( exists ){
      /* One of the journals pointed to by the super-journal exists.
      ** Open it and check if it points at the super-journal. If
      ** so, return without deleting the super-journal file.
      /* One of the journals pointed to by the master journal exists.
      ** Open it and check if it points at the master journal. If
      ** so, return without deleting the master journal file.
      ** NB:  zJournal is really a MAIN_JOURNAL.  But call it a 
      ** SUPER_JOURNAL here so that the VFS will not send the zJournal
      ** name into sqlite3_database_file_object().
      */
      int c;
      int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL);
      int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
      rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
      if( rc!=SQLITE_OK ){
        goto delsuper_out;
        goto delmaster_out;
      }

      rc = readSuperJournal(pJournal, zSuperPtr, nSuperPtr);
      rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
      sqlite3OsClose(pJournal);
      if( rc!=SQLITE_OK ){
        goto delsuper_out;
        goto delmaster_out;
      }

      c = zSuperPtr[0]!=0 && strcmp(zSuperPtr, zSuper)==0;
      c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
      if( c ){
        /* We have a match. Do not delete the super-journal file. */
        goto delsuper_out;
        /* We have a match. Do not delete the master journal file. */
        goto delmaster_out;
      }
    }
    zJournal += (sqlite3Strlen30(zJournal)+1);
  }
 
  sqlite3OsClose(pSuper);
  rc = sqlite3OsDelete(pVfs, zSuper, 0);
  sqlite3OsClose(pMaster);
  rc = sqlite3OsDelete(pVfs, zMaster, 0);

delsuper_out:
  sqlite3_free(zFree);
  if( pSuper ){
    sqlite3OsClose(pSuper);
delmaster_out:
  sqlite3_free(zMasterJournal);
  if( pMaster ){
    sqlite3OsClose(pMaster);
    assert( !isOpen(pJournal) );
    sqlite3_free(pSuper);
    sqlite3_free(pMaster);
  }
  return rc;
}


/*
** This function is used to change the actual size of the database 
2647
2648
2649
2650
2651
2652
2653
2654

2655
2656
2657
2658
2659
2660
2661
2721
2722
2723
2724
2725
2726
2727

2728
2729
2730
2731
2732
2733
2734
2735







-
+







}

/*
** Set the value of the Pager.sectorSize variable for the given
** pager based on the value returned by the xSectorSize method
** of the open database file. The sector size will be used 
** to determine the size and alignment of journal header and 
** super-journal pointers within created journal files.
** master journal pointers within created journal files.
**
** For temporary files the effective sector size is always 512 bytes.
**
** Otherwise, for non-temporary files, the effective sector size is
** the value returned by the xSectorSize() method rounded up to 32 if
** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
** is greater than MAX_SECTOR_SIZE.
2746
2747
2748
2749
2750
2751
2752
2753

2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768


2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781




2782
2783

2784
2785
2786
2787
2788
2789
2790
2820
2821
2822
2823
2824
2825
2826

2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840


2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851




2852
2853
2854
2855
2856

2857
2858
2859
2860
2861
2862
2863
2864







-
+













-
-
+
+









-
-
-
-
+
+
+
+

-
+







  sqlite3_vfs *pVfs = pPager->pVfs;
  i64 szJ;                 /* Size of the journal file in bytes */
  u32 nRec;                /* Number of Records in the journal */
  u32 u;                   /* Unsigned loop counter */
  Pgno mxPg = 0;           /* Size of the original file in pages */
  int rc;                  /* Result code of a subroutine */
  int res = 1;             /* Value returned by sqlite3OsAccess() */
  char *zSuper = 0;        /* Name of super-journal file if any */
  char *zMaster = 0;       /* Name of master journal file if any */
  int needPagerReset;      /* True to reset page prior to first page rollback */
  int nPlayback = 0;       /* Total number of pages restored from journal */
  u32 savedPageSize = pPager->pageSize;

  /* Figure out how many records are in the journal.  Abort early if
  ** the journal is empty.
  */
  assert( isOpen(pPager->jfd) );
  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }

  /* Read the super-journal name from the journal, if it is present.
  ** If a super-journal file name is specified, but the file is not
  /* Read the master journal name from the journal, if it is present.
  ** If a master journal file name is specified, but the file is not
  ** present on disk, then the journal is not hot and does not need to be
  ** played back.
  **
  ** TODO: Technically the following is an error because it assumes that
  ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
  ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
  ** mxPathname is 512, which is the same as the minimum allowable value
  ** for pageSize.
  */
  zSuper = pPager->pTmpSpace;
  rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1);
  if( rc==SQLITE_OK && zSuper[0] ){
    rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res);
  zMaster = pPager->pTmpSpace;
  rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
  if( rc==SQLITE_OK && zMaster[0] ){
    rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
  }
  zSuper = 0;
  zMaster = 0;
  if( rc!=SQLITE_OK || !res ){
    goto end_playback;
  }
  pPager->journalOff = 0;
  needPagerReset = isHot;

  /* This loop terminates either when a readJournalHdr() or 
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915


2916
2917
2918
2919
2920
2921
2922
2923
2924

2925
2926
2927
2928
2929



2930
2931
2932
2933

2934
2935
2936
2937
2938
2939
2940
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







-
-
-
-
-
-
+
+








-
+


-
-
-
+
+
+

-
-
-
+







  ** update the change-counter at all. This may lead to cache inconsistency
  ** problems for other processes at some point in the future. So, just
  ** in case this has happened, clear the changeCountDone flag now.
  */
  pPager->changeCountDone = pPager->tempFile;

  if( rc==SQLITE_OK ){
    /* Leave 4 bytes of space before the super-journal filename in memory.
    ** This is because it may end up being passed to sqlite3OsOpen(), in
    ** which case it requires 4 0x00 bytes in memory immediately before
    ** the filename. */
    zSuper = &pPager->pTmpSpace[4];
    rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1);
    zMaster = pPager->pTmpSpace;
    rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
    testcase( rc!=SQLITE_OK );
  }
  if( rc==SQLITE_OK
   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
  ){
    rc = sqlite3PagerSync(pPager, 0);
  }
  if( rc==SQLITE_OK ){
    rc = pager_end_transaction(pPager, zSuper[0]!='\0', 0);
    rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
    testcase( rc!=SQLITE_OK );
  }
  if( rc==SQLITE_OK && zSuper[0] && res ){
    /* If there was a super-journal and this routine will return success,
    ** see if it is possible to delete the super-journal.
  if( rc==SQLITE_OK && zMaster[0] && res ){
    /* If there was a master journal and this routine will return success,
    ** see if it is possible to delete the master journal.
    */
    assert( zSuper==&pPager->pTmpSpace[4] );
    memset(&zSuper[-4], 0, 4);
    rc = pager_delsuper(pPager, zSuper);
    rc = pager_delmaster(pPager, zMaster);
    testcase( rc!=SQLITE_OK );
  }
  if( isHot && nPlayback ){
    sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
                nPlayback, pPager->zJournal);
  }

3001
3002
3003
3004
3005
3006
3007


3008
3009
3010
3011
3012
3013
3014
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084







+
+







      */
      memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
    }else{
      u8 *dbFileVers = &((u8*)pPg->pData)[24];
      memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
    }
  }
  CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT);

  PAGER_INCR(sqlite3_pager_readdb_count);
  PAGER_INCR(pPager->nRead);
  IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno));
  PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
               PAGERID(pPager), pPg->pgno, pager_pagehash(pPg)));

  return rc;
3305
3306
3307
3308
3309
3310
3311
3312

3313
3314
3315
3316
3317
3318
3319
3375
3376
3377
3378
3379
3380
3381

3382
3383
3384
3385
3386
3387
3388
3389







-
+







  }
  return rc;
}
#endif

/*
** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
** the entire super-journal file. The case pSavepoint==NULL occurs when 
** the entire master journal file. The case pSavepoint==NULL occurs when 
** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction 
** savepoint.
**
** When pSavepoint is not NULL (meaning a non-transaction savepoint is 
** being rolled back), then the rollback consists of up to three stages,
** performed in the order specified:
**
3744
3745
3746
3747
3748
3749
3750

3751
3752
3753
3754
3755
3756
3757
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828







+







  }

  *pPageSize = pPager->pageSize;
  if( rc==SQLITE_OK ){
    if( nReserve<0 ) nReserve = pPager->nReserve;
    assert( nReserve>=0 && nReserve<1000 );
    pPager->nReserve = (i16)nReserve;
    pagerReportSize(pPager);
    pagerFixMaplimit(pPager);
  }
  return rc;
}

/*
** Return a pointer to the "temporary page" buffer held internally
3768
3769
3770
3771
3772
3773
3774
3775

3776
3777
3778
3779
3780
3781
3782
3839
3840
3841
3842
3843
3844
3845

3846
3847
3848
3849
3850
3851
3852
3853







-
+







/*
** Attempt to set the maximum database page count if mxPage is positive. 
** Make no changes if mxPage is zero or negative.  And never reduce the
** maximum page count below the current size of the database.
**
** Regardless of mxPage, return the current maximum page count.
*/
Pgno sqlite3PagerMaxPageCount(Pager *pPager, Pgno mxPage){
int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
  if( mxPage>0 ){
    pPager->mxPgno = mxPage;
  }
  assert( pPager->eState!=PAGER_OPEN );      /* Called only by OP_MaxPgcnt */
  /* assert( pPager->mxPgno>=pPager->dbSize ); */
  /* OP_MaxPgcnt ensures that the parameter passed to this function is not
  ** less than the total number of valid pages in the database. But this
4139
4140
4141
4142
4143
4144
4145





4146
4147
4148
4149
4150
4151
4152
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228







+
+
+
+
+







  enable_simulated_io_errors();
  PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
  IOTRACE(("CLOSE %p\n", pPager))
  sqlite3OsClose(pPager->jfd);
  sqlite3OsClose(pPager->fd);
  sqlite3PageFree(pTmp);
  sqlite3PcacheClose(pPager->pPCache);

#ifdef SQLITE_HAS_CODEC
  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
#endif

  assert( !pPager->aSavepoint && !pPager->pInJournal );
  assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );

  sqlite3_free(pPager);
  return SQLITE_OK;
}

4389
4390
4391
4392
4393
4394
4395

4396

4397
4398
4399
4400
4401
4402
4403
4465
4466
4467
4468
4469
4470
4471
4472

4473
4474
4475
4476
4477
4478
4479
4480







+
-
+







    if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
      i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
      char *pData;                                   /* Data to write */    

      assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
      if( pList->pgno==1 ) pager_write_changecounter(pList);

      /* Encode the database */
      pData = pList->pData;
      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData);

      /* Write out the page data. */
      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);

      /* If page 1 was just written, update Pager.dbFileVers to match
      ** the value now stored in the database file. If writing this 
      ** page caused the database file to grow, update dbFileSize. 
4478
4479
4480
4481
4482
4483
4484






4485
4486
4487
4488
4489
4490
4491
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574







+
+
+
+
+
+








    /* If the sub-journal was opened successfully (or was already open),
    ** write the journal record into the file.  */
    if( rc==SQLITE_OK ){
      void *pData = pPg->pData;
      i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
      char *pData2;

#if SQLITE_HAS_CODEC   
      if( !pPager->subjInMemory ){
        CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
      }else
#endif
      pData2 = pData;
      PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
      rc = write32bits(pPager->sjfd, offset, pPg->pgno);
      if( rc==SQLITE_OK ){
        rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
      }
    }
4673
4674
4675
4676
4677
4678
4679
4680
4681

4682
4683
4684
4685
4686
4687
4688
4756
4757
4758
4759
4760
4761
4762


4763
4764
4765
4766
4767
4768
4769
4770







-
-
+







  int journalFileSize;     /* Bytes to allocate for each journal fd */
  char *zPathname = 0;     /* Full path to database file */
  int nPathname = 0;       /* Number of bytes in zPathname */
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
  int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
  u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
  const char *zUri = 0;    /* URI args to copy */
  int nUriByte = 1;        /* Number of bytes of URI args at *zUri */
  int nUri = 0;            /* Number of URI parameters */
  int nUri = 0;            /* Number of bytes of URI args at *zUri */

  /* Figure out how much space is required for each journal file-handle
  ** (there are two of them, the main journal and the sub-journal).  */
  journalFileSize = ROUND8(sqlite3JournalSize(pVfs));

  /* Set the output variable to NULL in case an error occurs. */
  *ppPager = 0;
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728


4729
4730
4731
4732


4733
4734
4735
4736
4737
4738
4739
4790
4791
4792
4793
4794
4795
4796









4797
4798
4799


4800
4801

4802


4803
4804
4805
4806
4807
4808
4809
4810
4811







-
-
-
-
-
-
-
-
-



-
-
+
+
-

-
-
+
+







    nPathname = pVfs->mxPathname+1;
    zPathname = sqlite3DbMallocRaw(0, nPathname*2);
    if( zPathname==0 ){
      return SQLITE_NOMEM_BKPT;
    }
    zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
    rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
    if( rc!=SQLITE_OK ){
      if( rc==SQLITE_OK_SYMLINK ){
        if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){
          rc = SQLITE_CANTOPEN_SYMLINK;
        }else{
          rc = SQLITE_OK;
        }
      }
    }
    nPathname = sqlite3Strlen30(zPathname);
    z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
    while( *z ){
      z += strlen(z)+1;
      z += strlen(z)+1;
      z += sqlite3Strlen30(z)+1;
      z += sqlite3Strlen30(z)+1;
      nUri++;
    }
    nUriByte = (int)(&z[1] - zUri);
    assert( nUriByte>=1 );
    nUri = (int)(&z[1] - zUri);
    assert( nUri>=0 );
    if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
      /* This branch is taken when the journal path required by
      ** the database being opened will be more than pVfs->mxPathname
      ** bytes in length. This means the database cannot be opened,
      ** as it will not be possible to open the journal file or even
      ** check for a hot-journal before reading.
      */
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
4822
4823
4824
4825
4826
4827
4828


4829


4830





























4831
4832




4833
4834
4835
4836



4837


4838
4839

4840
4841

4842
4843
4844
4845
4846
4847
4848


4849
4850



4851
4852
4853
4854

4855

4856



4857













4858
4859
4860




4861
4862



4863


4864
4865





4866
4867
4868


4869

4870


4871
4872



4873
4874
4875
4876
4877
4878
4879







-
-

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


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

-
+

-






+
-
-
+
+
-
-
-
+
+
+

-

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

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

-
-
+

-
-
-







  ** file name. The layout in memory is as follows:
  **
  **     Pager object                    (sizeof(Pager) bytes)
  **     PCache object                   (sqlite3PcacheSize() bytes)
  **     Database file handle            (pVfs->szOsFile bytes)
  **     Sub-journal file handle         (journalFileSize bytes)
  **     Main journal file handle        (journalFileSize bytes)
  **     Ptr back to the Pager           (sizeof(Pager*) bytes)
  **     \0\0\0\0 database prefix        (4 bytes)
  **     Database file name              (nPathname+1 bytes)
  **     URI query parameters            (nUriByte bytes)
  **     Journal filename                (nPathname+8+1 bytes)
  **     Journal file name               (nPathname+8+1 bytes)
  **     WAL filename                    (nPathname+4+1 bytes)
  **     \0\0\0 terminator               (3 bytes)
  **
  ** Some 3rd-party software, over which we have no control, depends on
  ** the specific order of the filenames and the \0 separators between them
  ** so that it can (for example) find the database filename given the WAL
  ** filename without using the sqlite3_filename_database() API.  This is a
  ** misuse of SQLite and a bug in the 3rd-party software, but the 3rd-party
  ** software is in widespread use, so we try to avoid changing the filename
  ** order and formatting if possible.  In particular, the details of the
  ** filename format expected by 3rd-party software should be as follows:
  **
  **   - Main Database Path
  **   - \0
  **   - Multiple URI components consisting of:
  **     - Key
  **     - \0
  **     - Value
  **     - \0
  **   - \0
  **   - Journal Path
  **   - \0
  **   - WAL Path (zWALName)
  **   - \0
  **
  ** The sqlite3_create_filename() interface and the databaseFilename() utility
  ** that is used by sqlite3_filename_database() and kin also depend on the
  ** specific formatting and order of the various filenames, so if the format
  ** changes here, be sure to change it there as well.
  */
  pPtr = (u8 *)sqlite3MallocZero(
    ROUND8(sizeof(*pPager)) +            /* Pager structure */
    ROUND8(pcacheSize) +                 /* PCache object */
    ROUND8(pVfs->szOsFile) +             /* The main db file */
    journalFileSize * 2 +                /* The two journal files */
    ROUND8(sizeof(*pPager)) +      /* Pager structure */
    ROUND8(pcacheSize) +           /* PCache object */
    ROUND8(pVfs->szOsFile) +       /* The main db file */
    journalFileSize * 2 +          /* The two journal files */ 
    sizeof(pPager) +                     /* Space to hold a pointer */
    4 +                                  /* Database prefix */
    nPathname + 1 +                      /* database filename */
    nPathname + 1 + nUri +         /* zFilename */
    nUriByte +                           /* query parameters */
    nPathname + 8 + 1 +                  /* Journal filename */
    nPathname + 8 + 2              /* zJournal */
#ifndef SQLITE_OMIT_WAL
    nPathname + 4 + 1 +                  /* WAL filename */
    + nPathname + 4 + 2            /* zWal */
#endif
    3                                    /* Terminator */
  );
  assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
  if( !pPtr ){
    sqlite3DbFree(0, zPathname);
    return SQLITE_NOMEM_BKPT;
  }
  pPager =              (Pager*)(pPtr);
  pPager = (Pager*)pPtr;                  pPtr += ROUND8(sizeof(*pPager));
  pPager->pPCache = (PCache*)pPtr;        pPtr += ROUND8(pcacheSize);
  pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
  pPager->fd =   (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
  pPager->fd = (sqlite3_file*)pPtr;       pPtr += ROUND8(pVfs->szOsFile);
  pPager->sjfd = (sqlite3_file*)pPtr;     pPtr += journalFileSize;
  pPager->jfd =  (sqlite3_file*)pPtr;     pPtr += journalFileSize;
  pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
  pPager->jfd =  (sqlite3_file*)(pPtr += journalFileSize);
  pPager->zFilename =    (char*)(pPtr += journalFileSize);
  assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
  memcpy(pPtr, &pPager, sizeof(pPager));  pPtr += sizeof(pPager);

  /* Fill in the Pager.zFilename and pPager.zQueryParam fields */
  /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
                                          pPtr += 4;  /* Skip zero prefix */
  pPager->zFilename = (char*)pPtr;
  if( nPathname>0 ){
  if( zPathname ){
    memcpy(pPtr, zPathname, nPathname);   pPtr += nPathname + 1;
    if( zUri ){
      memcpy(pPtr, zUri, nUriByte);       pPtr += nUriByte;
    }else{
                                          pPtr++;
    }
  }


  /* Fill in Pager.zJournal */
  if( nPathname>0 ){
    pPager->zJournal = (char*)pPtr;
    memcpy(pPtr, zPathname, nPathname);   pPtr += nPathname;
    assert( nPathname>0 );
    pPager->zJournal =   (char*)(pPtr += nPathname + 1 + nUri);
    memcpy(pPager->zFilename, zPathname, nPathname);
    memcpy(pPtr, "-journal",8);           pPtr += 8 + 1;
#ifdef SQLITE_ENABLE_8_3_NAMES
    sqlite3FileSuffix3(zFilename,pPager->zJournal);
    pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1);
    if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
    memcpy(pPager->zJournal, zPathname, nPathname);
#endif
  }else{
    pPager->zJournal = 0;
    memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
  }

    sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
  /* Fill in Pager.zWal */
  if( nPathname>0 ){
    pPager->zWal = (char*)pPtr;
    memcpy(pPtr, zPathname, nPathname);   pPtr += nPathname;
    memcpy(pPtr, "-wal", 4);              pPtr += 4 + 1;
    pPager->zWal = &pPager->zJournal[nPathname+8+1];
    memcpy(pPager->zWal, zPathname, nPathname);
    memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
#ifdef SQLITE_ENABLE_8_3_NAMES
    sqlite3FileSuffix3(zFilename, pPager->zWal);
    sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
    pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1);
#endif
  }else{
    pPager->zWal = 0;
    sqlite3DbFree(0, zPathname);
  }
#endif

  if( nPathname ) sqlite3DbFree(0, zPathname);
  pPager->pVfs = pVfs;
  pPager->vfsFlags = vfsFlags;

  /* Open the pager file.
  */
  if( zFilename && zFilename[0] ){
    int fout = 0;                    /* VFS flags returned by xOpen() */
4903
4904
4905
4906
4907
4908
4909
4910

4911
4912

4913
4914
4915
4916
4917
4918
4919
4914
4915
4916
4917
4918
4919
4920

4921
4922

4923
4924
4925
4926
4927
4928
4929
4930







-
+

-
+







            if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
              szPageDflt = ii;
            }
          }
        }
#endif
      }
      pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0);
      pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
      if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
       || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){
       || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
          vfsFlags |= SQLITE_OPEN_READONLY;
          goto act_like_temp_file;
      }
    }
  }else{
    /* If a temporary file is requested, it is not opened immediately.
    ** In this case we accept the default page size and delay actually
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
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







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




















-
-
+
+







  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
  /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */

  *ppPager = pPager;
  return SQLITE_OK;
}

/*
** Return the sqlite3_file for the main database given the name
** of the corresonding WAL or Journal name as passed into
** xOpen.
*/
sqlite3_file *sqlite3_database_file_object(const char *zName){
  Pager *pPager;
  while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
    zName--;
  }
  pPager = *(Pager**)(zName - 4 - sizeof(Pager*));
  return pPager->fd;
}


/*
** This function is called after transitioning from PAGER_UNLOCK to
** PAGER_SHARED state. It tests if there is a hot journal present in
** the file-system for the given pager. A hot journal is one that 
** needs to be played back. According to this function, a hot-journal
** file exists if the following criteria are met:
**
**   * The journal file exists in the file system, and
**   * No process holds a RESERVED or greater lock on the database file, and
**   * The database file itself is greater than 0 bytes in size, and
**   * The first byte of the journal file exists and is not 0x00.
**
** If the current size of the database file is 0 but a journal file
** exists, that is probably an old journal left over from a prior
** database with the same name. In this case the journal file is
** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
** is returned.
**
** This routine does not check if there is a super-journal filename
** at the end of the file. If there is, and that super-journal file
** This routine does not check if there is a master journal filename
** at the end of the file. If there is, and that master journal file
** does not exist, then the journal file is not really hot. In this
** case this routine will return a false-positive. The pager_playback()
** routine will discover that the journal file is not really hot and 
** will not roll it back. 
**
** If a hot-journal file is found to exist, *pExists is set to 1 and 
** SQLITE_OK returned. If no hot-journal file is present, *pExists is
5495
5496
5497
5498
5499
5500
5501
5502

5503
5504
5505
5506
5507
5508
5509
5510

5511
5512
5513

5514
5515
5516
5517
5518
5519
5520
5493
5494
5495
5496
5497
5498
5499

5500
5501
5502
5503
5504
5505
5506
5507

5508
5509
5510

5511
5512
5513
5514
5515
5516
5517
5518







-
+







-
+


-
+







  assert( pPg->pgno==pgno );
  assert( pPg->pPager==pPager || pPg->pPager==0 );

  noContent = (flags & PAGER_GET_NOCONTENT)!=0;
  if( pPg->pPager && !noContent ){
    /* In this case the pcache already contains an initialized copy of
    ** the page. Return without further ado.  */
    assert( pgno!=PAGER_MJ_PGNO(pPager) );
    assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
    pPager->aStat[PAGER_STAT_HIT]++;
    return SQLITE_OK;

  }else{
    /* The pager cache has created a new page. Its content needs to 
    ** be initialized. But first some error checks:
    **
    ** (*) obsolete.  Was: maximum page number is 2^31
    ** (1) The maximum page number is 2^31
    ** (2) Never try to fetch the locking page
    */
    if( pgno==PAGER_MJ_PGNO(pPager) ){
    if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
      rc = SQLITE_CORRUPT_BKPT;
      goto pager_acquire_err;
    }

    pPg->pPager = pPager;

    assert( !isOpen(pPager->fd) || !MEMDB );
5580
5581
5582
5583
5584
5585
5586



5587
5588
5589
5590
5591
5592
5593
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594







+
+
+







  ** flag was specified by the caller. And so long as the db is not a 
  ** temporary or in-memory database.  */
  const int bMmapOk = (pgno>1
   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
  );

  assert( USEFETCH(pPager) );
#ifdef SQLITE_HAS_CODEC
  assert( pPager->xCodec==0 );
#endif

  /* Optimization note:  Adding the "pgno<=1" term before "pgno==0" here
  ** allows the compiler optimizer to reuse the results of the "pgno>1"
  ** test in the previous statement, and avoid testing pgno==0 in the
  ** common case where pgno is large. */
  if( pgno<=1 && pgno==0 ){
    return SQLITE_CORRUPT_BKPT;
5710
5711
5712
5713
5714
5715
5716

5717
5718
5719
5720
5721
5722
5723
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725







+







}
void sqlite3PagerUnrefPageOne(DbPage *pPg){
  Pager *pPager;
  assert( pPg!=0 );
  assert( pPg->pgno==1 );
  assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
  pPager = pPg->pPager;
  sqlite3PagerResetLockTimeout(pPager);
  sqlite3PcacheRelease(pPg);
  pagerUnlockIfUnused(pPager);
}

/*
** This function is called at the start of every write transaction.
** There must already be a RESERVED or EXCLUSIVE lock on the database 
5791
5792
5793
5794
5795
5796
5797
5798

5799
5800
5801
5802
5803
5804
5805
5793
5794
5795
5796
5797
5798
5799

5800
5801
5802
5803
5804
5805
5806
5807







-
+







    /* Write the first journal header to the journal file and open 
    ** the sub-journal if necessary.
    */
    if( rc==SQLITE_OK ){
      /* TODO: Check if all of these are really required. */
      pPager->nRec = 0;
      pPager->journalOff = 0;
      pPager->setSuper = 0;
      pPager->setMaster = 0;
      pPager->journalHdr = 0;
      rc = writeJournalHdr(pPager);
    }
  }

  if( rc!=SQLITE_OK ){
    sqlite3BitvecDestroy(pPager->pInJournal);
5907
5908
5909
5910
5911
5912
5913
5914

5915
5916
5917
5918
5919
5920
5921
5909
5910
5911
5912
5913
5914
5915

5916
5917
5918
5919
5920
5921
5922
5923







-
+








  /* We should never write to the journal file the page that
  ** contains the database locks.  The following assert verifies
  ** that we do not. */
  assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );

  assert( pPager->journalHdr<=pPager->journalOff );
  pData2 = pPg->pData;
  CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
  cksum = pager_cksum(pPager, (u8*)pData2);

  /* Even if an IO or diskfull error occurs while journalling the
  ** page in the block above, set the need-sync flag for the page.
  ** Otherwise, when the transaction is rolled back, the logic in
  ** playback_one_page() will think that the page needs to be restored
  ** in the database file. And if an IO error occurs while doing so,
6272
6273
6274
6275
6276
6277
6278
6279

6280
6281
6282
6283
6284
6285
6286
6274
6275
6276
6277
6278
6279
6280

6281
6282
6283
6284
6285
6286
6287
6288







-
+







      /* Actually do the update of the change counter */
      pager_write_changecounter(pPgHdr);

      /* If running in direct mode, write the contents of page 1 to the file. */
      if( DIRECT_MODE ){
        const void *zBuf;
        assert( pPager->dbFileSize>0 );
        zBuf = pPgHdr->pData;
        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf);
        if( rc==SQLITE_OK ){
          rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
          pPager->aStat[PAGER_STAT_WRITE]++;
        }
        if( rc==SQLITE_OK ){
          /* Update the pager's copy of the change-counter. Otherwise, the
          ** next time a read transaction is opened the cache will be
6303
6304
6305
6306
6307
6308
6309
6310

6311
6312

6313
6314
6315
6316
6317
6318
6319
6305
6306
6307
6308
6309
6310
6311

6312
6313

6314
6315
6316
6317
6318
6319
6320
6321







-
+

-
+







/*
** Sync the database file to disk. This is a no-op for in-memory databases
** or pages with the Pager.noSync flag set.
**
** If successful, or if called on a pager for which it is a no-op, this
** function returns SQLITE_OK. Otherwise, an IO error code is returned.
*/
int sqlite3PagerSync(Pager *pPager, const char *zSuper){
int sqlite3PagerSync(Pager *pPager, const char *zMaster){
  int rc = SQLITE_OK;
  void *pArg = (void*)zSuper;
  void *pArg = (void*)zMaster;
  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
  if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
  if( rc==SQLITE_OK && !pPager->noSync ){
    assert( !MEMDB );
    rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
  }
  return rc;
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
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







-
-
-
-
+
+
+
+











-
+

-
+









-
+

















-
-
+
+







      rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
    }
  }
  return rc;
}

/*
** Sync the database file for the pager pPager. zSuper points to the name
** of a super-journal file that should be written into the individual
** journal file. zSuper may be NULL, which is interpreted as no 
** super-journal (a single database transaction).
** Sync the database file for the pager pPager. zMaster points to the name
** of a master journal file that should be written into the individual
** journal file. zMaster may be NULL, which is interpreted as no master
** journal (a single database transaction).
**
** This routine ensures that:
**
**   * The database file change-counter is updated,
**   * the journal is synced (unless the atomic-write optimization is used),
**   * all dirty pages are written to the database file, 
**   * the database file is truncated (if required), and
**   * the database file synced. 
**
** The only thing that remains to commit the transaction is to finalize 
** (delete, truncate or zero the first part of) the journal file (or 
** delete the super-journal file if specified).
** delete the master journal file if specified).
**
** Note that if zSuper==NULL, this does not overwrite a previous value
** Note that if zMaster==NULL, this does not overwrite a previous value
** passed to an sqlite3PagerCommitPhaseOne() call.
**
** If the final parameter - noSync - is true, then the database file itself
** is not synced. The caller must call sqlite3PagerSync() directly to
** sync the database file before calling CommitPhaseTwo() to delete the
** journal file in this case.
*/
int sqlite3PagerCommitPhaseOne(
  Pager *pPager,                  /* Pager object */
  const char *zSuper,            /* If not NULL, the super-journal name */
  const char *zMaster,            /* If not NULL, the master journal name */
  int noSync                      /* True to omit the xSync on the db file */
){
  int rc = SQLITE_OK;             /* Return code */

  assert( pPager->eState==PAGER_WRITER_LOCKED
       || pPager->eState==PAGER_WRITER_CACHEMOD
       || pPager->eState==PAGER_WRITER_DBMOD
       || pPager->eState==PAGER_ERROR
  );
  assert( assert_pager_state(pPager) );

  /* If a prior error occurred, report that error again. */
  if( NEVER(pPager->errCode) ) return pPager->errCode;

  /* Provide the ability to easily simulate an I/O error during testing */
  if( sqlite3FaultSim(400) ) return SQLITE_IOERR;

  PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n", 
      pPager->zFilename, zSuper, pPager->dbSize));
  PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
      pPager->zFilename, zMaster, pPager->dbSize));

  /* If no database changes have been made, return early. */
  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;

  assert( MEMDB==0 || pPager->tempFile );
  assert( isOpen(pPager->fd) || pPager->tempFile );
  if( 0==pagerFlushOnCommit(pPager, 1) ){
6428
6429
6430
6431
6432
6433
6434
6435

6436
6437
6438
6439
6440
6441
6442
6430
6431
6432
6433
6434
6435
6436

6437
6438
6439
6440
6441
6442
6443
6444







-
+







    }else{
      /* The bBatch boolean is true if the batch-atomic-write commit method
      ** should be used.  No rollback journal is created if batch-atomic-write
      ** is enabled.
      */
#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
      sqlite3_file *fd = pPager->fd;
      int bBatch = zSuper==0    /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
      int bBatch = zMaster==0    /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
        && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC)
        && !pPager->noSync
        && sqlite3JournalIsInMemory(pPager->jfd);
#else
#     define bBatch 0
#endif

6466
6467
6468
6469
6470
6471
6472
6473

6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494

6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506



6507
6508

6509
6510
6511
6512
6513
6514
6515
6468
6469
6470
6471
6472
6473
6474

6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495

6496
6497
6498
6499
6500
6501
6502
6503
6504
6505



6506
6507
6508
6509

6510
6511
6512
6513
6514
6515
6516
6517







-
+




















-
+









-
-
-
+
+
+

-
+







      */
      if( bBatch==0 ){
        PgHdr *pPg;
        assert( isOpen(pPager->jfd) 
            || pPager->journalMode==PAGER_JOURNALMODE_OFF 
            || pPager->journalMode==PAGER_JOURNALMODE_WAL 
            );
        if( !zSuper && isOpen(pPager->jfd) 
        if( !zMaster && isOpen(pPager->jfd) 
         && pPager->journalOff==jrnlBufferSize(pPager) 
         && pPager->dbSize>=pPager->dbOrigSize
         && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
        ){
          /* Update the db file change counter via the direct-write method. The 
          ** following call will modify the in-memory representation of page 1 
          ** to include the updated change counter and then write page 1 
          ** directly to the database file. Because of the atomic-write 
          ** property of the host file-system, this is safe.
          */
          rc = pager_incr_changecounter(pPager, 1);
        }else{
          rc = sqlite3JournalCreate(pPager->jfd);
          if( rc==SQLITE_OK ){
            rc = pager_incr_changecounter(pPager, 0);
          }
        }
      }
#else  /* SQLITE_ENABLE_ATOMIC_WRITE */
#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
      if( zSuper ){
      if( zMaster ){
        rc = sqlite3JournalCreate(pPager->jfd);
        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
        assert( bBatch==0 );
      }
#endif
      rc = pager_incr_changecounter(pPager, 0);
#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */
      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  
      /* Write the super-journal name into the journal file. If a
      ** super-journal file name has already been written to the journal file, 
      ** or if zSuper is NULL (no super-journal), then this call is a no-op.
      /* Write the master journal name into the journal file. If a master 
      ** journal file name has already been written to the journal file, 
      ** or if zMaster is NULL (no master journal), then this call is a no-op.
      */
      rc = writeSuperJournal(pPager, zSuper);
      rc = writeMasterJournal(pPager, zMaster);
      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  
      /* Sync the journal file and write all dirty pages to the database.
      ** If the atomic-update optimization is being used, this sync will not 
      ** create the journal file or perform any real IO.
      **
      ** Because the change-counter page was just modified, unless the
6569
6570
6571
6572
6573
6574
6575
6576

6577
6578
6579
6580
6581
6582
6583
6571
6572
6573
6574
6575
6576
6577

6578
6579
6580
6581
6582
6583
6584
6585







-
+







        assert( pPager->eState==PAGER_WRITER_DBMOD );
        rc = pager_truncate(pPager, nNew);
        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
      }
  
      /* Finally, sync the database file. */
      if( !noSync ){
        rc = sqlite3PagerSync(pPager, zSuper);
        rc = sqlite3PagerSync(pPager, zMaster);
      }
      IOTRACE(("DBSYNC %p\n", pPager))
    }
  }

commit_phase_one_exit:
  if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6607
6608
6609
6610
6611
6612
6613

6614
6615
6616
6617
6618
6619
6620







-







int sqlite3PagerCommitPhaseTwo(Pager *pPager){
  int rc = SQLITE_OK;                  /* Return code */

  /* This routine should not be called if a prior error has occurred.
  ** But if (due to a coding error elsewhere in the system) it does get
  ** called, just return the same error code without doing anything. */
  if( NEVER(pPager->errCode) ) return pPager->errCode;
  pPager->iDataVersion++;

  assert( pPager->eState==PAGER_WRITER_LOCKED
       || pPager->eState==PAGER_WRITER_FINISHED
       || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
  );
  assert( assert_pager_state(pPager) );

6634
6635
6636
6637
6638
6639
6640

6641

6642
6643
6644
6645
6646
6647
6648
6635
6636
6637
6638
6639
6640
6641
6642

6643
6644
6645
6646
6647
6648
6649
6650







+
-
+







  ){
    assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff );
    pPager->eState = PAGER_READER;
    return SQLITE_OK;
  }

  PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
  pPager->iDataVersion++;
  rc = pager_end_transaction(pPager, pPager->setSuper, 1);
  rc = pager_end_transaction(pPager, pPager->setMaster, 1);
  return pager_error(pPager, rc);
}

/*
** If a write transaction is open, then all changes made within the 
** transaction are reverted and the current write-transaction is closed.
** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR
6679
6680
6681
6682
6683
6684
6685
6686

6687
6688
6689
6690
6691
6692
6693
6681
6682
6683
6684
6685
6686
6687

6688
6689
6690
6691
6692
6693
6694
6695







-
+







  assert( assert_pager_state(pPager) );
  if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
  if( pPager->eState<=PAGER_READER ) return SQLITE_OK;

  if( pagerUseWal(pPager) ){
    int rc2;
    rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
    rc2 = pager_end_transaction(pPager, pPager->setSuper, 0);
    rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
    if( rc==SQLITE_OK ) rc = rc2;
  }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
    int eState = pPager->eState;
    rc = pager_end_transaction(pPager, 0, 0);
    if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
      /* This can happen using journal_mode=off. Move the pager to the error 
      ** state to indicate that the contents of the cache may not be trusted.
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6850
6851
6852
6853
6854
6855
6856

6857
6858
6859
6860
6861
6862
6863







-







    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;
6930
6931
6932
6933
6934
6935
6936
6937
6938

6939
6940
6941
6942

6943
6944
6945

6946
6947
6948
6949
6950
6951
6952
6931
6932
6933
6934
6935
6936
6937


6938
6939
6940


6941
6942
6943

6944
6945
6946
6947
6948
6949
6950
6951







-
-
+


-
-
+


-
+







      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) ){
      if( nNew==0 && 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);
          rc = sqlite3OsTruncate(pPager->sjfd, 0);
          assert( rc==SQLITE_OK );
        }
        pPager->nSubRec = pRel->iSubRec;
        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.
    */
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991

6992
6993

6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010










7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
















































7031
7032
7033
7034
7035
7036
7037
6979
6980
6981
6982
6983
6984
6985



6986

6987


6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090







-
-
-

-
+
-
-
+

















+
+
+
+
+
+
+
+
+
+




















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







**
** Except, if the pager is in-memory only, then return an empty string if
** nullIfMemDb is true.  This routine is called with nullIfMemDb==1 when
** used to report the filename to the user, for compatibility with legacy
** behavior.  But when the Btree needs to know the filename for matching to
** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
** participate in shared-cache.
**
** The return value to this routine is always safe to use with
** sqlite3_uri_parameter() and sqlite3_filename_database() and friends.
*/
const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){
const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
  static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename;
  return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
}

/*
** Return the VFS structure for the pager.
*/
sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
  return pPager->pVfs;
}

/*
** Return the file handle for the database file associated
** with the pager.  This might return NULL if the file has
** not yet been opened.
*/
sqlite3_file *sqlite3PagerFile(Pager *pPager){
  return pPager->fd;
}

#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** Reset the lock timeout for pager.
*/
void sqlite3PagerResetLockTimeout(Pager *pPager){
  int x = 0;
  sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
}
#endif

/*
** Return the file handle for the journal file (if it exists).
** This will be either the rollback journal or the WAL file.
*/
sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
#if SQLITE_OMIT_WAL
  return pPager->jfd;
#else
  return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd;
#endif
}

/*
** Return the full pathname of the journal file.
*/
const char *sqlite3PagerJournalname(Pager *pPager){
  return pPager->zJournal;
}

#ifdef SQLITE_HAS_CODEC
/*
** Set or retrieve the codec for this pager
*/
void sqlite3PagerSetCodec(
  Pager *pPager,
  void *(*xCodec)(void*,void*,Pgno,int),
  void (*xCodecSizeChng)(void*,int,int),
  void (*xCodecFree)(void*),
  void *pCodec
){
  if( pPager->xCodecFree ){
    pPager->xCodecFree(pPager->pCodec);
  }else{
    pager_reset(pPager);
  }
  pPager->xCodec = pPager->memDb ? 0 : xCodec;
  pPager->xCodecSizeChng = xCodecSizeChng;
  pPager->xCodecFree = xCodecFree;
  pPager->pCodec = pCodec;
  setGetterMethod(pPager);
  pagerReportSize(pPager);
}
void *sqlite3PagerGetCodec(Pager *pPager){
  return pPager->pCodec;
}

/*
** This function is called by the wal module when writing page content
** into the log file.
**
** This function returns a pointer to a buffer containing the encrypted
** page content. If a malloc fails, this function may return NULL.
*/
void *sqlite3PagerCodec(PgHdr *pPg){
  void *aData = 0;
  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
  return aData;
}

/*
** Return the current pager state
*/
int sqlite3PagerState(Pager *pPager){
  return pPager->eState;
}
#endif /* SQLITE_HAS_CODEC */

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Move the page pPg to location pgno in the file.
**
** There must be no references to the page previously located at
** pgno (which we call pPgOld) though that page is allowed to be
** in cache.  If the page previously located at pgno is not already
7418
7419
7420
7421
7422
7423
7424

7425
7426
7427
7428
7429
7430
7431
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485







+







  if( pPager->pWal ){
    rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
        (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
        pPager->pBusyHandlerArg,
        pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
        pnLog, pnCkpt
    );
    sqlite3PagerResetLockTimeout(pPager);
  }
  return rc;
}

int sqlite3PagerWalCallback(Pager *pPager){
  return sqlite3WalCallback(pPager->pWal);
}
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633

7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7636
7637
7638
7639
7640
7641
7642


























7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660

7661



7662
7663
7664
7665
7666
7667
7668







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


















-
+
-
-
-







      pagerFixMaplimit(pPager);
      if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
    }
  }
  return rc;
}

#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** If pager pPager is a wal-mode database not in exclusive locking mode,
** invoke the sqlite3WalWriteLock() function on the associated Wal object 
** with the same db and bLock parameters as were passed to this function.
** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
*/
int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){
  int rc = SQLITE_OK;
  if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){
    rc = sqlite3WalWriteLock(pPager->pWal, bLock);
  }
  return rc;
}

/*
** Set the database handle used by the wal layer to determine if 
** blocking locks are required.
*/
void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
  if( pagerUseWal(pPager) ){
    sqlite3WalDb(pPager->pWal, db);
  }
}
#endif

#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** If this is a WAL database, obtain a snapshot handle for the snapshot
** currently open. Otherwise, return an error.
*/
int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){
  int rc = SQLITE_ERROR;
  if( pPager->pWal ){
    rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot);
  }
  return rc;
}

/*
** If this is a WAL database, store a pointer to pSnapshot. Next time a
** read transaction is opened, attempt to read from the snapshot it 
** identifies. If this is not a WAL database, return an error.
*/
int sqlite3PagerSnapshotOpen(
int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
  Pager *pPager, 
  sqlite3_snapshot *pSnapshot
){
  int rc = SQLITE_OK;
  if( pPager->pWal ){
    sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
  }else{
    rc = SQLITE_ERROR;
  }
  return rc;

Changes to src/pager.h.

42
43
44
45
46
47
48
49
50


51
52
53
54
55
56
57
42
43
44
45
46
47
48


49
50
51
52
53
54
55
56
57







-
-
+
+







*/
typedef struct PgHdr DbPage;

/*
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
** reserved for working around a windows/posix incompatibility). It is
** used in the journal to signify that the remainder of the journal file 
** is devoted to storing a super-journal name - there are no more pages to
** roll back. See comments for function writeSuperJournal() in pager.c 
** is devoted to storing a master journal name - there are no more pages to
** roll back. See comments for function writeMasterJournal() in pager.c 
** for details.
*/
#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))

/*
** Allowed values for the flags parameter to sqlite3PagerOpen().
**
124
125
126
127
128
129
130



131

132
133
134
135
136
137
138
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141







+
+
+
-
+







);
int sqlite3PagerClose(Pager *pPager, sqlite3*);
int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);

/* Functions used to configure a Pager object. */
void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *);
int sqlite3PagerSetPagesize(Pager*, u32*, int);
#ifdef SQLITE_HAS_CODEC
void sqlite3PagerAlignReserve(Pager*,Pager*);
#endif
Pgno sqlite3PagerMaxPageCount(Pager*, Pgno);
int sqlite3PagerMaxPageCount(Pager*, int);
void sqlite3PagerSetCachesize(Pager*, int);
int sqlite3PagerSetSpillsize(Pager*, int);
void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
void sqlite3PagerShrink(Pager*);
void sqlite3PagerSetFlags(Pager*,unsigned);
int sqlite3PagerLockingMode(Pager *, int);
int sqlite3PagerSetJournalMode(Pager *, int);
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
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







-
+

-
+













-
-
+
+






-
-
-
-
-
-
-
-















-
+









+
+
+
+
+





+
+
+
+







int sqlite3PagerPageRefcount(DbPage*);
void *sqlite3PagerGetData(DbPage *); 
void *sqlite3PagerGetExtra(DbPage *); 

/* Functions used to manage pager transactions and savepoints. */
void sqlite3PagerPagecount(Pager*, int*);
int sqlite3PagerBegin(Pager*, int exFlag, int);
int sqlite3PagerCommitPhaseOne(Pager*,const char *zSuper, int);
int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
int sqlite3PagerExclusiveLock(Pager*);
int sqlite3PagerSync(Pager *pPager, const char *zSuper);
int sqlite3PagerSync(Pager *pPager, const char *zMaster);
int sqlite3PagerCommitPhaseTwo(Pager*);
int sqlite3PagerRollback(Pager*);
int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
int sqlite3PagerSharedLock(Pager *pPager);

#ifndef SQLITE_OMIT_WAL
  int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
  int sqlite3PagerWalSupported(Pager *pPager);
  int sqlite3PagerWalCallback(Pager *pPager);
  int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
  int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
# ifdef SQLITE_ENABLE_SNAPSHOT
  int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot);
  int sqlite3PagerSnapshotOpen(Pager*, sqlite3_snapshot *pSnapshot);
  int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
  int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
  int sqlite3PagerSnapshotRecover(Pager *pPager);
  int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
  void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
#endif

#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_ENABLE_SETLK_TIMEOUT)
  int sqlite3PagerWalWriteLock(Pager*, int);
  void sqlite3PagerWalDb(Pager*, sqlite3*);
#else
# define sqlite3PagerWalWriteLock(y,z) SQLITE_OK
# define sqlite3PagerWalDb(x,y)
#endif

#ifdef SQLITE_DIRECT_OVERFLOW_READ
  int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif

#ifdef SQLITE_ENABLE_ZIPVFS
  int sqlite3PagerWalFramesize(Pager *pPager);
#endif

/* Functions used to query pager state and configuration. */
u8 sqlite3PagerIsreadonly(Pager*);
u32 sqlite3PagerDataVersion(Pager*);
#ifdef SQLITE_DEBUG
  int sqlite3PagerRefcount(Pager*);
#endif
int sqlite3PagerMemUsed(Pager*);
const char *sqlite3PagerFilename(const Pager*, int);
const char *sqlite3PagerFilename(Pager*, int);
sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*);
sqlite3_file *sqlite3PagerJrnlFile(Pager*);
const char *sqlite3PagerJournalname(Pager*);
void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerIsMemdb(Pager*);
void sqlite3PagerCacheStat(Pager *, int, int, int *);
void sqlite3PagerClearCache(Pager*);
int sqlite3SectorSize(sqlite3_file *);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
void sqlite3PagerResetLockTimeout(Pager *pPager);
#else
# define sqlite3PagerResetLockTimeout(X)
#endif

/* Functions used to truncate the database file. */
void sqlite3PagerTruncateImage(Pager*,Pgno);

void sqlite3PagerRekey(DbPage*, Pgno, u16);

#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
void *sqlite3PagerCodec(DbPage *);
#endif

/* Functions to support testing and debugging. */
#if !defined(NDEBUG) || defined(SQLITE_TEST)
  Pgno sqlite3PagerPagenumber(DbPage*);
  int sqlite3PagerIswriteable(DbPage*);
#endif
#ifdef SQLITE_TEST

Changes to src/parse.y.

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

1

2
3
4
5
6
7
8
9
10
11


12
13



14



15
16

17
18
19
20
21
22
23
-

-
+









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

-







%include {
/*
** 2001-09-15
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains SQLite's SQL parser.
**
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** The canonical source code to this file ("parse.y") is a Lemon grammar 
** file that specifies the input grammar and actions to take while parsing.
** That input file is processed by Lemon to generate a C-language 
** the parser.  Lemon will also generate a header file containing
** implementation of a parser for the given grammer.  You might be reading
** this comment as part of the translated C-code.  Edits should be made
** to the original parse.y sources.
** numeric codes for all of the tokens.
*/
}

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
//
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
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







-

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










-
+







struct FrameBound     { int eType; Expr *pExpr; };

/*
** Disable lookaside memory allocation for objects that might be
** shared across database connections.
*/
static void disableLookaside(Parse *pParse){
  sqlite3 *db = pParse->db;
  pParse->disableLookaside++;
  DisableLookaside;
}

  pParse->db->lookaside.bDisable++;
#if !defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) \
 && defined(SQLITE_UDL_CAPABLE_PARSER)
/*
** Issue an error message if an ORDER BY or LIMIT clause occurs on an
** UPDATE or DELETE statement.
*/
static void updateDeleteLimitError(
  Parse *pParse,
  ExprList *pOrderBy,
  Expr *pLimit
){
  if( pOrderBy ){
    sqlite3ErrorMsg(pParse, "syntax error near \"ORDER BY\"");
  }else{
    sqlite3ErrorMsg(pParse, "syntax error near \"LIMIT\"");
  }
}
  sqlite3ExprListDelete(pParse->db, pOrderBy);
  sqlite3ExprDelete(pParse->db, pLimit);
}
#endif /* SQLITE_ENABLE_UPDATE_DELETE_LIMIT */

} // end %include

// Input is a single SQL command
input ::= cmdlist.
cmdlist ::= cmdlist ecmd.
cmdlist ::= ecmd.
ecmd ::= SEMI.
ecmd ::= cmdx SEMI.
%ifndef SQLITE_OMIT_EXPLAIN
ecmd ::= explain cmdx SEMI.       {NEVER-REDUCE}
ecmd ::= explain cmdx.
explain ::= EXPLAIN.              { pParse->explain = 1; }
explain ::= EXPLAIN QUERY PLAN.   { pParse->explain = 2; }
%endif  SQLITE_OMIT_EXPLAIN
cmdx ::= cmd.           { sqlite3FinishCoding(pParse); }

///////////////////// Begin and end transactions. ////////////////////////////
//
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
207
208
209
210
211
212
213

214
215
216
217
218
219
220




221
222
223
224
225
226
227







-







-
-
-
-







%fallback ID
  ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
  CONFLICT DATABASE DEFERRED DESC DETACH DO
  EACH END EXCLUSIVE EXPLAIN FAIL FOR
  IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
  QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
  ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
  NULLS FIRST LAST
%ifdef SQLITE_OMIT_COMPOUND_SELECT
  EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
%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,
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
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







-
-
-
-







-
-
+
+


-
-
-
+
+
+

-
+

-
+

















-
+




-
-
-
-







// post-processing, if needed.
//
%type scanpt {const char*}
scanpt(A) ::= . {
  assert( yyLookahead!=YYNOCODE );
  A = yyLookaheadToken.z;
}
scantok(A) ::= . {
  assert( yyLookahead!=YYNOCODE );
  A = yyLookaheadToken;
}

// "carglist" is a list of additional constraints that come after the
// column name and column type in a CREATE TABLE statement.
//
carglist ::= carglist ccons.
carglist ::= .
ccons ::= CONSTRAINT nm(X).           {pParse->constraintName = X;}
ccons ::= DEFAULT scantok(A) term(X).
                            {sqlite3AddDefaultValue(pParse,X,A.z,&A.z[A.n]);}
ccons ::= DEFAULT scanpt(A) term(X) scanpt(Z).
                            {sqlite3AddDefaultValue(pParse,X,A,Z);}
ccons ::= DEFAULT LP(A) expr(X) RP(Z).
                            {sqlite3AddDefaultValue(pParse,X,A.z+1,Z.z);}
ccons ::= DEFAULT PLUS(A) scantok(Z) term(X).
                            {sqlite3AddDefaultValue(pParse,X,A.z,&Z.z[Z.n]);}
ccons ::= DEFAULT MINUS(A) scantok(Z) term(X). {
ccons ::= DEFAULT PLUS(A) term(X) scanpt(Z).
                            {sqlite3AddDefaultValue(pParse,X,A.z,Z);}
ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z).      {
  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0);
  sqlite3AddDefaultValue(pParse,p,A.z,&Z.z[Z.n]);
  sqlite3AddDefaultValue(pParse,p,A.z,Z);
}
ccons ::= DEFAULT scantok id(X).       {
ccons ::= DEFAULT scanpt id(X).       {
  Expr *p = tokenExpr(pParse, TK_STRING, X);
  if( p ){
    sqlite3ExprIdToTrueFalse(p);
    testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
  }
    sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
}

// In addition to the type name, we also care about the primary key and
// UNIQUE constraints.
//
ccons ::= NULL onconf.
ccons ::= NOT NULL onconf(R).    {sqlite3AddNotNull(pParse, R);}
ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
                                 {sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
ccons ::= UNIQUE onconf(R).      {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0,
                                   SQLITE_IDXTYPE_UNIQUE);}
ccons ::= CHECK LP(A) expr(X) RP(B).  {sqlite3AddCheckConstraint(pParse,X,A.z,B.z);}
ccons ::= CHECK LP expr(X) RP.   {sqlite3AddCheckConstraint(pParse,X);}
ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R).
                                 {sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
ccons ::= defer_subclause(D).    {sqlite3DeferForeignKey(pParse,D);}
ccons ::= COLLATE ids(C).        {sqlite3AddCollateType(pParse, &C);}
ccons ::= GENERATED ALWAYS AS generated.
ccons ::= AS generated.
generated ::= LP expr(E) RP.          {sqlite3AddGenerated(pParse,E,0);}
generated ::= LP expr(E) RP ID(TYPE). {sqlite3AddGenerated(pParse,E,&TYPE);}

// The optional AUTOINCREMENT keyword
%type autoinc {int}
autoinc(X) ::= .          {X = 0;}
autoinc(X) ::= AUTOINCR.  {X = 1;}

// The next group of rules parses the arguments to a REFERENCES clause
423
424
425
426
427
428
429
430
431


432
433
434
435
436
437
438
382
383
384
385
386
387
388


389
390
391
392
393
394
395
396
397







-
-
+
+







tconscomma ::= .
tcons ::= CONSTRAINT nm(X).      {pParse->constraintName = X;}
tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R).
                                 {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
tcons ::= UNIQUE LP sortlist(X) RP onconf(R).
                                 {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,
                                       SQLITE_IDXTYPE_UNIQUE);}
tcons ::= CHECK LP(A) expr(E) RP(B) onconf.
                                 {sqlite3AddCheckConstraint(pParse,E,A.z,B.z);}
tcons ::= CHECK LP expr(E) RP onconf.
                                 {sqlite3AddCheckConstraint(pParse,E);}
tcons ::= FOREIGN KEY LP eidlist(FA) RP
          REFERENCES nm(T) eidlist_opt(TA) refargs(R) defer_subclause_opt(D). {
    sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
    sqlite3DeferForeignKey(pParse, D);
}
%type defer_subclause_opt {int}
defer_subclause_opt(A) ::= .                    {A = 0;}
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
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







-
+


















-

-
-
+
+
-
+


-
-
-
-
-
-
-
-
-
-









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







  sqlite3DropTable(pParse, X, 1, E);
}
%endif  SQLITE_OMIT_VIEW

//////////////////////// The SELECT statement /////////////////////////////////
//
cmd ::= select(X).  {
  SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0};
  SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
  sqlite3Select(pParse, X, &dest);
  sqlite3SelectDelete(pParse->db, X);
}

%type select {Select*}
%destructor select {sqlite3SelectDelete(pParse->db, $$);}
%type selectnowith {Select*}
%destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);}
%type oneselect {Select*}
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}

%include {
  /*
  ** 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;
      Select *pNext = 0, *pLoop;
      int mxSelect, cnt = 0;
      while(1){
      for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
        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.
}

%ifndef SQLITE_OMIT_CTE
  */
  static Select *attachWithToSelect(Parse *pParse, Select *pSelect, With *pWith){
    if( pSelect ){
      pSelect->pWith = pWith;
      parserDoubleLinkSelect(pParse, pSelect);
    }else{
      sqlite3WithDelete(pParse->db, pWith);
    }
    return pSelect;
  }
}

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;
}
%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*/
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
619
620
621
622
623
624
625

626
627
628
629
630
631
632
633







-
+







%type stl_prefix {SrcList*}
%destructor stl_prefix {sqlite3SrcListDelete(pParse->db, $$);}
%type from {SrcList*}
%destructor from {sqlite3SrcListDelete(pParse->db, $$);}

// A complete FROM clause.
//
from(A) ::= .                {A = 0;}
from(A) ::= .                {A = sqlite3DbMallocZero(pParse->db, sizeof(*A));}
from(A) ::= FROM seltablist(X). {
  A = X;
  sqlite3SrcListShiftJoinType(A);
}

// "seltablist" is a "Select Table List" - the content of the FROM clause
// in a SELECT statement.  "stl_prefix" is a prefix of this list.
702
703
704
705
706
707
708
709
710


711
712
713
714
715
716
717
654
655
656
657
658
659
660


661
662
663
664
665
666
667
668
669







-
-
+
+







  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;
        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;
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
772
773
774
775
776
777
778

779
780

781
782

783
784

785
786
787
788
789
790
791
792
793





794
795
796
797
798
799
800







-
+

-
+

-
+

-
+








-
-
-
-
-







// sort order.
//
%type sortlist {ExprList*}
%destructor sortlist {sqlite3ExprListDelete(pParse->db, $$);}

orderby_opt(A) ::= .                          {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z) nulls(X). {
sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). {
  A = sqlite3ExprListAppend(pParse,A,Y);
  sqlite3ExprListSetSortOrder(A,Z,X);
  sqlite3ExprListSetSortOrder(A,Z);
}
sortlist(A) ::= expr(Y) sortorder(Z) nulls(X). {
sortlist(A) ::= expr(Y) sortorder(Z). {
  A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/
  sqlite3ExprListSetSortOrder(A,Z,X);
  sqlite3ExprListSetSortOrder(A,Z);
}

%type sortorder {int}

sortorder(A) ::= ASC.           {A = SQLITE_SO_ASC;}
sortorder(A) ::= DESC.          {A = SQLITE_SO_DESC;}
sortorder(A) ::= .              {A = SQLITE_SO_UNDEFINED;}

%type nulls {int}
nulls(A) ::= NULLS FIRST.       {A = SQLITE_SO_ASC;}
nulls(A) ::= NULLS LAST.        {A = SQLITE_SO_DESC;}
nulls(A) ::= .                  {A = SQLITE_SO_UNDEFINED;}

%type groupby_opt {ExprList*}
%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
groupby_opt(A) ::= .                      {A = 0;}
groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;}

%type having_opt {Expr*}
%destructor having_opt {sqlite3ExprDelete(pParse->db, $$);}
870
871
872
873
874
875
876
877
878


879
880
881
882
883
884
885


886
887
888
889
890
891



892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915



916
917
918
919
920
921
922
923
924
925
926
927
928
929
930




931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
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







-
-
+
+



-
-
-
-
+
+
-



-
-
+
+
+







-
-



-
-
-
-
-
-



-
-
-
+
+
+

-

-
-
-
-
-
-
-


-
-
-
+
+
+
+


-



-
-







limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). 
                         {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)
%ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
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;
  sqlite3ExprListDelete(pParse->db, O); O = 0;
  sqlite3ExprDelete(pParse->db, L); L = 0;
  }
#endif
  sqlite3DeleteFrom(pParse,X,W,O,L);
}
%else
cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W). {
%endif
%ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
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, $$);}
%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).  {
%ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y)
        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_ret(W). {
%endif
%ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y)
        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



%type setlist {ExprList*}
%destructor setlist {sqlite3ExprListDelete(pParse->db, $$);}

setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). {
  A = sqlite3ExprListAppend(pParse, A, Y);
  sqlite3ExprListSetName(pParse, A, &X, 1);
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
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







-
+












-

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








////////////////////////// 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.
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) ::= 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); }
              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); }
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, $$);}
1019
1020
1021
1022
1023
1024
1025
1026

1027
1028
1029
1030
1031
1032
1033
1034
1035
940
941
942
943
944
945
946

947
948

949
950
951
952
953
954
955







-
+

-







  ** that created the expression.
  */
  static Expr *tokenExpr(Parse *pParse, int op, Token t){
    Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
    if( p ){
      /* memset(p, 0, sizeof(Expr)); */
      p->op = (u8)op;
      p->affExpr = 0;
      p->affinity = 0;
      p->flags = EP_Leaf;
      ExprClearVVAProperties(p);
      p->iAgg = -1;
      p->pLeft = p->pRight = 0;
      p->x.pList = 0;
      p->pAggInfo = 0;
      p->y.pTab = 0;
      p->op2 = 0;
      p->iTable = 0;
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
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







-
+



-
+














-
-
-





-
+







  A = sqlite3ExprFunction(pParse, Y, &X, D);
}
expr(A) ::= id(X) LP STAR RP. {
  A = sqlite3ExprFunction(pParse, 0, &X, 0);
}

%ifndef SQLITE_OMIT_WINDOWFUNC
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP filter_over(Z). {
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP over_clause(Z). {
  A = sqlite3ExprFunction(pParse, Y, &X, D);
  sqlite3WindowAttach(pParse, A, Z);
}
expr(A) ::= id(X) LP STAR RP filter_over(Z). {
expr(A) ::= id(X) LP STAR RP over_clause(Z). {
  A = sqlite3ExprFunction(pParse, 0, &X, 0);
  sqlite3WindowAttach(pParse, A, Z);
}
%endif

term(A) ::= CTIME_KW(OP). {
  A = sqlite3ExprFunction(pParse, 0, &OP, 0);
}

expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
  ExprList *pList = sqlite3ExprListAppend(pParse, X, Y);
  A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
  if( A ){
    A->x.pList = pList;
    if( ALWAYS(pList->nExpr) ){
      A->flags |= pList->a[0].pExpr->flags & EP_Propagate;
    }
  }else{
    sqlite3ExprListDelete(pParse->db, pList);
  }
}

expr(A) ::= expr(A) AND expr(Y).        {A=sqlite3ExprAnd(pParse,A,Y);}
expr(A) ::= expr(A) AND(OP) expr(Y).    {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) OR(OP) expr(Y).     {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
                                        {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) EQ|NE(OP) expr(Y).  {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
                                        {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) PLUS|MINUS(OP) expr(Y).
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257




















1258
1259
1260


1261
1262





1263
1264
1265
1266
1267
1268
1269
1270
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







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



+
+
-
-
+
+
+
+
+
-







      **
      **      expr1 IN ()
      **      expr1 NOT IN ()
      **
      ** simplify to constants 0 (false) and 1 (true), respectively,
      ** regardless of the value of expr1.
      */
      if( IN_RENAME_OBJECT==0 ){
      sqlite3ExprUnmapAndDelete(pParse, A);
      A = sqlite3Expr(pParse->db, TK_INTEGER, N ? "1" : "0");
    }else if( Y->nExpr==1 && sqlite3ExprIsConstant(Y->a[0].pExpr) ){
        sqlite3ExprDelete(pParse->db, A);
        A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1);
      }
    }else if( Y->nExpr==1 ){
      /* Expressions of the form:
      **
      **      expr1 IN (?1)
      **      expr1 NOT IN (?2)
      **
      ** with exactly one value on the RHS can be simplified to something
      ** like this:
      **
      **      expr1 == ?1
      **      expr1 <> ?2
      **
      ** But, the RHS of the == or <> is marked with the EP_Generic flag
      ** so that it may not contribute to the computation of comparison
      ** affinity or the collating sequence to use for comparison.  Otherwise,
      ** the semantics would be subtly different from IN or NOT IN.
      */
      Expr *pRHS = Y->a[0].pExpr;
      Y->a[0].pExpr = 0;
      sqlite3ExprListDelete(pParse->db, Y);
      /* pRHS cannot be NULL because a malloc error would have been detected
      ** before now and control would have never reached this point */
      pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
      A = sqlite3PExpr(pParse, TK_EQ, A, pRHS);
      if( ALWAYS(pRHS) ){
        pRHS->flags &= ~EP_Collate;
        pRHS->flags |= EP_Generic;
      }
      A = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A, pRHS);
      if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
    }else{
      A = sqlite3PExpr(pParse, TK_IN, A, 0);
      if( A ){
        A->x.pList = Y;
        sqlite3ExprSetHeightAndFlags(pParse, A);
      }else{
        sqlite3ExprListDelete(pParse->db, Y);
1371
1372
1373
1374
1375
1376
1377
1378

1379
1380
1381
1382
1383
1384
1385
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323
1324







-
+







// can be easily sent to sqlite3ColumnsExprList().
//
// eidlist is grouped with CREATE INDEX because it used to be the non-terminal
// used for the arguments to an index.  That is just an historical accident.
//
// IMPORTANT COMPATIBILITY NOTE:  Some prior versions of SQLite accepted
// COLLATE clauses and ASC or DESC keywords on ID lists in inappropriate
// places - places that might have been stored in the sqlite_schema table.
// places - places that might have been stored in the sqlite_master schema.
// Those extra features were ignored.  But because they might be in some
// (busted) old databases, we need to continue parsing them when loading
// historical schemas.
//
%type eidlist {ExprList*}
%destructor eidlist {sqlite3ExprListDelete(pParse->db, $$);}
%type eidlist_opt {ExprList*}
1426
1427
1428
1429
1430
1431
1432
1433


1434
1435
1436
1437
1438
1439
1440


1441
1442
1443
1444
1445
1446
1447
1365
1366
1367
1368
1369
1370
1371

1372
1373
1374
1375
1376
1377
1378
1379

1380
1381
1382
1383
1384
1385
1386
1387
1388







-
+
+






-
+
+








///////////////////////////// The DROP INDEX command /////////////////////////
//
cmd ::= DROP INDEX ifexists(E) fullname(X).   {sqlite3DropIndex(pParse, X, E);}

///////////////////////////// The VACUUM command /////////////////////////////
//
%if !SQLITE_OMIT_VACUUM && !SQLITE_OMIT_ATTACH
%ifndef SQLITE_OMIT_VACUUM
%ifndef SQLITE_OMIT_ATTACH
%type vinto {Expr*}
%destructor vinto {sqlite3ExprDelete(pParse->db, $$);}
cmd ::= VACUUM vinto(Y).                {sqlite3Vacuum(pParse,0,Y);}
cmd ::= VACUUM nm(X) vinto(Y).          {sqlite3Vacuum(pParse,&X,Y);}
vinto(A) ::= INTO expr(X).              {A = X;}
vinto(A) ::= .                          {A = 0;}
%endif
%endif  SQLITE_OMIT_ATTACH
%endif  SQLITE_OMIT_VACUUM

///////////////////////////// The PRAGMA command /////////////////////////////
//
%ifndef SQLITE_OMIT_PRAGMA
cmd ::= PRAGMA nm(X) dbnm(Z).                {sqlite3Pragma(pParse,&X,&Z,0,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ nmnum(Y).    {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) LP nmnum(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
1540
1541
1542
1543
1544
1545
1546
1547
1548


1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1572
1573

1574
1575
1576
1577
1578
1579
1580
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







-
-
+
+


















-
+





-
+










%type trigger_cmd {TriggerStep*}
%destructor trigger_cmd {sqlite3DeleteTriggerStep(pParse->db, $$);}
// UPDATE 
trigger_cmd(A) ::=
   UPDATE(B) orconf(R) trnm(X) tridxby SET setlist(Y) from(F) where_opt(Z) scanpt(E).  
   {A = sqlite3TriggerUpdateStep(pParse, &X, F, Y, Z, R, B.z, E);}
   UPDATE(B) orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z) scanpt(E).  
   {A = sqlite3TriggerUpdateStep(pParse, &X, Y, Z, R, B.z, E);}

// INSERT
trigger_cmd(A) ::= scanpt(B) insert_cmd(R) INTO
                      trnm(X) idlist_opt(F) select(S) upsert(U) scanpt(Z). {
   A = sqlite3TriggerInsertStep(pParse,&X,F,S,R,U,B,Z);/*A-overwrites-R*/
}
// DELETE
trigger_cmd(A) ::= DELETE(B) FROM trnm(X) tridxby where_opt(Y) scanpt(E).
   {A = sqlite3TriggerDeleteStep(pParse, &X, Y, B.z, E);}

// SELECT
trigger_cmd(A) ::= scanpt(B) select(X) scanpt(E).
   {A = sqlite3TriggerSelectStep(pParse->db, X, B, E); /*A-overwrites-X*/}

// The special RAISE expression that may occur in trigger programs
expr(A) ::= RAISE LP IGNORE RP.  {
  A = sqlite3PExpr(pParse, TK_RAISE, 0, 0); 
  if( A ){
    A->affExpr = OE_Ignore;
    A->affinity = OE_Ignore;
  }
}
expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP.  {
  A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1); 
  if( A ) {
    A->affExpr = (char)T;
    A->affinity = (char)T;
  }
}
%endif  !SQLITE_OMIT_TRIGGER

%type raisetype {int}
raisetype(A) ::= ROLLBACK.  {A = OE_Rollback;}
raisetype(A) ::= ABORT.     {A = OE_Abort;}
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1565
1566
1567
1568
1569
1570
1571




1572
1573
1574
1575
1576
1577
1578







-
-
-
-







  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);
}
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688


1689
1690
1691


1692
1693
1694
1695
1696
1697
1698
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







-
-






-
-
-
-
-
-
-
-
-
+
+

-
-
+
+







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) ::= 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 wqitem(X). {
  A = sqlite3WithAdd(pParse, A, 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 
1723
1724
1725
1726
1727
1728
1729
1730
1731


1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1651
1652
1653
1654
1655
1656
1657


1658
1659






1660
1661
1662
1663
1664
1665
1666







-
-
+
+
-
-
-
-
-
-








%type frame_opt {Window*}
%destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);}

%type part_opt {ExprList*}
%destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);}

%type filter_clause {Expr*}
%destructor filter_clause {sqlite3ExprDelete(pParse->db, $$);}
%type filter_opt {Expr*}
%destructor filter_opt {sqlite3ExprDelete(pParse->db, $$);}

%type over_clause {Window*}
%destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}

%type filter_over {Window*}
%destructor filter_over {sqlite3WindowDelete(pParse->db, $$);}

%type range_or_rows {int}

%type frame_bound {struct FrameBound}
%destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
%type frame_bound_s {struct FrameBound}
%destructor frame_bound_s {sqlite3ExprDelete(pParse->db, $$.pExpr);}
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
1718
1719
1720
1721
1722
1723
1724



1725
1726
1727
1728



1729
1730
1731

1732
1733
1734


1735
1736
1737

1738
1739
1740
1741












1742
1743
1744
1745
1746
1747
1748
1749
1750



1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763







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

-
+


-
-
+
+

-
+



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







-
-
-



+
+
+







frame_exclude(A) ::= GROUP|TIES(X).  {A = @X; /*A-overwrites-X*/}


%type window_clause {Window*}
%destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);}
window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; }

filter_over(A) ::= filter_clause(F) over_clause(O). {
  O->pFilter = F;
  A = O;
%type over_clause {Window*}
%destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}
over_clause(A) ::= filter_opt(W) OVER LP window(Z) RP. {
  A = Z;
}
filter_over(A) ::= over_clause(O). {
  A = O;
  assert( A!=0 );
  A->pFilter = W;
}
filter_over(A) ::= filter_clause(F). {
over_clause(A) ::= filter_opt(W) OVER nm(Z). {
  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( A ){
    A->eFrmType = TK_FILTER;
    A->pFilter = F;
    A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
    A->pFilter = W;
  }else{
    sqlite3ExprDelete(pParse->db, F);
    sqlite3ExprDelete(pParse->db, W);
  }
}

over_clause(A) ::= OVER LP window(Z) RP. {
  A = Z;
  assert( A!=0 );
}
over_clause(A) ::= OVER nm(Z). {
  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( A ){
    A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
  }
}

filter_clause(A) ::= FILTER LP WHERE expr(X) RP.  { A = X; }
filter_opt(A) ::= .                            { A = 0; }
filter_opt(A) ::= FILTER LP WHERE expr(X) RP.  { A = X; }
%endif /* SQLITE_OMIT_WINDOWFUNC */

/*
** The code generator needs some extra TK_ token values for tokens that
** are synthesized and do not actually appear in the grammar:
*/
%token
  COLUMN          /* Reference to a table column */
  AGG_FUNCTION    /* An aggregate function */
  AGG_COLUMN      /* An aggregated column */
  TRUEFALSE       /* True or false keyword */
  ISNOT           /* Combination of IS and NOT */
  FUNCTION        /* A function invocation */
  COLUMN          /* Reference to a table column */
  AGG_FUNCTION    /* An aggregate function */
  AGG_COLUMN      /* An aggregated column */
  UMINUS          /* Unary minus */
  UPLUS           /* Unary plus */
  TRUTH           /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */
  REGISTER        /* Reference to a VDBE register */
  VECTOR          /* Vector */
  SELECT_COLUMN   /* Choose a single column from a multi-column SELECT */
  IF_NULL_ROW     /* the if-null-row operator */

Changes to src/pcache.c.

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







-
-
-
+
+
+
-















-







*/
static int numberOfCachePages(PCache *p){
  if( p->szCache>=0 ){
    /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
    ** suggested cache size is set to N. */
    return p->szCache;
  }else{
    /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
    ** number of cache pages is adjusted to be a number of pages that would
    ** use approximately abs(N*1024) bytes of memory based on the current
    /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
    ** the number of cache pages is adjusted to use approximately abs(N*1024)
    ** bytes of memory. */
    ** page size. */
    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
  }
}

/*************************************************** General Interfaces ******
**
** Initialize and shutdown the page cache subsystem. Neither of these 
** functions are threadsafe.
*/
int sqlite3PcacheInitialize(void){
  if( sqlite3GlobalConfig.pcache2.xInit==0 ){
    /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
    ** built-in default page cache is used instead of the application defined
    ** page cache. */
    sqlite3PCacheSetDefault();
    assert( sqlite3GlobalConfig.pcache2.xInit!=0 );
  }
  return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
}
void sqlite3PcacheShutdown(void){
  if( sqlite3GlobalConfig.pcache2.xShutdown ){
    /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
    sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg);

Changes to src/pcache1.c.

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
420
421
422
423
424
425
426

427
428
429
430
431
432
433







-







*/
static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
  PgHdr1 *p = 0;
  void *pPg;

  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
  if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){
    assert( pCache->pFree!=0 );
    p = pCache->pFree;
    pCache->pFree = p->pNext;
    p->pNext = 0;
  }else{
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
    /* The group mutex must be released before pcache1Alloc() is called. This
    ** is because it might call sqlite3_release_memory(), which assumes that 
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
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







+






-
-
-




-







    if( !pPg || !p ){
      pcache1Free(pPg);
      sqlite3_free(p);
      pPg = 0;
    }
#else
    pPg = pcache1Alloc(pCache->szAlloc);
    p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
    if( benignMalloc ){ sqlite3EndBenignMalloc(); }
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
    pcache1EnterMutex(pCache->pGroup);
#endif
    if( pPg==0 ) return 0;
#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().
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794

795
796
797
798
799
800
801
774
775
776
777
778
779
780

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







-









+







  if( pCache ){
    if( pcache1.separateCache ){
      pGroup = (PGroup*)&pCache[1];
      pGroup->mxPinned = 10;
    }else{
      pGroup = &pcache1.grp;
    }
    pcache1EnterMutex(pGroup);
    if( pGroup->lru.isAnchor==0 ){
      pGroup->lru.isAnchor = 1;
      pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
    }
    pCache->pGroup = pGroup;
    pCache->szPage = szPage;
    pCache->szExtra = szExtra;
    pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
    pCache->bPurgeable = (bPurgeable ? 1 : 0);
    pcache1EnterMutex(pGroup);
    pcache1ResizeHash(pCache);
    if( bPurgeable ){
      pCache->nMin = 10;
      pGroup->nMinPage += pCache->nMin;
      pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
      pCache->pnPurgeable = &pGroup->nPurgeable;
    }else{

Changes to src/pragma.c.

127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
127
128
129
130
131
132
133

134


135
136
137
138
139
140
141







-
+
-
-







/*
** Invalidate temp storage, either when the temp storage is changed
** from default, or when 'file' and the temp_store_directory has changed
*/
static int invalidateTempStorage(Parse *pParse){
  sqlite3 *db = pParse->db;
  if( db->aDb[1].pBt!=0 ){
    if( !db->autoCommit
    if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
     || sqlite3BtreeTxnState(db->aDb[1].pBt)!=SQLITE_TXN_NONE
    ){
      sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
        "from within a transaction");
      return SQLITE_ERROR;
    }
    sqlite3BtreeClose(db->aDb[1].pBt);
    db->aDb[1].pBt = 0;
    sqlite3ResetAllSchemasOfConnection(db);
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
290
291
292
293
294
295
296

















































297
298
299
300
301
302
303







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







      upr = mid - 1;
    }else{
      lwr = mid + 1;
    }
  }
  return lwr>upr ? 0 : &aPragmaName[mid];
}

/*
** Create zero or more entries in the output for the SQL functions
** defined by FuncDef p.
*/
static void pragmaFunclistLine(
  Vdbe *v,               /* The prepared statement being created */
  FuncDef *p,            /* A particular function definition */
  int isBuiltin,         /* True if this is a built-in function */
  int showInternFuncs    /* True if showing internal functions */
){
  for(; p; p=p->pNext){
    const char *zType;
    static const u32 mask = 
        SQLITE_DETERMINISTIC |
        SQLITE_DIRECTONLY |
        SQLITE_SUBTYPE |
        SQLITE_INNOCUOUS |
        SQLITE_FUNC_INTERNAL
    ;
    static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };

    assert( SQLITE_FUNC_ENCMASK==0x3 );
    assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 );
    assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 );
    assert( strcmp(azEnc[SQLITE_UTF16BE],"utf16be")==0 );

    if( p->xSFunc==0 ) continue;
    if( (p->funcFlags & SQLITE_FUNC_INTERNAL)!=0
     && showInternFuncs==0
    ){
      continue;
    }    
    if( p->xValue!=0 ){
      zType = "w";
    }else if( p->xFinalize!=0 ){
      zType = "a";
    }else{
      zType = "s";
    }
    sqlite3VdbeMultiLoad(v, 1, "sissii",
       p->zName, isBuiltin,
       zType, azEnc[p->funcFlags&SQLITE_FUNC_ENCMASK],
       p->nArg,
       (p->funcFlags & mask) ^ SQLITE_INNOCUOUS
    );
  }
}


/*
** Helper subroutine for PRAGMA integrity_check:
**
** Generate code to output a single-column result row with a value of the
** string held in register 3.  Decrement the result count in register 1
** and halt if the maximum number of result rows have been issued.
553
554
555
556
557
558
559
560

561
562
563
564
565
566
567
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516







-
+







      int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
      returnSingleInt(v, size);
    }else{
      /* Malloc may fail when setting the page-size, as there is an internal
      ** buffer that the pager module resizes using sqlite3_realloc().
      */
      db->nextPagesize = sqlite3Atoi(zRight);
      if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){
      if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
        sqlite3OomFault(db);
      }
    }
    break;
  }

  /*
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
558
559
560
561
562
563
564

565
566
567
568
569







570
571
572
573
574
575
576
577
578







-





-
-
-
-
-
-
-
+
+







  **
  **  PRAGMA [schema.]page_count
  **
  ** Return the number of pages in the specified database.
  */
  case PragTyp_PAGE_COUNT: {
    int iReg;
    i64 x = 0;
    sqlite3CodeVerifySchema(pParse, iDb);
    iReg = ++pParse->nMem;
    if( sqlite3Tolower(zLeft[0])=='p' ){
      sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
    }else{
      if( zRight && sqlite3DecOrHexToI64(zRight,&x)==0 ){
        if( x<0 ) x = 0;
        else if( x>0xfffffffe ) x = 0xfffffffe;
      }else{
        x = 0;
      }
      sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, (int)x);
      sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, 
                        sqlite3AbsInt32(sqlite3Atoi(zRight)));
    }
    sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
    break;
  }

  /*
  **  PRAGMA [schema.]locking_mode
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
640
641
642
643
644
645
646





647
648
649
650
651
652
653







-
-
-
-
-







        if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break;
      }
      if( !zMode ){
        /* If the "=MODE" part does not match any known journal mode,
        ** then do a query */
        eMode = PAGER_JOURNALMODE_QUERY;
      }
      if( eMode==PAGER_JOURNALMODE_OFF && (db->flags & SQLITE_Defensive)!=0 ){
        /* Do not allow journal-mode "OFF" in defensive since the database
        ** can become corrupted using ordinary SQL when the journal is off */
        eMode = PAGER_JOURNALMODE_QUERY;
      }
    }
    if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
      /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
      iDb = 0;
      pId2->n = 1;
    }
    for(ii=db->nDb-1; ii>=0; ii--){
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
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







-


+





+


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








-
+





-
+







  ** type:       Column declaration type.
  ** notnull:    True if 'NOT NULL' is part of column declaration
  ** dflt_value: The default value for the column, if any.
  ** pk:         Non-zero for PK fields.
  */
  case PragTyp_TABLE_INFO: if( zRight ){
    Table *pTab;
    sqlite3CodeVerifyNamedSchema(pParse, zDb);
    pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
    if( pTab ){
      int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
      int i, k;
      int nHidden = 0;
      Column *pCol;
      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
      pParse->nMem = 7;
      sqlite3CodeVerifySchema(pParse, iTabDb);
      sqlite3ViewGetColumnNames(pParse, pTab);
      for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
        int isHidden = 0;
        int isHidden = IsHiddenColumn(pCol);
        if( pCol->colFlags & COLFLAG_NOINSERT ){
          if( pPragma->iArg==0 ){
            nHidden++;
            continue;
        if( isHidden && pPragma->iArg==0 ){
          nHidden++;
          continue;
          }
          if( pCol->colFlags & COLFLAG_VIRTUAL ){
            isHidden = 2;  /* GENERATED ALWAYS AS ... VIRTUAL */
          }else if( pCol->colFlags & COLFLAG_STORED ){
            isHidden = 3;  /* GENERATED ALWAYS AS ... STORED */
          }else{ assert( pCol->colFlags & COLFLAG_HIDDEN );
            isHidden = 1;  /* HIDDEN */
          }
        }
        if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
          k = 0;
        }else if( pPk==0 ){
          k = 1;
        }else{
          for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
        }
        assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN || isHidden>=2 );
        assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
        sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
               i-nHidden,
               pCol->zName,
               sqlite3ColumnType(pCol,""),
               pCol->notNull ? 1 : 0,
               pCol->pDflt && isHidden<2 ? pCol->pDflt->u.zToken : 0,
               pCol->pDflt ? pCol->pDflt->u.zToken : 0,
               k,
               isHidden);
      }
    }
  }
  break;

1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1148
1149
1150
1151
1152
1153
1154









1155
1156
1157
1158
1159
1160
1161







-
-
-
-
-
-
-
-
-







  break;
#endif

  case PragTyp_INDEX_INFO: if( zRight ){
    Index *pIdx;
    Table *pTab;
    pIdx = sqlite3FindIndex(db, zRight, zDb);
    if( pIdx==0 ){
      /* If there is no index named zRight, check to see if there is a
      ** WITHOUT ROWID table named zRight, and if there is, show the
      ** structure of the PRIMARY KEY index for that table. */
      pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
      if( pTab && !HasRowid(pTab) ){
        pIdx = sqlite3PrimaryKeyIndex(pTab);
      }
    }
    if( pIdx ){
      int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
      int i;
      int mx;
      if( pPragma->iArg ){
        /* PRAGMA index_xinfo (newer version with more rows and columns) */
        mx = pIdx->nColumn;
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
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







-
+




-
-
+


+
-
+




-
+







    for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
      CollSeq *pColl = (CollSeq *)sqliteHashData(p);
      sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
    }
  }
  break;

#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
#ifdef SQLITE_INTROSPECTION_PRAGMAS
  case PragTyp_FUNCTION_LIST: {
    int i;
    HashElem *j;
    FuncDef *p;
    int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0;
    pParse->nMem = 6;
    pParse->nMem = 2;
    for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
      for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
        if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
        pragmaFunclistLine(v, p, 1, showInternFunc);
        sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
      }
    }
    for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
      p = (FuncDef*)sqliteHashData(j);
      pragmaFunclistLine(v, p, 0, showInternFunc);
      sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0);
    }
  }
  break;

#ifndef SQLITE_OMIT_VIRTUALTABLE
  case PragTyp_MODULE_LIST: {
    HashElem *j;
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
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







+








-
+
-
-
-
+
+

-
+





-
+



-
+

-
+

















-
+








    regResult = pParse->nMem+1;
    pParse->nMem += 4;
    regKey = ++pParse->nMem;
    regRow = ++pParse->nMem;
    k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
    while( k ){
      int iTabDb;
      if( zRight ){
        pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
        k = 0;
      }else{
        pTab = (Table*)sqliteHashData(k);
        k = sqliteHashNext(k);
      }
      if( pTab==0 || pTab->pFKey==0 ) continue;
      iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
      iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
      zDb = db->aDb[iDb].zDbSName;
      sqlite3CodeVerifySchema(pParse, iDb);
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
      sqlite3CodeVerifySchema(pParse, iTabDb);
      sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName);
      if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
      sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
      sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead);
      sqlite3VdbeLoadString(v, regResult, pTab->zName);
      for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
        pParent = sqlite3FindTable(db, pFK->zTo, zDb);
        if( pParent==0 ) continue;
        pIdx = 0;
        sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
        sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName);
        x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
        if( x==0 ){
          if( pIdx==0 ){
            sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
            sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead);
          }else{
            sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
            sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb);
            sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
          }
        }else{
          k = 0;
          break;
        }
      }
      assert( pParse->nErr>0 || pFK==0 );
      if( pFK ) break;
      if( pParse->nTab<i ) pParse->nTab = i;
      addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
      for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
        pParent = sqlite3FindTable(db, pFK->zTo, zDb);
        pIdx = 0;
        aiCols = 0;
        if( pParent ){
          x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
          assert( x==0 || db->mallocFailed );
          assert( x==0 );
        }
        addrOk = sqlite3VdbeMakeLabel(pParse);

        /* Generate code to read the child key values into registers
        ** regRow..regRow+n. If any of the child key values are NULL, this 
        ** row cannot cause an FK violation. Jump directly to addrOk in 
        ** this case. */
1474
1475
1476
1477
1478
1479
1480
1481

1482
1483
1484
1485
1486
1487
1488
1395
1396
1397
1398
1399
1400
1401

1402
1403
1404
1405
1406
1407
1408
1409







-
+







              sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
          sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
          VdbeCoverage(v);
        }else if( pParent ){
          int jmp = sqlite3VdbeCurrentAddr(v)+2;
          sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
          sqlite3VdbeGoto(v, addrOk);
          assert( pFK->nCol==1 || db->mallocFailed );
          assert( pFK->nCol==1 );
        }

        /* Generate code to report an FK violation to the caller. */
        if( HasRowid(pTab) ){
          sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
        }else{
          sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1);
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
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







-









-

















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



-







      sqlite3VdbeJumpHere(v, addrTop);
    }
  }
  break;
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */

#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
  /* Reinstall the LIKE and GLOB functions.  The variant of LIKE
  ** used will be case sensitive or not depending on the RHS.
  */
  case PragTyp_CASE_SENSITIVE_LIKE: {
    if( zRight ){
      sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
    }
  }
  break;
#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */

#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
#endif

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
  /*    PRAGMA integrity_check
  **    PRAGMA integrity_check(N)
  **    PRAGMA quick_check
  **    PRAGMA quick_check(N)
  **
  ** Verify the integrity of the database.
  **
  ** The "quick_check" is reduced version of 
  ** integrity_check designed to detect most database corruption
  ** without the overhead of cross-checking indexes.  Quick_check
  ** is linear time wherease integrity_check is O(NlogN).
  **
  ** The maximum nubmer of errors is 100 by default.  A different default
  ** can be specified using a numeric parameter N.
  **
  ** Or, the parameter N can be the name of a table.  In that case, only
  ** the one table named is verified.  The freelist is only verified if
  ** the named table is "sqlite_schema" (or one of its aliases).
  **
  ** All schemas are checked by default.  To check just a single
  ** schema, use the form:
  **
  **      PRAGMA schema.integrity_check;
  */
  case PragTyp_INTEGRITY_CHECK: {
    int i, j, addr, mxErr;
    Table *pObjTab = 0;     /* Check only this one table, if not NULL */

    int isQuick = (sqlite3Tolower(zLeft[0])=='q');

    /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
    ** then iDb is set to the index of the database identified by <db>.
    ** In this case, the integrity of database iDb only is verified by
    ** the VDBE created below.
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571



1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1468
1469
1470
1471
1472
1473
1474



1475
1476
1477




1478
1479
1480
1481
1482
1483
1484







-
-
-
+
+
+
-
-
-
-








    /* Initialize the VDBE program */
    pParse->nMem = 6;

    /* Set the maximum error count */
    mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
    if( zRight ){
      if( sqlite3GetInt32(zRight, &mxErr) ){
        if( mxErr<=0 ){
          mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
      sqlite3GetInt32(zRight, &mxErr);
      if( mxErr<=0 ){
        mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
        }
      }else{
        pObjTab = sqlite3LocateTable(pParse, 0, zRight,
                      iDb>=0 ? db->aDb[iDb].zDbSName : 0);
      }
    }
    sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */

    /* Do an integrity check on each database file */
    for(i=0; i<db->nDb; i++){
      HashElem *x;     /* For looping over tables in the schema */
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
1499
1500
1501
1502
1503
1504
1505

1506
1507
1508
1509


1510
1511



1512
1513
1514

1515
1516
1517
1518
1519
1520
1521







-




-
-


-
-
-
+


-







      */
      assert( sqlite3SchemaMutexHeld(db, i, 0) );
      pTbls = &db->aDb[i].pSchema->tblHash;
      for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);  /* Current table */
        Index *pIdx;                      /* An index on pTab */
        int nIdx;                         /* Number of indexes on pTab */
        if( pObjTab && pObjTab!=pTab ) continue;
        if( HasRowid(pTab) ) cnt++;
        for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
        if( nIdx>mxIdx ) mxIdx = nIdx;
      }
      if( cnt==0 ) continue;
      if( pObjTab ) cnt++;
      aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1));
      if( aRoot==0 ) break;
      cnt = 0;
      if( pObjTab ) aRoot[++cnt] = 0;
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
      for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        if( pObjTab && pObjTab!=pTab ) continue;
        if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          aRoot[++cnt] = pIdx->tnum;
        }
      }
      aRoot[0] = cnt;

1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669

1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680

1681
1682
1683
1684
1685
1686
1687
1688
1541
1542
1543
1544
1545
1546
1547

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

1564
1565
1566
1567
1568
1569
1570
1571
1572
1573


1574

1575
1576
1577
1578
1579
1580
1581







-
















-
+









-
-
+
-







        Index *pIdx, *pPk;
        Index *pPrior = 0;
        int loopTop;
        int iDataCur, iIdxCur;
        int r1 = -1;

        if( pTab->tnum<1 ) continue;  /* Skip VIEWs or VIRTUAL TABLEs */
        if( pObjTab && pObjTab!=pTab ) continue;
        pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
        sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
                                   1, 0, &iDataCur, &iIdxCur);
        /* reg[7] counts the number of entries in the table.
        ** reg[8+i] counts the number of entries in the i-th index 
        */
        sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
        }
        assert( pParse->nMem>=8+j );
        assert( sqlite3NoTempsInRange(pParse,1,7+j) );
        sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
        loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
        if( !isQuick ){
          /* Sanity check on record header decoding */
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3);
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
        }
        /* Verify that all NOT NULL columns really are NOT NULL */
        for(j=0; j<pTab->nCol; j++){
          char *zErr;
          int jmp2;
          if( j==pTab->iPKey ) continue;
          if( pTab->aCol[j].notNull==0 ) continue;
          sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
          if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){
            sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
          }
          jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
          zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
                              pTab->aCol[j].zName);
          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
          integrityCheckResultRow(v);
          sqlite3VdbeJumpHere(v, jmp2);
        }
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
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







+













+







            }
            sqlite3VdbeJumpHere(v, jmp4);
            sqlite3ResolvePartIdxLabel(pParse, jmp3);
          }
        }
        sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
        sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
        if( !isQuick ){
          sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
          for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
            if( pPk==pIdx ) continue;
            sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
            addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
            sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
            sqlite3VdbeLoadString(v, 4, pIdx->zName);
            sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
            integrityCheckResultRow(v);
            sqlite3VdbeJumpHere(v, addr);
          }
        }
#endif /* SQLITE_OMIT_BTREECOUNT */
      } 
    }
    {
      static const int iLn = VDBE_OFFSET_LINENO(2);
      static const VdbeOpList endCode[] = {
        { OP_AddImm,      1, 0,        0},    /* 0 */
        { OP_IfNotZero,   1, 4,        0},    /* 1 */
1849
1850
1851
1852
1853
1854
1855
1856




1857
1858
1859
1860

1861

1862
1863
1864
1865
1866
1867
1868
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756


1757

1758
1759
1760
1761
1762
1763
1764
1765







-
+
+
+
+


-
-
+
-
+







      returnSingleText(v, encnames[ENC(pParse->db)].zName);
    }else{                        /* "PRAGMA encoding = XXX" */
      /* Only change the value of sqlite.enc if the database handle is not
      ** initialized. If the main database exists, the new sqlite.enc value
      ** will be overwritten when the schema is next loaded. If it does not
      ** already exists, it will be created to use the new encoding value.
      */
      if( (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){
      if( 
        !(DbHasProperty(db, 0, DB_SchemaLoaded)) || 
        DbHasProperty(db, 0, DB_Empty) 
      ){
        for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
          if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
            u8 enc = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
            SCHEMA_ENC(db) = enc;
            SCHEMA_ENC(db) = ENC(db) =
            sqlite3SetTextEncoding(db, enc);
                pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
            break;
          }
        }
        if( !pEnc->zName ){
          sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
        }
      }
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1814
1815
1816
1817
1818
1819
1820

1821
1822
1823
1824
1825
1826
1827







-







      sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie));
      aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
      if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
      aOp[0].p1 = iDb;
      aOp[1].p1 = iDb;
      aOp[1].p2 = iCookie;
      aOp[1].p3 = sqlite3Atoi(zRight);
      aOp[1].p5 = 1;
    }else{
      /* Read the specified cookie value */
      static const VdbeOpList readCookie[] = {
        { OP_Transaction,     0,  0,  0},    /* 0 */
        { OP_ReadCookie,      0,  1,  0},    /* 1 */
        { OP_ResultRow,       1,  1,  0}
      };
1965
1966
1967
1968
1969
1970
1971
1972

1973
1974
1975
1976
1977
1978
1979
1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872
1873
1874
1875







-
+







#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 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 ){
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
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







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



















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







    if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
      sqlite3_soft_heap_limit64(N);
    }
    returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
    break;
  }

  /*
  **   PRAGMA hard_heap_limit
  **   PRAGMA hard_heap_limit = N
  **
  ** Invoke sqlite3_hard_heap_limit64() to query or set the hard heap
  ** limit.  The hard heap limit can be activated or lowered by this
  ** pragma, but not raised or deactivated.  Only the
  ** sqlite3_hard_heap_limit64() C-language API can raise or deactivate
  ** the hard heap limit.  This allows an application to set a heap limit
  ** constraint that cannot be relaxed by an untrusted SQL script.
  */
  case PragTyp_HARD_HEAP_LIMIT: {
    sqlite3_int64 N;
    if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
      sqlite3_int64 iPrior = sqlite3_hard_heap_limit64(-1);
      if( N>0 && (iPrior==0 || iPrior>N) ) sqlite3_hard_heap_limit64(N);
    }
    returnSingleInt(v, sqlite3_hard_heap_limit64(-1));
    break;
  }

  /*
  **   PRAGMA threads
  **   PRAGMA threads = N
  **
  ** Configure the maximum number of worker threads.  Return the new
  ** maximum, which might be less than requested.
  */
  case PragTyp_THREADS: {
    sqlite3_int64 N;
    if( zRight
     && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
     && N>=0
    ){
      sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
    }
    returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
    break;
  }

  /*
  **   PRAGMA analysis_limit
  **   PRAGMA analysis_limit = N
  **
  ** Configure the maximum number of rows that ANALYZE will examine
  ** in each index that it looks at.  Return the new limit.
  */
  case PragTyp_ANALYSIS_LIMIT: {
    sqlite3_int64 N;
    if( zRight
     && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
     && N>=0
    ){
      db->nAnalysisLimit = (int)(N&0x7fffffff);
    }
    returnSingleInt(v, db->nAnalysisLimit);
    break;
  }

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
  /*
  ** Report the current state of file logs for all databases
  */
  case PragTyp_LOCK_STATUS: {
    static const char *const azLockName[] = {
      "unlocked", "shared", "reserved", "pending", "exclusive"
2251
2252
2253
2254
2255
2256
2257







































2258

2259






2260
2261
2262

2263
2264
2265
2266
2267
2268
2269
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152

2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171







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

+
+
+
+
+
+



+







      }
      sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState);
    }
    break;
  }
#endif

#ifdef SQLITE_HAS_CODEC
  /* Pragma        iArg
  ** ----------   ------
  **  key           0
  **  rekey         1
  **  hexkey        2
  **  hexrekey      3
  **  textkey       4
  **  textrekey     5
  */
  case PragTyp_KEY: {
    if( zRight ){
      int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
      if( (pPragma->iArg & 1)==0 ){
        sqlite3_key_v2(db, zDb, zRight, n);
      }else{
        sqlite3_rekey_v2(db, zDb, zRight, n);
      }
    }
    break;
  }
  case PragTyp_HEXKEY: {
    if( zRight ){
      u8 iByte;
      int i;
      char zKey[40];
      for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
        iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
        if( (i&1)!=0 ) zKey[i/2] = iByte;
      }
      if( (pPragma->iArg & 1)==0 ){
        sqlite3_key_v2(db, zDb, zKey, i/2);
      }else{
        sqlite3_rekey_v2(db, zDb, zKey, i/2);
      }
    }
    break;
  }
#endif
#if defined(SQLITE_ENABLE_CEROD)
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
  case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){
#ifdef SQLITE_HAS_CODEC
    if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
      sqlite3_activate_see(&zRight[4]);
    }
#endif
#ifdef SQLITE_ENABLE_CEROD
    if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
      sqlite3_activate_cerod(&zRight[6]);
    }
#endif
  }
  break;
#endif

  } /* End of the PRAGMA switch */

  /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only

Changes to src/pragma.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
















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



























51
52
53
54
55
56
57
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







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







/* DO NOT EDIT!
** This file is automatically generated by the script at
** ../tool/mkpragmatab.tcl.  To update the set of pragmas, edit
** that script and rerun it.
*/

/* The various pragma types */
#define PragTyp_ACTIVATE_EXTENSIONS            0
#define PragTyp_ANALYSIS_LIMIT                 1
#define PragTyp_HEADER_VALUE                   2
#define PragTyp_AUTO_VACUUM                    3
#define PragTyp_FLAG                           4
#define PragTyp_BUSY_TIMEOUT                   5
#define PragTyp_CACHE_SIZE                     6
#define PragTyp_CACHE_SPILL                    7
#define PragTyp_CASE_SENSITIVE_LIKE            8
#define PragTyp_COLLATION_LIST                 9
#define PragTyp_COMPILE_OPTIONS               10
#define PragTyp_DATA_STORE_DIRECTORY          11
#define PragTyp_DATABASE_LIST                 12
#define PragTyp_DEFAULT_CACHE_SIZE            13
#define PragTyp_ENCODING                      14
#define PragTyp_FOREIGN_KEY_CHECK             15
#define PragTyp_FOREIGN_KEY_LIST              16
#define PragTyp_FUNCTION_LIST                 17
#define PragTyp_HEADER_VALUE                   0
#define PragTyp_AUTO_VACUUM                    1
#define PragTyp_FLAG                           2
#define PragTyp_BUSY_TIMEOUT                   3
#define PragTyp_CACHE_SIZE                     4
#define PragTyp_CACHE_SPILL                    5
#define PragTyp_CASE_SENSITIVE_LIKE            6
#define PragTyp_COLLATION_LIST                 7
#define PragTyp_COMPILE_OPTIONS                8
#define PragTyp_DATA_STORE_DIRECTORY           9
#define PragTyp_DATABASE_LIST                 10
#define PragTyp_DEFAULT_CACHE_SIZE            11
#define PragTyp_ENCODING                      12
#define PragTyp_FOREIGN_KEY_CHECK             13
#define PragTyp_FOREIGN_KEY_LIST              14
#define PragTyp_FUNCTION_LIST                 15
#define PragTyp_HARD_HEAP_LIMIT               18
#define PragTyp_INCREMENTAL_VACUUM            19
#define PragTyp_INDEX_INFO                    20
#define PragTyp_INDEX_LIST                    21
#define PragTyp_INTEGRITY_CHECK               22
#define PragTyp_JOURNAL_MODE                  23
#define PragTyp_JOURNAL_SIZE_LIMIT            24
#define PragTyp_LOCK_PROXY_FILE               25
#define PragTyp_LOCKING_MODE                  26
#define PragTyp_PAGE_COUNT                    27
#define PragTyp_MMAP_SIZE                     28
#define PragTyp_MODULE_LIST                   29
#define PragTyp_OPTIMIZE                      30
#define PragTyp_PAGE_SIZE                     31
#define PragTyp_PRAGMA_LIST                   32
#define PragTyp_SECURE_DELETE                 33
#define PragTyp_SHRINK_MEMORY                 34
#define PragTyp_SOFT_HEAP_LIMIT               35
#define PragTyp_SYNCHRONOUS                   36
#define PragTyp_TABLE_INFO                    37
#define PragTyp_TEMP_STORE                    38
#define PragTyp_TEMP_STORE_DIRECTORY          39
#define PragTyp_THREADS                       40
#define PragTyp_WAL_AUTOCHECKPOINT            41
#define PragTyp_WAL_CHECKPOINT                42
#define PragTyp_INCREMENTAL_VACUUM            16
#define PragTyp_INDEX_INFO                    17
#define PragTyp_INDEX_LIST                    18
#define PragTyp_INTEGRITY_CHECK               19
#define PragTyp_JOURNAL_MODE                  20
#define PragTyp_JOURNAL_SIZE_LIMIT            21
#define PragTyp_LOCK_PROXY_FILE               22
#define PragTyp_LOCKING_MODE                  23
#define PragTyp_PAGE_COUNT                    24
#define PragTyp_MMAP_SIZE                     25
#define PragTyp_MODULE_LIST                   26
#define PragTyp_OPTIMIZE                      27
#define PragTyp_PAGE_SIZE                     28
#define PragTyp_PRAGMA_LIST                   29
#define PragTyp_SECURE_DELETE                 30
#define PragTyp_SHRINK_MEMORY                 31
#define PragTyp_SOFT_HEAP_LIMIT               32
#define PragTyp_SYNCHRONOUS                   33
#define PragTyp_TABLE_INFO                    34
#define PragTyp_TEMP_STORE                    35
#define PragTyp_TEMP_STORE_DIRECTORY          36
#define PragTyp_THREADS                       37
#define PragTyp_WAL_AUTOCHECKPOINT            38
#define PragTyp_WAL_CHECKPOINT                39
#define PragTyp_ACTIVATE_EXTENSIONS           40
#define PragTyp_HEXKEY                        41
#define PragTyp_KEY                           42
#define PragTyp_LOCK_STATUS                   43
#define PragTyp_STATS                         44

/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
#define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
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
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







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

-
+












-
+






-
-
-
-
-







                           /* table_info reuses 8 */
  /*  15 */ "seqno",       /* Used by: index_xinfo */
  /*  16 */ "cid",        
  /*  17 */ "name",       
  /*  18 */ "desc",       
  /*  19 */ "coll",       
  /*  20 */ "key",        
  /*  21 */ "name",        /* Used by: function_list */
  /*  22 */ "builtin",    
  /*  23 */ "type",       
  /*  24 */ "enc",        
  /*  25 */ "narg",       
  /*  26 */ "flags",      
  /*  27 */ "tbl",         /* Used by: stats */
  /*  28 */ "idx",        
  /*  29 */ "wdth",       
  /*  30 */ "hght",       
  /*  31 */ "flgs",       
  /*  32 */ "seq",         /* Used by: index_list */
  /*  33 */ "name",       
  /*  34 */ "unique",     
  /*  35 */ "origin",     
  /*  36 */ "partial",    
  /*  37 */ "table",       /* Used by: foreign_key_check */
  /*  38 */ "rowid",      
  /*  39 */ "parent",     
  /*  40 */ "fkid",       
  /*  21 */ "tbl",         /* Used by: stats */
  /*  22 */ "idx",        
  /*  23 */ "wdth",       
  /*  24 */ "hght",       
  /*  25 */ "flgs",       
  /*  26 */ "seq",         /* Used by: index_list */
  /*  27 */ "name",       
  /*  28 */ "unique",     
  /*  29 */ "origin",     
  /*  30 */ "partial",    
  /*  31 */ "table",       /* Used by: foreign_key_check */
  /*  32 */ "rowid",      
  /*  33 */ "parent",     
  /*  34 */ "fkid",       
                           /* index_info reuses 15 */
  /*  35 */ "seq",         /* Used by: database_list */
  /*  36 */ "name",       
  /*  37 */ "file",       
  /*  38 */ "busy",        /* Used by: wal_checkpoint */
  /*  39 */ "log",        
  /*  40 */ "checkpointed",
                           /* index_info reuses 15 */
  /*  41 */ "seq",         /* Used by: database_list */
  /*  42 */ "name",       
  /*  41 */ "name",        /* Used by: function_list */
  /*  42 */ "builtin",    
  /*  43 */ "file",       
  /*  44 */ "busy",        /* Used by: wal_checkpoint */
  /*  45 */ "log",        
  /*  46 */ "checkpointed",
                           /* collation_list reuses 32 */
  /*  47 */ "database",    /* Used by: lock_status */
  /*  48 */ "status",     
  /*  49 */ "cache_size",  /* Used by: default_cache_size */
                           /* collation_list reuses 26 */
  /*  43 */ "database",    /* Used by: lock_status */
  /*  44 */ "status",     
  /*  45 */ "cache_size",  /* Used by: default_cache_size */
                           /* module_list pragma_list reuses 9 */
  /*  50 */ "timeout",     /* Used by: busy_timeout */
  /*  46 */ "timeout",     /* Used by: busy_timeout */
};

/* Definitions of all built-in pragmas */
typedef struct PragmaName {
  const char *const zName; /* Name of pragma */
  u8 ePragTyp;             /* PragTyp_XXX value */
  u8 mPragFlg;             /* Zero or more PragFlg_XXX values */
  u8 iPragCName;           /* Start of column names in pragCName[] */
  u8 nPragCName;           /* Num of col names. 0 means use pragma name */
  u64 iArg;                /* Extra argument */
} PragmaName;
static const PragmaName aPragmaName[] = {
#if defined(SQLITE_ENABLE_CEROD)
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
 {/* zName:     */ "activate_extensions",
  /* ePragTyp:  */ PragTyp_ACTIVATE_EXTENSIONS,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
 {/* zName:     */ "analysis_limit",
  /* ePragTyp:  */ PragTyp_ANALYSIS_LIMIT,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
 {/* zName:     */ "application_id",
  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
  /* ePragFlg:  */ PragFlg_NoColumns1|PragFlg_Result0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ BTREE_APPLICATION_ID },
#endif
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
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







-
+















-





-
















-
+







  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_AutoIndex },
#endif
#endif
 {/* zName:     */ "busy_timeout",
  /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 50, 1,
  /* ColNames:  */ 46, 1,
  /* iArg:      */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "cache_size",
  /* ePragTyp:  */ PragTyp_CACHE_SIZE,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "cache_spill",
  /* ePragTyp:  */ PragTyp_CACHE_SPILL,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
 {/* zName:     */ "case_sensitive_like",
  /* ePragTyp:  */ PragTyp_CASE_SENSITIVE_LIKE,
  /* ePragFlg:  */ PragFlg_NoColumns,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
 {/* zName:     */ "cell_size_check",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_CellSizeCk },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "checkpoint_fullfsync",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_CkptFullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "collation_list",
  /* ePragTyp:  */ PragTyp_COLLATION_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 32, 2,
  /* ColNames:  */ 26, 2,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
 {/* zName:     */ "compile_options",
  /* ePragTyp:  */ PragTyp_COMPILE_OPTIONS,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 0, 0,
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255

256
257
258
259
260
261
262
230
231
232
233
234
235
236

237
238
239
240
241
242
243

244
245
246
247
248
249
250
251







-
+






-
+







  /* ColNames:  */ 0, 0,
  /* iArg:      */ BTREE_DATA_VERSION },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "database_list",
  /* ePragTyp:  */ PragTyp_DATABASE_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
  /* ColNames:  */ 41, 3,
  /* ColNames:  */ 35, 3,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
 {/* zName:     */ "default_cache_size",
  /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 49, 1,
  /* ColNames:  */ 45, 1,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
 {/* zName:     */ "defer_foreign_keys",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
277
278
279
280
281
282
283
284
285


286
287
288
289
290
291
292
266
267
268
269
270
271
272


273
274
275
276
277
278
279
280
281







-
-
+
+







  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
 {/* zName:     */ "foreign_key_check",
  /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 37, 4,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
  /* ColNames:  */ 31, 4,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
 {/* zName:     */ "foreign_key_list",
  /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 0, 8,
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
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







-
+



-
+



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

-
+
+







 {/* zName:     */ "fullfsync",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_FullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "function_list",
  /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 21, 6,
  /* ColNames:  */ 41, 2,
  /* iArg:      */ 0 },
#endif
#endif
#if defined(SQLITE_HAS_CODEC)
 {/* zName:     */ "hexkey",
  /* ePragTyp:  */ PragTyp_HEXKEY,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 2 },
 {/* zName:     */ "hard_heap_limit",
  /* ePragTyp:  */ PragTyp_HARD_HEAP_LIMIT,
  /* ePragFlg:  */ PragFlg_Result0,
 {/* zName:     */ "hexrekey",
  /* ePragTyp:  */ PragTyp_HEXKEY,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
  /* iArg:      */ 3 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_CHECK)
 {/* zName:     */ "ignore_check_constraints",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_IgnoreChecks },
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365







-
+







  /* ePragTyp:  */ PragTyp_INDEX_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 15, 3,
  /* iArg:      */ 0 },
 {/* zName:     */ "index_list",
  /* ePragTyp:  */ PragTyp_INDEX_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 32, 5,
  /* ColNames:  */ 26, 5,
  /* iArg:      */ 0 },
 {/* zName:     */ "index_xinfo",
  /* ePragTyp:  */ PragTyp_INDEX_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 15, 6,
  /* iArg:      */ 1 },
#endif
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
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







+
+
+
+
+
+
+







+
+
+
+
+












-
+







  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
 {/* zName:     */ "journal_size_limit",
  /* ePragTyp:  */ PragTyp_JOURNAL_SIZE_LIMIT,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if defined(SQLITE_HAS_CODEC)
 {/* zName:     */ "key",
  /* ePragTyp:  */ PragTyp_KEY,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "legacy_alter_table",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_LegacyAlter },
 {/* zName:     */ "legacy_file_format",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_LegacyFileFmt },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
 {/* zName:     */ "lock_proxy_file",
  /* ePragTyp:  */ PragTyp_LOCK_PROXY_FILE,
  /* ePragFlg:  */ PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
 {/* zName:     */ "lock_status",
  /* ePragTyp:  */ PragTyp_LOCK_STATUS,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 47, 2,
  /* ColNames:  */ 43, 2,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "locking_mode",
  /* ePragTyp:  */ PragTyp_LOCKING_MODE,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq,
  /* ColNames:  */ 0, 0,
422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444







-
+







  /* ePragTyp:  */ PragTyp_MMAP_SIZE,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "module_list",
  /* ePragTyp:  */ PragTyp_MODULE_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 9, 1,
  /* iArg:      */ 0 },
#endif
#endif
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479







-
+







 {/* zName:     */ "parser_trace",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_ParserTrace },
#endif
#endif
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "pragma_list",
  /* ePragTyp:  */ PragTyp_PRAGMA_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 9, 1,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
489
490
491
492
493
494
495









496
497
498
499
500
501
502
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519







+
+
+
+
+
+
+
+
+







  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_ReadUncommit },
 {/* zName:     */ "recursive_triggers",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_RecTriggers },
#endif
#if defined(SQLITE_HAS_CODEC)
 {/* zName:     */ "rekey",
  /* ePragTyp:  */ PragTyp_KEY,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 1 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "reverse_unordered_selects",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_ReverseOrder },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570







-
+







  /* iArg:      */ SQLITE_SqlTrace },
#endif
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
 {/* zName:     */ "stats",
  /* ePragTyp:  */ PragTyp_STATS,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
  /* ColNames:  */ 27, 5,
  /* ColNames:  */ 21, 5,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "synchronous",
  /* ePragTyp:  */ PragTyp_SYNCHRONOUS,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
572
573
574
575
576
577
578












579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
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







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






-
-
-
-
-
-
-







  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
 {/* zName:     */ "temp_store_directory",
  /* ePragTyp:  */ PragTyp_TEMP_STORE_DIRECTORY,
  /* ePragFlg:  */ PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if defined(SQLITE_HAS_CODEC)
 {/* zName:     */ "textkey",
  /* ePragTyp:  */ PragTyp_KEY,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 4 },
 {/* zName:     */ "textrekey",
  /* ePragTyp:  */ PragTyp_KEY,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 5 },
#endif
 {/* zName:     */ "threads",
  /* ePragTyp:  */ PragTyp_THREADS,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "trusted_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_TrustedSchema },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
 {/* zName:     */ "user_version",
  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
  /* ePragFlg:  */ PragFlg_NoColumns1|PragFlg_Result0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ BTREE_USER_VERSION },
#endif
630
631
632
633
634
635
636
637

638
639
640
641
642
643
644
645
646
647
648

652
653
654
655
656
657
658

659
660
661
662
663
664
665
666
667
668
669

670







-
+










-
+
  /* ePragTyp:  */ PragTyp_WAL_AUTOCHECKPOINT,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
 {/* zName:     */ "wal_checkpoint",
  /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
  /* ePragFlg:  */ PragFlg_NeedSchema,
  /* ColNames:  */ 44, 3,
  /* ColNames:  */ 38, 3,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
/* Number of pragmas: 67 on by default, 77 total. */
/* Number of pragmas: 62 on by default, 81 total. */

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







-
+







-
-
+
+
-
-
-
-





-
+



















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








-
-
+
-
-
-
+
+







-
+


-
+


-
+





-
-
-
+
+
+
-
-




-
-
-
-
-








-
+
-
-
-
-
-
-

-
-
-
+








-
+



-
+




-
-
+
+








-
-
+
+
-
-
-
+

-


-
-
+
-




















-
+


-
+

-









-
-
+
+



-
-
+
-
-
-
+
+

-
+






-
-
+
-



















-
+








/*
** 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 *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_AlterRename|INITFLAG_AlterDrop) ){
    *pData->pzErrMsg = sqlite3MPrintf(db, 
  }else if( pData->mInitFlags & INITFLAG_AlterTable ){
    *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra);
        "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] : "?";
    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;
  }
}

/*
** Check to see if any sibling index (another index on the same table)
** of pIndex has the same root page number, and if it does, return true.
** This would indicate a corrupt schema.
*/
int sqlite3IndexHasDuplicateRootPage(Index *pIndex){
  Index *p;
  for(p=pIndex->pTable->pIndex; p; p=p->pNext){
    if( p->tnum==pIndex->tnum && p!=pIndex ) return 1;
  }
  return 0;
}

/* forward declaration */
static int sqlite3Prepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  u32 prepFlags,            /* Zero or more SQLITE_PREPARE_* flags */
  Vdbe *pReprepare,         /* VM being reprepared */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
);


/*
** This is the callback routine for the code that initializes the
** database.  See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**
** Each callback contains the following information:
**
**     argv[0] = type of object: "table", "index", "trigger", or "view".
**     argv[1] = name of thing being created
**     argv[0] = name of thing being created
**     argv[2] = associated table if an index or trigger
**     argv[3] = root page number for table or index. 0 for trigger or view.
**     argv[4] = SQL text for the CREATE statement.
**     argv[1] = root page number for table or index. 0 for trigger or view.
**     argv[2] = SQL text for the CREATE statement.
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb = pData->iDb;

  assert( argc==5 );
  assert( argc==3 );
  UNUSED_PARAMETER2(NotUsed, argc);
  assert( sqlite3_mutex_held(db->mutex) );
  db->mDbFlags |= DBFLAG_EncodingFixed;
  DbClearProperty(db, iDb, DB_Empty);
  pData->nInitRow++;
  if( db->mallocFailed ){
    corruptSchema(pData, argv, 0);
    corruptSchema(pData, argv[0], 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]
  if( argv[1]==0 ){
    corruptSchema(pData, argv[0], 0);
  }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
         && '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 = sqlite3Atoi(argv[1]);
     || (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);
    TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &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;
        pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          sqlite3OomFault(db);
        }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
          corruptSchema(pData, argv, sqlite3_errmsg(db));
          corruptSchema(pData, argv[0], sqlite3_errmsg(db));
        }
      }
    }
    sqlite3_finalize(pStmt);
  }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){
    corruptSchema(pData, argv, 0);
  }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
    corruptSchema(pData, argv[0], 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 ){
    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
    if( pIndex==0
      corruptSchema(pData, argv, "orphan index");
    }else
    if( sqlite3GetUInt32(argv[3],&pIndex->tnum)==0
     || sqlite3GetInt32(argv[1],&pIndex->tnum)==0
     || pIndex->tnum<2
     || pIndex->tnum>pData->mxPage
     || sqlite3IndexHasDuplicateRootPage(pIndex)
    ){
      if( sqlite3Config.bExtraSchemaChecks ){
        corruptSchema(pData, argv, "invalid rootpage");
      corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index");
      }
    }
  }
  return 0;
}

/*
** Attempt to read the database schema and initialize internal
** data structures for a single database file.  The index of the
** database file is given by iDb.  iDb==0 is used for the main
** database.  iDb==1 should never be used.  iDb>=2 is used for
** auxiliary databases.  Return one of the SQLITE_ error codes to
** indicate success or failure.
*/
int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
  int rc;
  int i;
#ifndef SQLITE_OMIT_DEPRECATED
  int size;
#endif
  Db *pDb;
  char const *azArg[6];
  char const *azArg[4];
  int meta[5];
  InitData initData;
  const char *zSchemaTabName;
  const char *zMasterName;
  int openedTransaction = 0;
  int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed);

  assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 );
  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pSchema );
  assert( sqlite3_mutex_held(db->mutex) );
  assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );

  db->init.busy = 1;

  /* Construct the in-memory representation schema tables (sqlite_schema or
  ** sqlite_temp_schema) by invoking the parser directly.  The appropriate
  /* Construct the in-memory representation schema tables (sqlite_master or
  ** sqlite_temp_master) by invoking the parser directly.  The appropriate
  ** table name will be inserted automatically by the parser so we can just
  ** use the abbreviation "x" here.  The parser will also automatically tag
  ** the schema table as read-only. */
  azArg[0] = "table";
  azArg[1] = zSchemaTabName = SCHEMA_TABLE(iDb);
  azArg[0] = zMasterName = SCHEMA_TABLE(iDb);
  azArg[2] = azArg[1];
  azArg[3] = "1";
  azArg[4] = "CREATE TABLE x(type text,name text,tbl_name text,"
  azArg[1] = "1";
  azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text,"
                            "rootpage int,sql text)";
  azArg[5] = 0;
  azArg[3] = 0;
  initData.db = db;
  initData.iDb = iDb;
  initData.rc = SQLITE_OK;
  initData.pzErrMsg = pzErrMsg;
  initData.mInitFlags = mFlags;
  initData.nInitRow = 0;
  initData.mxPage = 0;
  sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
  sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
  db->mDbFlags &= mask;
  if( initData.rc ){
    rc = initData.rc;
    goto error_out;
  }

  /* Create a cursor to hold the database open
  */
  pDb = &db->aDb[iDb];
  if( pDb->pBt==0 ){
    assert( iDb==1 );
    DbSetProperty(db, 1, DB_SchemaLoaded);
    rc = SQLITE_OK;
    goto error_out;
  }

  /* If there is not already a read-only (or read-write) transaction opened
  ** on the b-tree database, open one now. If a transaction is opened, it 
  ** will be closed before this function returns.  */
  sqlite3BtreeEnter(pDb->pBt);
  if( sqlite3BtreeTxnState(pDb->pBt)==SQLITE_TXN_NONE ){
  if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
    rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0);
    if( rc!=SQLITE_OK ){
      sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
      goto initone_error_out;
    }
    openedTransaction = 1;
  }
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
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







-
+
-

+



+

-
+

-


-
+






+
+








  /* If opening a non-empty database, check the text encoding. For the
  ** main database, set sqlite3.enc to the encoding of the main database.
  ** For an attached db, it is an error if the encoding is not the same
  ** as sqlite3.enc.
  */
  if( meta[BTREE_TEXT_ENCODING-1] ){  /* text encoding */
    if( iDb==0 && (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){
    if( iDb==0 ){
      u8 encoding;
#ifndef SQLITE_OMIT_UTF16
      u8 encoding;
      /* If opening the main database, set ENC(db). */
      encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
      if( encoding==0 ) encoding = SQLITE_UTF8;
      ENC(db) = encoding;
#else
      encoding = SQLITE_UTF8;
      ENC(db) = SQLITE_UTF8;
#endif
      sqlite3SetTextEncoding(db, encoding);
    }else{
      /* If opening an attached database, the encoding much match ENC(db) */
      if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){
      if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
        sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
            " text encoding as main database");
        rc = SQLITE_ERROR;
        goto initone_error_out;
      }
    }
  }else{
    DbSetProperty(db, iDb, DB_Empty);
  }
  pDb->pSchema->enc = ENC(db);

  if( pDb->pSchema->cache_size==0 ){
#ifndef SQLITE_OMIT_DEPRECATED
    size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]);
    if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
348
349
350
351
352
353
354
355
356
357
358
359
360


361
362
363
364
365
366
367
307
308
309
310
311
312
313

314
315
316


317
318
319
320
321
322
323
324
325







-



-
-
+
+







  if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
    db->flags &= ~(u64)SQLITE_LegacyFileFmt;
  }

  /* Read the schema information out of the schema tables
  */
  assert( db->init.busy );
  initData.mxPage = sqlite3BtreeLastPage(pDb->pBt);
  {
    char *zSql;
    zSql = sqlite3MPrintf(db, 
        "SELECT*FROM\"%w\".%s ORDER BY rowid",
        db->aDb[iDb].zDbSName, zSchemaTabName);
        "SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid",
        db->aDb[iDb].zDbSName, zMasterName);
#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      sqlite3_xauth xAuth;
      xAuth = db->xAuth;
      db->xAuth = 0;
#endif
      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355







-
+







  }
  if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
    /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
    ** the schema loaded, even if errors occurred. In this situation the 
    ** current sqlite3_prepare() operation will fail, but the following one
    ** will attempt to compile the supplied statement against whatever subset
    ** of the schema was loaded before the error occurred. The primary
    ** purpose of this is to allow access to the sqlite_schema table
    ** purpose of this is to allow access to the sqlite_master table
    ** even when its contents have been corrupted.
    */
    DbSetProperty(db, iDb, DB_SchemaLoaded);
    rc = SQLITE_OK;
  }

  /* Jump here for an error that occurs after successfully allocating
418
419
420
421
422
423
424
425


426
427
428
429
430
431
432
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390
391







-
+
+







/*
** Initialize all database files - the main database file, the file
** used to store temporary tables, and any additional database files
** created using ATTACH statements.  Return a success code.  If an
** error occurs, write an error message into *pzErrMsg.
**
** After a database is initialized, the DB_SchemaLoaded bit is set
** bit is set in the flags field of the Db structure. 
** bit is set in the flags field of the Db structure. If the database
** file was of zero-length, then the DB_Empty flag is also set.
*/
int sqlite3Init(sqlite3 *db, char **pzErrMsg){
  int i, rc;
  int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange);
  
  assert( sqlite3_mutex_held(db->mutex) );
  assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463







-
+







    int openedTransaction = 0;         /* True if a transaction is opened */
    Btree *pBt = db->aDb[iDb].pBt;     /* Btree database to read cookie from */
    if( pBt==0 ) continue;

    /* If there is not already a read-only (or read-write) transaction opened
    ** on the b-tree database, open one now. If a transaction is opened, it 
    ** will be closed immediately after reading the meta-value. */
    if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_NONE ){
    if( !sqlite3BtreeIsInReadTrans(pBt) ){
      rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
      if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
        sqlite3OomFault(db);
      }
      if( rc!=SQLITE_OK ) return;
      openedTransaction = 1;
    }
524
525
526
527
528
529
530
531

532
533

534
535
536
537
538
539


540
541

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
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







-
+

-
+




-
-
+
+

-
+
-



















-
-
-
-
-
-

-
-
+
-



-




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







** Convert a schema pointer into the iDb index that indicates
** which database file in db->aDb[] the schema refers to.
**
** If the same database is attached more than once, the first
** attached database is returned.
*/
int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
  int i = -32768;
  int i = -1000000;

  /* If pSchema is NULL, then return -32768. This happens when code in 
  /* If pSchema is NULL, then return -1000000. This happens when code in 
  ** expr.c is trying to resolve a reference to a transient table (i.e. one
  ** created by a sub-select). In this case the return value of this 
  ** function should never be used.
  **
  ** We return -32768 instead of the more usual -1 simply because using
  ** -32768 as the incorrect index into db->aDb[] is much 
  ** We return -1000000 instead of the more usual -1 simply because using
  ** -1000000 as the incorrect index into db->aDb[] is much 
  ** more likely to cause a segfault than -1 (of course there are assert()
  ** statements too, but it never hurts to play the odds) and
  ** statements too, but it never hurts to play the odds).
  ** -32768 will still fit into a 16-bit signed integer.
  */
  assert( sqlite3_mutex_held(db->mutex) );
  if( pSchema ){
    for(i=0; 1; i++){
      assert( i<db->nDb );
      if( db->aDb[i].pSchema==pSchema ){
        break;
      }
    }
    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);
  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. */
  int nBytes,               /* Length of zSql in bytes. */
651
652
653
654
655
656
657
658

659
660
661
662
663
664
665
551
552
553
554
555
556
557

558
559
560
561
562
563
564
565







-
+







  assert( sqlite3_mutex_held(db->mutex) );

  /* For a long-term use prepared statement avoid the use of
  ** lookaside memory.
  */
  if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
    sParse.disableLookaside++;
    DisableLookaside;
    db->lookaside.bDisable++;
  }
  sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;

  /* Check to verify that it is possible to get a read lock on all
  ** database schemas.  The inability to get a read lock indicates that
  ** some other database connection is holding a write-lock, which in
  ** turn means that the other connection has made uncommitted changes
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
578
579
580
581
582
583
584











585
586
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601







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







  ** locks on the schema, we just need to make sure nobody else is 
  ** holding them.
  **
  ** Note that setting READ_UNCOMMITTED overrides most lock detection,
  ** but it does *not* override schema lock detection, so this all still
  ** works even if READ_UNCOMMITTED is set.
  */
  if( !db->noSharedCache ){
    for(i=0; i<db->nDb; i++) {
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        assert( sqlite3BtreeHoldsMutex(pBt) );
        rc = sqlite3BtreeSchemaLocked(pBt);
        if( rc ){
          const char *zDb = db->aDb[i].zDbSName;
          sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
          testcase( db->flags & SQLITE_ReadUncommit );
          goto end_prepare;
  for(i=0; i<db->nDb; i++) {
    Btree *pBt = db->aDb[i].pBt;
    if( pBt ){
      assert( sqlite3BtreeHoldsMutex(pBt) );
      rc = sqlite3BtreeSchemaLocked(pBt);
      if( rc ){
        const char *zDb = db->aDb[i].zDbSName;
        sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
        testcase( db->flags & SQLITE_ReadUncommit );
        goto end_prepare;
        }
      }
    }
  }

  sqlite3VtabUnlockList(db);

  sParse.db = db;
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
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







-
-
+
+
-
-
+
-
-




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







      sParse.zTail = &zSql[nBytes];
    }
  }else{
    sqlite3RunParser(&sParse, zSql, &zErrMsg);
  }
  assert( 0==sParse.nQueryLoop );

  if( pzTail ){
    *pzTail = sParse.zTail;
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.checkSchema ){
  }

    schemaIsValid(&sParse);
  if( db->init.busy==0 ){
    sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
  }
  if( db->mallocFailed ){
    sParse.rc = SQLITE_NOMEM_BKPT;
  }
  if( pzTail ){
    *pzTail = sParse.zTail;
  }
  rc = sParse.rc;

#ifndef SQLITE_OMIT_EXPLAIN
  if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){
    if( sParse.checkSchema ){
      schemaIsValid(&sParse);
    }
    if( sParse.pVdbe ){
      sqlite3VdbeFinalize(sParse.pVdbe);
    }
    assert( 0==(*ppStmt) );
  if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
    static const char * const azColName[] = {
       "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
       "id", "parent", "notused", "detail"
    };
    int iFirst, mx;
    if( sParse.explain==2 ){
      sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
      iFirst = 8;
      mx = 12;
    }else{
      sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
      iFirst = 0;
      mx = 8;
    }
    for(i=iFirst; i<mx; i++){
      sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME,
                            azColName[i], SQLITE_STATIC);
    }
  }
#endif

  if( db->init.busy==0 ){
    sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
  }
  if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
    sqlite3VdbeFinalize(sParse.pVdbe);
    assert(!(*ppStmt));
  }else{
    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  }

    rc = sParse.rc;
    if( zErrMsg ){
      sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
      sqlite3DbFree(db, zErrMsg);
    }else{
      sqlite3Error(db, 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);
  }
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
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







-










-
+







    rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
    assert( rc==SQLITE_OK || *ppStmt==0 );
  }while( rc==SQLITE_ERROR_RETRY
       || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
  sqlite3BtreeLeaveAll(db);
  rc = sqlite3ApiExit(db, rc);
  assert( (rc&db->errMask)==rc );
  db->busyHandler.nBusy = 0;
  sqlite3_mutex_leave(db->mutex);
  return rc;
}


/*
** Rerun the compilation of a statement after a schema change.
**
** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
** if the statement cannot be recompiled because another connection has
** locked the sqlite3_schema table, return SQLITE_LOCKED. If any other error
** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error
** occurs, return SQLITE_SCHEMA.
*/
int sqlite3Reprepare(Vdbe *p){
  int rc;
  sqlite3_stmt *pNew;
  const char *zSql;
  sqlite3 *db;

Changes to src/printf.c.

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






102
103
104
105
106
107
108







-
-
-
-
-
-








  /* All the rest are undocumented and are for internal use only */
  {  'T',  0, 0, etTOKEN,      0,  0 },
  {  'S',  0, 0, etSRCLIST,    0,  0 },
  {  'r', 10, 1, etORDINAL,    0,  0 },
};

/* Floating point constants used for rounding */
static const double arRound[] = {
  5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05,
  5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10,
};

/*
** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
** conversions will work.
*/
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** "*val" is a double such that 0.1 <= *val < 10.0
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
184
185
186
187
188
189
190







191
192
193
194
195
196
197







-
-
-
-
-
-
-







** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
*/
#ifndef SQLITE_PRINT_BUF_SIZE
# define SQLITE_PRINT_BUF_SIZE 70
#endif
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */

/*
** Hard limit on the precision of floating-point conversions.
*/
#ifndef SQLITE_PRINTF_PRECISION_LIMIT
# define SQLITE_FP_PRECISION_LIMIT 100000000
#endif

/*
** Render a string given by "fmt" into the StrAccum object.
*/
void sqlite3_str_vappendf(
  sqlite3_str *pAccum,       /* Accumulate results here */
  const char *fmt,           /* Format string */
  va_list ap                 /* arguments */
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
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







-
-




-
+



-
+















-
+
-
-
-
+
+
+
+







    **   width                       The specified field width.  This is
    **                               always non-negative.  Zero is the default.
    **   precision                   The specified precision.  The default
    **                               is -1.
    **   xtype                       The class of the conversion.
    **   infop                       Pointer to the appropriate info struct.
    */
    assert( width>=0 );
    assert( precision>=(-1) );
    switch( xtype ){
      case etPOINTER:
        flag_long = sizeof(char*)==sizeof(i64) ? 2 :
                     sizeof(char*)==sizeof(long int) ? 1 : 0;
        /* no break */ deliberate_fall_through
        /* Fall through into the next case */
      case etORDINAL:
      case etRADIX:      
        cThousand = 0;
        /* no break */ deliberate_fall_through
        /* Fall through into the next case */
      case etDECIMAL:
        if( infop->flags & FLAG_SIGNED ){
          i64 v;
          if( bArgList ){
            v = getIntArg(pArgList);
          }else if( flag_long ){
            if( flag_long==2 ){
              v = va_arg(ap,i64) ;
            }else{
              v = va_arg(ap,long int);
            }
          }else{
            v = va_arg(ap,int);
          }
          if( v<0 ){
            testcase( v==SMALLEST_INT64 );
            if( v==SMALLEST_INT64 ){
            testcase( v==(-1) );
            longvalue = ~v;
            longvalue++;
              longvalue = ((u64)1)<<63;
            }else{
              longvalue = -v;
            }
            prefix = '-';
          }else{
            longvalue = v;
            prefix = flag_prefix;
          }
        }else{
          if( bArgList ){
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
505
506
507
508
509
510
511





512
513
514
515
516
517
518
519

520



521








522
523
524
525
526
527
528







-
-
-
-
-








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







        }else{
          realvalue = va_arg(ap,double);
        }
#ifdef SQLITE_OMIT_FLOATING_POINT
        length = 0;
#else
        if( precision<0 ) precision = 6;         /* Set default precision */
#ifdef SQLITE_FP_PRECISION_LIMIT
        if( precision>SQLITE_FP_PRECISION_LIMIT ){
          precision = SQLITE_FP_PRECISION_LIMIT;
        }
#endif
        if( realvalue<0.0 ){
          realvalue = -realvalue;
          prefix = '-';
        }else{
          prefix = flag_prefix;
        }
        if( xtype==etGENERIC && precision>0 ) precision--;
        testcase( precision>0xfff );
        idx = precision & 0xfff;
        for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
        rounder = arRound[idx%10];
        while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; }
        if( xtype==etFLOAT ){
        if( xtype==etFLOAT ) realvalue += rounder;
          double rx = (double)realvalue;
          sqlite3_uint64 u;
          int ex;
          memcpy(&u, &rx, sizeof(u));
          ex = -1023 + (int)((u>>52)&0x7ff);
          if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16;
          realvalue += rounder;
        }
        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
        exp = 0;
        if( sqlite3IsNaN((double)realvalue) ){
          bufpt = "NaN";
          length = 3;
          break;
        }
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791







-
+







        if( bArgList ){
          escarg = getTextArg(pArgList);
        }else{
          escarg = va_arg(ap,char*);
        }
        isnull = escarg==0;
        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
        /* For %q, %Q, and %w, the precision is the number of bytes (or
        /* For %q, %Q, and %w, the precision is the number of byte (or
        ** characters if the ! flags is present) to use from the input.
        ** Because of the extra quoting characters inserted, the number
        ** of output characters may be larger than the precision.
        */
        k = precision;
        for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
          if( ch==q )  n++;
852
853
854
855
856
857
858
859

860
861
862
863
864
865
866
823
824
825
826
827
828
829

830
831
832
833
834
835
836
837







-
+







        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc;
        int k;
        SrcItem *pItem;
        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 ){
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
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







-
+















-
+







  }
  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;
    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);
      setStrAccumError(p, SQLITE_TOOBIG);
      return 0;
    }else{
      p->nAlloc = (int)szNew;
    }
    if( p->db ){
      zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
    }else{
      zNew = sqlite3Realloc(zOld, p->nAlloc);
      zNew = sqlite3_realloc64(zOld, p->nAlloc);
    }
    if( zNew ){
      assert( p->zText!=0 || p->nChar==0 );
      if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
      p->zText = zNew;
      p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
      p->printfFlags |= SQLITE_PRINTF_MALLOCED;
1275
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1246
1247
1248
1249
1250
1251
1252

1253
1254
1255
1256
1257
1258
1259
1260







-
+







** A version of printf() that understands %lld.  Used for debugging.
** The printf() built into some versions of windows does not understand %lld
** and segfaults if you give it a long long int.
*/
void sqlite3DebugPrintf(const char *zFormat, ...){
  va_list ap;
  StrAccum acc;
  char zBuf[SQLITE_PRINT_BUF_SIZE*10];
  char zBuf[500];
  sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  va_start(ap,zFormat);
  sqlite3_str_vappendf(&acc, zFormat, ap);
  va_end(ap);
  sqlite3StrAccumFinish(&acc);
#ifdef SQLITE_OS_TRACE_PROC
  {

Changes to src/resolve.c.

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
12
13
14
15
16
17
18





19
20
21
22
23
24
25
26


27
28
29
30
31
32
33







-
-
-
-
-








-
-







**
** This file contains routines used for walking the parser tree and
** resolve all identifiers by associating them with a particular
** table and column.
*/
#include "sqliteInt.h"

/*
** Magic table number to mean the EXCLUDED table in an UPSERT statement.
*/
#define EXCLUDED_TABLE_NUMBER  2

/*
** Walk the expression tree pExpr and increase the aggregate function
** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node.
** This needs to occur when copying a TK_AGG_FUNCTION node from an
** outer query into an inner subquery.
**
** incrAggFunctionDepth(pExpr,n) is the main routine.  incrAggDepth(..)
** is a helper function - a callback for the tree walker.
**
** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c
*/
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
  return WRC_Continue;
}
static void incrAggFunctionDepth(Expr *pExpr, int N){
  if( N>0 ){
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
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







+












-
+



















-
-
-
-
-
-
-


+







** 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 ){
    incrAggFunctionDepth(pDup, nSubquery);
    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.
    ** The pExpr->u.zToken might point into memory that will be freed by the
    ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
    ** make a copy of the token before doing the sqlite3DbFree().
    */
    ExprSetProperty(pExpr, EP_Static);
    sqlite3ExprDelete(db, pExpr);
    memcpy(pExpr, pDup, sizeof(*pExpr));
    if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
      assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
      pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
      pExpr->flags |= EP_MemToken;
    }
    if( ExprHasProperty(pExpr, EP_WinFunc) ){
      if( pExpr->y.pWin!=0 ){
        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
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
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







-
-
+
+





-
-
-
















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







/*
** Subqueries stores the original database, table and column names for their
** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
** Check to see if the zSpan given to this routine matches the zDb, zTab,
** and zCol.  If any of zDb, zTab, and zCol are NULL then those fields will
** match anything.
*/
int sqlite3MatchEName(
  const struct ExprList_item *pItem,
int sqlite3MatchSpanName(
  const char *zSpan,
  const char *zCol,
  const char *zTab,
  const char *zDb
){
  int n;
  const char *zSpan;
  if( pItem->eEName!=ENAME_TAB ) return 0;
  zSpan = pItem->zEName;
  for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
  if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
    return 0;
  }
  zSpan += n+1;
  for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
  if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){
    return 0;
  }
  zSpan += n+1;
  if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
    return 0;
  }
  return 1;
}

/*
** Return TRUE if the double-quoted string  mis-feature should be supported.
*/
static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
  if( db->init.busy ) return 1;  /* Always support for legacy schemas */
  if( pTopNC->ncFlags & NC_IsDDL ){
    /* Currently parsing a DDL statement */
    if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){
      return 1;
    }
    return (db->flags & SQLITE_DqsDDL)!=0;
  }else{
    /* Currently parsing a DML statement */
    return (db->flags & SQLITE_DqsDML)!=0;
  }
}

/*
** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN.
** return the appropriate colUsed mask.
*/
Bitmask sqlite3ExprColUsed(Expr *pExpr){
  int n;
  Table *pExTab;

  n = pExpr->iColumn;
  pExTab = pExpr->y.pTab;
  assert( pExTab!=0 );
  if( (pExTab->tabFlags & TF_HasGenerated)!=0
   && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 
  ){
    testcase( pExTab->nCol==BMS-1 );
    testcase( pExTab->nCol==BMS );
    return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
  }else{
    testcase( n==BMS-1 );
    testcase( n==BMS );
    if( n>=BMS ) n = BMS-1;
    return ((Bitmask)1)<<n;
  }
}

/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr 
** expression node refer back to that source column.  The following changes
** are made to pExpr:
**
**    pExpr->iDb           Set the index in db->aDb[] of the database X
241
242
243
244
245
246
247
248
249


250
251
252
253
254
255
256
184
185
186
187
188
189
190


191
192
193
194
195
196
197
198
199







-
-
+
+







  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 */
  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. */
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
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







-
-
-
-
-
-











-







-
+







      for(i=0; i<db->nDb; i++){
        assert( db->aDb[i].zDbSName );
        if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){
          pSchema = db->aDb[i].pSchema;
          break;
        }
      }
      if( i==db->nDb && sqlite3StrICmp("main", zDb)==0 ){
        /* This branch is taken when the main database has been renamed
        ** using SQLITE_DBCONFIG_MAINDBNAME. */
        pSchema = db->aDb[0].pSchema;
        zDb = db->aDb[0].zDbSName;
      }
    }
  }

  /* Start at the inner-most context and move outward until a match is found */
  assert( pNC && cnt==0 );
  do{
    ExprList *pEList;
    SrcList *pSrcList = pNC->pSrcList;

    if( pSrcList ){
      for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
        u8 hCol;
        pTab = pItem->pTab;
        assert( pTab!=0 && pTab->zName!=0 );
        assert( pTab->nCol>0 );
        if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
          int hit = 0;
          pEList = pItem->pSelect->pEList;
          for(j=0; j<pEList->nExpr; j++){
            if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
            if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
              cnt++;
              cntTab = 2;
              pMatch = pItem;
              pExpr->iColumn = j;
              hit = 1;
            }
          }
329
330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
265
266
267
268
269
270
271

272

273
274
275
276
277
278
279
280







-

-
+







          if( IN_RENAME_OBJECT && pItem->zAlias ){
            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
          }
        }
        if( 0==(cntTab++) ){
          pMatch = pItem;
        }
        hCol = sqlite3StrIHash(zCol);
        for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
          if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            /* If there has been exactly one prior match and this match
            ** is for the right-hand table of a NATURAL JOIN or is in a 
            ** USING clause, then skip this match.
            */
            if( cnt==1 ){
              if( pItem->fg.jointype & JT_NATURAL ) continue;
              if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
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
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







-
+
-

-
+





-
-
-
-
-
-
-
-
+


-
+






-
+



-
+






-



-
+












-

-
+






-
+
-

+




-
-
-
-
-
-
-
-

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

-












-
+





-
+







        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
    ** maybe it is an excluded.* from an upsert.
    ** a reference in the RETURNING clause to a table being modified.
    */
    if( cnt==0 && zDb==0 ){
    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( pParse->bReturning ){
          if( (pNC->ncFlags & NC_UBaseReg)!=0
           && (zTab==0 || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0)
          ){
            pExpr->iTable = op!=TK_DELETE;
            pTab = pParse->pTriggerTab;
          }
        }else if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){
        if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
          pExpr->iTable = 1;
          pTab = pParse->pTriggerTab;
        }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){
        }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 && zTab!=0 ){
      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;
          pExpr->iTable = 2;
        }
      }
#endif /* SQLITE_OMIT_UPSERT */

      if( pTab ){ 
        int iCol;
        u8 hCol = sqlite3StrIHash(zCol);
        pSchema = pTab->pSchema;
        cntTab++;
        for(iCol=0, pCol=pTab->aCol; iCol<pTab->nCol; iCol++, pCol++){
          if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            if( iCol==pTab->iPKey ){
              iCol = -1;
            }
            break;
          }
        }
        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 ){
          if( pExpr->iTable==2 ){
            testcase( iCol==(-1) );
            if( IN_RENAME_OBJECT ){
              pExpr->iColumn = iCol;
              pExpr->y.pTab = pTab;
              eNewExprOp = TK_COLUMN;
            }else{
              pExpr->iTable = pNC->uNC.pUpsert->regData +
              pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
                 sqlite3TableColumnToStorage(pTab, iCol);
              eNewExprOp = TK_REGISTER;
              ExprSetProperty(pExpr, EP_Alias);
            }
          }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));
              }
            if( iCol<0 ){
              pExpr->affinity = 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) */

    /*
    ** Perhaps the name is a reference to the ROWID
    */
    if( cnt==0
     && cntTab==1
     && pMatch
     && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
     && (pNC->ncFlags & NC_IdxExpr)==0
     && sqlite3IsRowid(zCol)
     && VisibleRowid(pMatch->pTab)
    ){
      cnt = 1;
      pExpr->iColumn = -1;
      pExpr->affExpr = SQLITE_AFF_INTEGER;
      pExpr->affinity = SQLITE_AFF_INTEGER;
    }

    /*
    ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
    ** might refer to an result-set alias.  This happens, for example, when
    ** we are resolving names in the WHERE clause of the following command:
    **
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
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







-
+
-
-
+
-









-
+
-
-







-
+







    if( (pNC->ncFlags & NC_UEList)!=0
     && cnt==0
     && zTab==0
    ){
      pEList = pNC->uNC.pEList;
      assert( pEList!=0 );
      for(j=0; j<pEList->nExpr; j++){
        char *zAs = pEList->a[j].zEName;
        char *zAs = pEList->a[j].zName;
        if( pEList->a[j].eEName==ENAME_NAME
         && sqlite3_stricmp(zAs, zCol)==0
        if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
        ){
          Expr *pOrig;
          assert( pExpr->pLeft==0 && pExpr->pRight==0 );
          assert( pExpr->x.pList==0 );
          assert( pExpr->x.pSelect==0 );
          pOrig = pEList->a[j].pExpr;
          if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
            sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
            return WRC_Abort;
          }
          if( ExprHasProperty(pOrig, EP_Win)
          if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){
           && ((pNC->ncFlags&NC_AllowWin)==0 || pNC!=pTopNC )
          ){
            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);
          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;
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
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







-
+
-
-
-













-
-
-
-
-







  ** pExpr.
  **
  ** Because no reference was made to outer contexts, the pNC->nRef
  ** fields are not changed in any context.
  */
  if( cnt==0 && zTab==0 ){
    assert( pExpr->op==TK_ID );
    if( ExprHasProperty(pExpr,EP_DblQuoted)
    if( ExprHasProperty(pExpr,EP_DblQuoted) ){
     && areDoubleQuotedStringsEnabled(db, pTopNC)
     && (db->init.bDropColumn==0 || sqlite3StrICmp(zCol, db->init.azInit[0])!=0)
    ){
      /* If a double-quoted identifier does not match any known column name,
      ** then treat it as a string.
      **
      ** This hack was added in the early days of SQLite in a misguided attempt
      ** to be compatible with MySQL 3.x, which used double-quotes for strings.
      ** I now sorely regret putting in this hack. The effect of this hack is
      ** that misspelled identifier names are silently converted into strings
      ** rather than causing an error, to the frustration of countless
      ** programmers. To all those frustrated programmers, my apologies.
      **
      ** Someday, I hope to get rid of this hack. Unfortunately there is
      ** a huge amount of legacy SQL that uses it. So for now, we just
      ** issue a warning.
      **
      ** 2021-03-15: ticket 1c24a659e6d7f3a1
      ** Do not do the ID-to-STRING conversion when doing the schema
      ** sanity check following a DROP COLUMN if the identifer name matches
      ** the name of the column being dropped.
      */
      sqlite3_log(SQLITE_WARNING,
        "double-quoted string literal: \"%w\"", zCol);
#ifdef SQLITE_ENABLE_NORMALIZE
      sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol);
#endif
      pExpr->op = TK_STRING;
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
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







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


+
+
+
+
+
+
-
+




-
-
-
-
-
+
+
+
+
-





-
-
+
-
-


-







    }
    pParse->checkSchema = 1;
    pTopNC->nErr++;
  }

  /* If a column from a table in pSrcList is referenced, then record
  ** this fact in the pSrcList.a[].colUsed bitmask.  Column 0 causes
  ** bit 0 to be set.  Column 1 sets bit 1.  And so forth.  Bit 63 is
  ** bit 0 to be set.  Column 1 sets bit 1.  And so forth.  If the
  ** set if the 63rd or any subsequent column is used.
  **
  ** The colUsed mask is an optimization used to help determine if an
  ** index is a covering index.  The correct answer is still obtained
  ** if the mask contains extra set bits.  However, it is important to
  ** avoid setting bits beyond the maximum column number of the table.
  ** column number is greater than the number of bits in the bitmask
  ** (See ticket [b92e5e8ec2cdbaa1]).
  **
  ** If a generated column is referenced, set bits for every column
  ** of the table.
  ** then set the high-order bit of the bitmask.
  */
  if( pExpr->iColumn>=0 && pMatch!=0 ){
    int n = pExpr->iColumn;
    testcase( n==BMS-1 );
    if( n>=BMS ){
      n = BMS-1;
    }
    assert( pMatch->iCursor==pExpr->iTable );
    pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
    pMatch->colUsed |= ((Bitmask)1)<<n;
  }

  /* 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;
  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
    if( !ExprHasProperty(pExpr, EP_Alias) ){
     && (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;
671
672
673
674
675
676
677
678
679


680
681
682
683
684
685
686
687
688
689
690
691
692
693
694



695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720




721

722


723
724


725
726

727
728
729
730
731

732
733

734
735
736

737
738
739
740
741
742
743
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







-
-
+
+





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








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

-
-
-
-
+
+
+
+
-
+

+
+
-
-
+
+

-
+

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







/*
** 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;
    struct SrcList_item *pItem = &pSrc->a[iSrc];
    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
       && (pTab->aCol[iCol].colFlags & COLFLAG_GENERATED)!=0
      ){
        testcase( pTab->nCol==63 );
        testcase( pTab->nCol==64 );
        pItem->colUsed = pTab->nCol>=64 ? ALLBITS : MASKBIT(pTab->nCol)-1;
      }else{
        testcase( iCol==BMS );
        testcase( iCol==BMS-1 );
        pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
      testcase( iCol==BMS );
      testcase( iCol==BMS-1 );
      pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
      }
    }
  }
  return p;
}

/*
** Report an error that an expression is not valid for some set of
** pNC->ncFlags values determined by validMask.
**
** static void notValid(
**   Parse *pParse,       // Leave error message here
**   NameContext *pNC,    // The name context 
**   const char *zMsg,    // Type of error
**   int validMask,       // Set of contexts for which prohibited
**   Expr *pExpr          // Invalidate this expression on error
** ){...}
**
** As an optimization, since the conditional is almost always false
** (because errors are rare), the conditional is moved outside of the
** function call using a macro.
*/
static void notValidImpl(
   Parse *pParse,       /* Leave error message here */
   NameContext *pNC,    /* The name context */
   const char *zMsg,    /* Type of error */
static void notValid(
  Parse *pParse,       /* Leave error message here */
  NameContext *pNC,    /* The name context */
  const char *zMsg,    /* Type of error */
   Expr *pExpr          /* Invalidate this expression on error */
  int validMask        /* Set of contexts for which prohibited */
){
  assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 );
  if( (pNC->ncFlags & validMask)!=0 ){
  const char *zIn = "partial index WHERE clauses";
  if( pNC->ncFlags & NC_IdxExpr )      zIn = "index expressions";
    const char *zIn = "partial index WHERE clauses";
    if( pNC->ncFlags & NC_IdxExpr )      zIn = "index expressions";
#ifndef SQLITE_OMIT_CHECK
  else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
    else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
#endif
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
#endif
  sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
    sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
  if( pExpr ) pExpr->op = TK_NULL;
}
  }
#define sqlite3ResolveNotValid(P,N,M,X,E) \
  assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
  if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E);
}

/*
** Expression p should encode a floating point value between 1.0 and 0.0.
** Return 1024 times this value.  Or return -1 if p is not a floating point
** value between 1.0 and 0.0.
*/
static int exprProbability(Expr *p){
776
777
778
779
780
781
782

783
784
785

786
787
788
789
790
791


792

793
794
795
796
797


798
799
800

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

815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
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







+


-
+
-



-
-
+
+

+



-
-
+
+


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







    for(i=0; i<pNC->pSrcList->nSrc; i++){
      assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
    }
  }
#endif
  switch( pExpr->op ){

#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
    /* 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 
    ** clause processing on UPDATE and DELETE statements.
    ** UPDATE ... FROM statement processing.
    */
    case TK_ROW: {
      SrcList *pSrcList = pNC->pSrcList;
      SrcItem *pItem;
      assert( pSrcList && pSrcList->nSrc>=1 );
      struct SrcList_item *pItem;
      assert( pSrcList && pSrcList->nSrc==1 );
      pItem = pSrcList->a;
      assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
      pExpr->op = TK_COLUMN;
      pExpr->y.pTab = pItem->pTab;
      pExpr->iTable = pItem->iCursor;
      pExpr->iColumn--;
      pExpr->affExpr = SQLITE_AFF_INTEGER;
      pExpr->iColumn = -1;
      pExpr->affinity = SQLITE_AFF_INTEGER;
      break;
    }

#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
    /* 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.
    */
          && !defined(SQLITE_OMIT_SUBQUERY) */
    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 
856
857
858
859
860
861
862
863
864
865

866
867
868
869
870
871
872
873
693
694
695
696
697
698
699



700

701
702
703
704
705
706
707







-
-
-
+
-








      if( pExpr->op==TK_ID ){
        zDb = 0;
        zTable = 0;
        zColumn = pExpr->u.zToken;
      }else{
        Expr *pLeft = pExpr->pLeft;
        testcase( pNC->ncFlags & NC_IdxExpr );
        testcase( pNC->ncFlags & NC_GenCol );
        sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
        notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
                               NC_IdxExpr|NC_GenCol, 0);
        pRight = pExpr->pRight;
        if( pRight->op==TK_ID ){
          zDb = 0;
        }else{
          assert( pRight->op==TK_DOT );
          zDb = pLeft->u.zToken;
          pLeft = pRight->pLeft;
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
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







-
+
-
-














-
+







      int wrong_num_args = 0;     /* True if wrong number of arguments */
      int is_agg = 0;             /* True if is an aggregate function */
      int nId;                    /* Number of characters in function name */
      const char *zId;            /* The function name. */
      FuncDef *pDef;              /* Information about the function */
      u8 enc = ENC(pParse->db);   /* The database encoding */
      int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
#ifndef SQLITE_OMIT_WINDOWFUNC

      Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
#endif
      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
      zId = pExpr->u.zToken;
      nId = sqlite3Strlen30(zId);
      pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
      if( pDef==0 ){
        pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
        if( pDef==0 ){
          no_such_func = 1;
        }else{
          wrong_num_args = 1;
        }
      }else{
        is_agg = pDef->xFinalize!=0;
        if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
          ExprSetProperty(pExpr, EP_Unlikely);
          ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
          if( n==2 ){
            pExpr->iTable = exprProbability(pList->a[1].pExpr);
            if( pExpr->iTable<0 ){
              sqlite3ErrorMsg(pParse,
                "second argument to likelihood() must be a "
                "constant between 0.0 and 1.0");
              pNC->nErr++;
948
949
950
951
952
953
954
955

956
957
958
959
960
961

962
963

964
965
966
967


968
969
970
971
972
973
974
975

976
977
978

979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997

998
999
1000
1001
1002
1003
1004
1005


1006
1007
1008

1009
1010
1011
1012
1013
1014
1015
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







-
+
-



-
-
+

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



-
+


-
+
-
-


-
-
-
-
-









-
+






-
-
+
+


-
+







            return WRC_Prune;
          }
        }
#endif
        if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
          /* For the purposes of the EP_ConstFunc flag, date and time
          ** functions and other functions that change slowly are considered
          ** constant because they are constant for the duration of one query.
          ** constant because they are constant for the duration of one query */
          ** This allows them to be factored out of inner loops. */
          ExprSetProperty(pExpr,EP_ConstFunc);
        }
        if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
          /* Clearly non-deterministic functions like random(), but also
          ** date/time functions that use 'now', and other functions like
          /* Date/time functions that use 'now', and other functions like
          ** sqlite_version() that might change over time cannot be used
          ** in an index or generated column.  Curiously, they can be used
          ** in an index. */
          ** in a CHECK constraint.  SQLServer, MySQL, and PostgreSQL all
          ** all this. */
          sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
                                 NC_IdxExpr|NC_PartIdx|NC_GenCol, 0);
          notValid(pParse, pNC, "non-deterministic functions",
                   NC_IdxExpr|NC_PartIdx);
        }else{
          assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
          pExpr->op2 = pNC->ncFlags & NC_SelfRef;
          if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
        }
        if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
         && pParse->nested==0
         && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
         && sqlite3Config.bInternalFunctions==0
        ){
          /* Internal-use-only functions are disallowed unless the
          ** SQL is being compiled using sqlite3NestedParse() or
          ** SQL is being compiled using sqlite3NestedParse() */
          ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
          ** used to activate internal functionsn for testing purposes */
          no_such_func = 1;
          pDef = 0;
        }else
        if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
         && !IN_RENAME_OBJECT
        ){
          sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
        }
      }

      if( 0==IN_RENAME_OBJECT ){
#ifndef SQLITE_OMIT_WINDOWFUNC
        assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
          || (pDef->xValue==0 && pDef->xInverse==0)
          || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
        );
        if( pDef && pDef->xValue==0 && pWin ){
        if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
          sqlite3ErrorMsg(pParse, 
              "%.*s() may not be used as a window function", nId, zId
          );
          pNC->nErr++;
        }else if( 
              (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
           || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin)
           || (is_agg && pWin && (pNC->ncFlags & NC_AllowWin)==0)
           || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
           || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
        ){
          const char *zType;
          if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
          if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
            zType = "window";
          }else{
            zType = "aggregate";
          }
          sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
          pNC->nErr++;
          is_agg = 0;
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
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







-
-
-
-
-
-
-
-
-





-
+





-
-
-
-
-



-
+

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







-
-
-
-
-




-
-
+
+







          sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
          pNC->nErr++;
        }else if( wrong_num_args ){
          sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
               nId, zId);
          pNC->nErr++;
        }
#ifndef SQLITE_OMIT_WINDOWFUNC
        else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
          sqlite3ErrorMsg(pParse, 
              "FILTER may not be used with non-aggregate %.*s()", 
              nId, zId
          );
          pNC->nErr++;
        }
#endif
        if( is_agg ){
          /* Window functions may not be arguments of aggregate functions.
          ** Or arguments of other window functions. But aggregate functions
          ** may be arguments for window functions.  */
#ifndef SQLITE_OMIT_WINDOWFUNC
          pNC->ncFlags &= ~(NC_AllowWin | (!pWin ? NC_AllowAgg : 0));
          pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0));
#else
          pNC->ncFlags &= ~NC_AllowAgg;
#endif
        }
      }
#ifndef SQLITE_OMIT_WINDOWFUNC
      else if( ExprHasProperty(pExpr, EP_WinFunc) ){
        is_agg = 1;
      }
#endif
      sqlite3WalkExprList(pWalker, pList);
      if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
        if( pWin ){
        if( pExpr->y.pWin ){
          Select *pSel = pNC->pWinSelect;
          assert( pWin==pExpr->y.pWin );
          if( IN_RENAME_OBJECT==0 ){
            sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
            if( pParse->db->mallocFailed ) break;
          }
          sqlite3WalkExprList(pWalker, pWin->pPartition);
          sqlite3WalkExprList(pWalker, pWin->pOrderBy);
          sqlite3WalkExpr(pWalker, pWin->pFilter);
          sqlite3WindowLink(pSel, pWin);
          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
          sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
          if( 0==pSel->pWin 
           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) 
          ){
            pExpr->y.pWin->pNextWin = pSel->pWin;
            pSel->pWin = pExpr->y.pWin;
          }
          pNC->ncFlags |= NC_HasWin;
        }else
#endif /* SQLITE_OMIT_WINDOWFUNC */
        {
          NameContext *pNC2 = pNC;
          pExpr->op = TK_AGG_FUNCTION;
          pExpr->op2 = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
          if( ExprHasProperty(pExpr, EP_WinFunc) ){
            sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
          }
#endif
          while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
            pExpr->op2++;
            pNC2 = pNC2->pNext;
          }
          assert( pDef!=0 || IN_RENAME_OBJECT );
          if( pNC2 && pDef ){
          assert( pDef!=0 );
          if( pNC2 ){
            assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
            testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
            pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);

          }
        }
        pNC->ncFlags |= savedAllowFlags;
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
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







-
-
-
-
-
+
-










-
-
-
-
-
+
-




-
+



-
+








-
+







    case TK_SELECT:
    case TK_EXISTS:  testcase( pExpr->op==TK_EXISTS );
#endif
    case TK_IN: {
      testcase( pExpr->op==TK_IN );
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        int nRef = pNC->nRef;
        testcase( pNC->ncFlags & NC_IsCheck );
        testcase( pNC->ncFlags & NC_PartIdx );
        testcase( pNC->ncFlags & NC_IdxExpr );
        testcase( pNC->ncFlags & NC_GenCol );
        sqlite3ResolveNotValid(pParse, pNC, "subqueries",
        notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
                 NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
        sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
          pNC->ncFlags |= NC_VarSelect;
        }
      }
      break;
    }
    case TK_VARIABLE: {
      testcase( pNC->ncFlags & NC_IsCheck );
      testcase( pNC->ncFlags & NC_PartIdx );
      testcase( pNC->ncFlags & NC_IdxExpr );
      testcase( pNC->ncFlags & NC_GenCol );
      sqlite3ResolveNotValid(pParse, pNC, "parameters",
      notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
               NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
      break;
    }
    case TK_IS:
    case TK_ISNOT: {
      Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
      Expr *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) ){
      if( (pRight = pExpr->pRight)->op==TK_ID ){
        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;
        }
      }
      /* no break */ deliberate_fall_through
      /* Fall thru */
    }
    case TK_BETWEEN:
    case TK_EQ:
    case TK_NE:
    case TK_LT:
    case TK_LE:
    case TK_GT:
1210
1211
1212
1213
1214
1215
1216
1217
1218


1219
1220
1221
1222
1223
1224
1225
1226
999
1000
1001
1002
1003
1004
1005


1006
1007

1008
1009
1010
1011
1012
1013
1014







-
-
+
+
-







  int i;             /* Loop counter */

  UNUSED_PARAMETER(pParse);

  if( pE->op==TK_ID ){
    char *zCol = pE->u.zToken;
    for(i=0; i<pEList->nExpr; i++){
      if( pEList->a[i].eEName==ENAME_NAME
       && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0
      char *zAs = pEList->a[i].zName;
      if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
      ){
        return i+1;
      }
    }
  }
  return 0;
}

1263
1264
1265
1266
1267
1268
1269
1270

1271
1272
1273
1274
1275
1276
1277
1051
1052
1053
1054
1055
1056
1057

1058
1059
1060
1061
1062
1063
1064
1065







-
+







  nc.pParse = pParse;
  nc.pSrcList = pSelect->pSrc;
  nc.uNC.pEList = pEList;
  nc.ncFlags = NC_AllowAgg|NC_UEList;
  nc.nErr = 0;
  db = pParse->db;
  savedSuppErr = db->suppressErr;
  if( IN_RENAME_OBJECT==0 ) db->suppressErr = 1;
  db->suppressErr = 1;
  rc = sqlite3ResolveExprNames(&nc, pE);
  db->suppressErr = savedSuppErr;
  if( rc ) return 0;

  /* Try to match the ORDER BY expression against an expression
  ** in the result set.  Return an 1-based index of the matching
  ** result-set entry.
1345
1346
1347
1348
1349
1350
1351
1352

1353
1354
1355
1356
1357
1358
1359
1360
1133
1134
1135
1136
1137
1138
1139

1140

1141
1142
1143
1144
1145
1146
1147







-
+
-







    moreToDo = 0;
    pEList = pSelect->pEList;
    assert( pEList!=0 );
    for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
      int iCol = -1;
      Expr *pE, *pDup;
      if( pItem->done ) continue;
      pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
      pE = sqlite3ExprSkipCollate(pItem->pExpr);
      if( NEVER(pE==0) ) continue;
      if( sqlite3ExprIsInteger(pE, &iCol) ){
        if( iCol<=0 || iCol>pEList->nExpr ){
          resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
          return 1;
        }
      }else{
        iCol = resolveAsName(pParse, pEList, pE);
1440
1441
1442
1443
1444
1445
1446
1447

1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460


1461
1462
1463
1464
1465
1466
1467
1468

1469
1470
1471
1472
1473
1474







1475
1476
1477
1478
1479
1480
1481
1482
1483

1484
1485
1486
1487
1488
1489
1490






1491
1492
1493
1494


1495
1496
1497
1498
1499
1500
1501
1227
1228
1229
1230
1231
1232
1233

1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
1254
1255

1256
1257
1258

1259


1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274

1275







1276
1277
1278
1279
1280
1281

1282


1283
1284
1285
1286
1287
1288
1289
1290
1291







-
+












-
+
+







-
+


-

-
-
+
+
+
+
+
+
+








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

-
-
+
+







  const char *zType     /* "ORDER" or "GROUP" */
){
  int i;
  sqlite3 *db = pParse->db;
  ExprList *pEList;
  struct ExprList_item *pItem;

  if( pOrderBy==0 || pParse->db->mallocFailed || IN_RENAME_OBJECT ) return 0;
  if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
  if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
    sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
    return 1;
  }
  pEList = pSelect->pEList;
  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);
      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
                   zType,0);
    }
  }
  return 0;
}

#ifndef SQLITE_OMIT_WINDOWFUNC
/*
** Walker callback for windowRemoveExprFromSelect().
** Walker callback for resolveRemoveWindows().
*/
static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){
  UNUSED_PARAMETER(pWalker);
  if( ExprHasProperty(pExpr, EP_WinFunc) ){
    Window *pWin = pExpr->y.pWin;
    sqlite3WindowUnlinkFromSelect(pWin);
    Window **pp;
    for(pp=&pWalker->u.pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
      if( *pp==pExpr->y.pWin ){
        *pp = (*pp)->pNextWin;
        break;
      }    
    }
  }
  return WRC_Continue;
}

/*
** Remove any Window objects owned by the expression pExpr from the
** Select.pWin list of Select object pSelect.
*/
static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){
static void resolveRemoveWindows(Select *pSelect, Expr *pExpr){
  if( pSelect->pWin ){
    Walker sWalker;
    memset(&sWalker, 0, sizeof(Walker));
    sWalker.xExprCallback = resolveRemoveWindowsCb;
    sWalker.u.pSelect = pSelect;
    sqlite3WalkExpr(&sWalker, pExpr);
  }
  Walker sWalker;
  memset(&sWalker, 0, sizeof(Walker));
  sWalker.xExprCallback = resolveRemoveWindowsCb;
  sWalker.u.pSelect = pSelect;
  sqlite3WalkExpr(&sWalker, pExpr);
}
}
#else
# define windowRemoveExprFromSelect(a, b)
#endif /* SQLITE_OMIT_WINDOWFUNC */
# define resolveRemoveWindows(x,y)
#endif

/*
** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
** The Name context of the SELECT statement is pNC.  zType is either
** "ORDER" or "GROUP" depending on which type of clause pOrderBy is.
**
** This routine resolves each term of the clause into an expression.
1524
1525
1526
1527
1528
1529
1530
1531

1532
1533
1534
1535
1536
1537
1538
1539
1314
1315
1316
1317
1318
1319
1320

1321

1322
1323
1324
1325
1326
1327
1328







-
+
-







  int nResult;                   /* Number of terms in the result set */

  if( pOrderBy==0 ) return 0;
  nResult = pSelect->pEList->nExpr;
  pParse = pNC->pParse;
  for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
    Expr *pE = pItem->pExpr;
    Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE);
    Expr *pE2 = sqlite3ExprSkipCollate(pE);
    if( NEVER(pE2==0) ) continue;
    if( zType[0]!='G' ){
      iCol = resolveAsName(pParse, pSelect->pEList, pE2);
      if( iCol>0 ){
        /* If an AS-name match is found, mark this ORDER BY column as being
        ** a copy of the iCol-th result-set column.  The subsequent call to
        ** sqlite3ResolveOrderGroupBy() will convert the expression to a
        ** copy of the iCol-th result-set expression. */
1559
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
1348
1349
1350
1351
1352
1353
1354

1355
1356
1357
1358
1359
1360
1361
1362







-
+







      return 1;
    }
    for(j=0; j<pSelect->pEList->nExpr; j++){
      if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
        /* Since this expresion is being changed into a reference
        ** to an identical expression in the result set, remove all Window
        ** objects belonging to the expression from the Select.pWin list. */
        windowRemoveExprFromSelect(pSelect, pE);
        resolveRemoveWindows(pSelect, pE);
        pItem->u.x.iOrderByCol = j+1;
      }
    }
  }
  return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}

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







-
+

+
-
+

+
+
+
+
+
+
+






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







      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];
      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 = pOuterNC ? pOuterNC->nRef : 0;
        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;

        /* 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);
        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;
1699
1700
1701
1702
1703
1704
1705
1706

1707
1708
1709
1710
1711
1712
1713
1714

1715
1716
1717
1718
1719
1720
1721
1489
1490
1491
1492
1493
1494
1495

1496
1497
1498
1499
1500
1501
1502
1503

1504
1505
1506
1507
1508
1509
1510
1511







-
+







-
+







    ** 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 );
    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++){
      SrcItem *pItem = &p->pSrc->a[i];
      struct SrcList_item *pItem = &p->pSrc->a[i];
      if( pItem->fg.isTabFunc
       && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) 
      ){
        return WRC_Abort;
      }
    }

1858
1859
1860
1861
1862
1863
1864
1865

1866
1867
1868
1869
1870
1871
1872
1648
1649
1650
1651
1652
1653
1654

1655
1656
1657
1658
1659
1660
1661
1662







-
+







** An error message is left in pParse if anything is amiss.  The number
** if errors is returned.
*/
int sqlite3ResolveExprNames( 
  NameContext *pNC,       /* Namespace to resolve expressions in. */
  Expr *pExpr             /* The expression to be analyzed. */
){
  int savedHasAgg;
  u16 savedHasAgg;
  Walker w;

  if( pExpr==0 ) return SQLITE_OK;
  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
  w.pParse = pNC->pParse;
  w.xExprCallback = resolveExprStep;
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
1688
1689
1690
1691
1692
1693
1694



1695








1696






1697
1698














1699



1700
1701
1702
1703
1704
1705
1706







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

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







** list rather than a single expression.
*/
int sqlite3ResolveExprListNames( 
  NameContext *pNC,       /* Namespace to resolve expressions in. */
  ExprList *pList         /* The expression list to be analyzed. */
){
  int i;
  int savedHasAgg = 0;
  Walker w;
  if( pList==0 ) return WRC_Continue;
  if( pList ){
  w.pParse = pNC->pParse;
  w.xExprCallback = resolveExprStep;
  w.xSelectCallback = resolveSelectStep;
  w.xSelectCallback2 = 0;
  w.u.pNC = pNC;
  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
  for(i=0; i<pList->nExpr; i++){
    for(i=0; i<pList->nExpr; i++){
    Expr *pExpr = pList->a[i].pExpr;
    if( pExpr==0 ) continue;
#if SQLITE_MAX_EXPR_DEPTH>0
    w.pParse->nHeight += pExpr->nHeight;
    if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
      return WRC_Abort;
      if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
    }
#endif
    sqlite3WalkExpr(&w, pExpr);
#if SQLITE_MAX_EXPR_DEPTH>0
    w.pParse->nHeight -= pExpr->nHeight;
#endif
    assert( EP_Agg==NC_HasAgg );
    assert( EP_Win==NC_HasWin );
    testcase( pNC->ncFlags & NC_HasAgg );
    testcase( pNC->ncFlags & NC_HasWin );
    if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin) ){
      ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
      savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
      pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
    }
  }
    if( pNC->nErr>0 || w.pParse->nErr>0 ) return WRC_Abort;
  }
  pNC->ncFlags |= savedHasAgg;
  return WRC_Continue;
}

/*
** Resolve all names in all expressions of a SELECT and in all
** decendents of the SELECT, including compounds off of p->pPrior,
** subqueries in expressions, and subqueries used as FROM clause
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
1728
1729
1730
1731
1732
1733
1734






1735
1736
1737
1738

1739
1740
1741
1742
1743
1744
1745
1746





1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757

1758

1759
1760
1761
1762
1763
1764
1765





1766
1767
1768

1769
1770
1771
1772
1773







-
-
-
-
-
-
+
+
+
+
-








-
-
-
-
-
+
+
+
+
+






-
+
-







-
-
-
-
-



-
+




  sqlite3WalkSelect(&w, p);
}

/*
** Resolve names in expressions that can only reference a single table
** or which cannot reference any tables at all.  Examples:
**
**                                                    "type" flag
**                                                    ------------
**    (1)   CHECK constraints                         NC_IsCheck
**    (2)   WHERE clauses on partial indices          NC_PartIdx
**    (3)   Expressions in indexes on expressions     NC_IdxExpr
**    (4)   Expression arguments to VACUUM INTO.      0
**    (1)   CHECK constraints
**    (2)   WHERE clauses on partial indices
**    (3)   Expressions in indexes on expressions
**    (4)   Expression arguments to VACUUM INTO.
**    (5)   GENERATED ALWAYS as expressions           NC_GenCol
**
** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
** nodes of the expression is set to -1 and the Expr.iColumn value is
** set to the column number.  In case (4), TK_COLUMN nodes cause an error.
**
** Any errors cause an error message to be set in pParse.
*/
int sqlite3ResolveSelfReference(
  Parse *pParse,   /* Parsing context */
  Table *pTab,     /* The table being referenced, or NULL */
  int type,        /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */
  Expr *pExpr,     /* Expression to resolve.  May be NULL. */
  ExprList *pList  /* Expression list to resolve.  May be NULL. */
  Parse *pParse,      /* Parsing context */
  Table *pTab,        /* The table being referenced, or NULL */
  int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */
  Expr *pExpr,        /* Expression to resolve.  May be NULL. */
  ExprList *pList     /* Expression list to resolve.  May be NULL. */
){
  SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
  NameContext sNC;                /* Name context for pParse->pNewTable */
  int rc;

  assert( type==0 || pTab!=0 );
  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr
  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 );
          || type==NC_GenCol || pTab==0 );
  memset(&sNC, 0, sizeof(sNC));
  memset(&sSrc, 0, sizeof(sSrc));
  if( pTab ){
    sSrc.nSrc = 1;
    sSrc.a[0].zName = pTab->zName;
    sSrc.a[0].pTab = pTab;
    sSrc.a[0].iCursor = -1;
    if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){
      /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP
      ** schema elements */
      type |= NC_FromDDL;
    }
  }
  sNC.pParse = pParse;
  sNC.pSrcList = &sSrc;
  sNC.ncFlags = type | NC_IsDDL;
  sNC.ncFlags = type;
  if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc;
  if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList);
  return rc;
}

Changes to src/rowset.c.

173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187







-
+







  sqlite3RowSetClear(pArg);
  sqlite3DbFree(((RowSet*)pArg)->db, pArg);
}

/*
** Allocate a new RowSetEntry object that is associated with the
** given RowSet.  Return a pointer to the new and completely uninitialized
** object.
** objected.
**
** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
** routine returns NULL.
*/
static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
  assert( p!=0 );
  if( p->nFresh==0 ){  /*OPTIMIZATION-IF-FALSE*/
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463







-
+







  ** To save unnecessary work, only do this when the batch number changes.
  */
  if( iBatch!=pRowSet->iBatch ){  /*OPTIMIZATION-IF-FALSE*/
    p = pRowSet->pEntry;
    if( p ){
      struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
        /* Only sort the current set of entries if they need it */
        /* Only sort the current set of entiries if they need it */
        p = rowSetEntrySort(p);
      }
      for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
        ppPrevTree = &pTree->pRight;
        if( pTree->pLeft==0 ){
          pTree->pLeft = rowSetListToTree(p);
          break;

Changes to src/select.c.

9
10
11
12
13
14
15














16
17
18
19
20
21
22
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







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







**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
*/
#include "sqliteInt.h"

/*
** Trace output macros
*/
#if SELECTTRACE_ENABLED
/***/ int sqlite3SelectTrace = 0;
# 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)
#endif


/*
** An instance of the following object is used to record information about
** how to process the DISTINCT keyword, to simplify passing that information
** into the selectInnerLoop() routine.
*/
typedef struct DistinctCtx DistinctCtx;
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
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







-
+
-
-
-











-




-
-
-
-

+












-







#endif
  struct RowLoadInfo *pDeferredRowLoad;  /* Deferred row loading info or NULL */
};
#define SORTFLAG_UseSorter  0x01   /* Use SorterOpen instead of OpenEphemeral */

/*
** Delete all the content of a Select structure.  Deallocate the structure
** itself depending on the value of bFree
** itself only if bFree is true.
**
** If bFree==1, call sqlite3DbFree() on the p object.
** If bFree==0, Leave the first Select object unfreed
*/
static void clearSelect(sqlite3 *db, Select *p, int bFree){
  while( p ){
    Select *pPrior = p->pPrior;
    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( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
    if( bFree ) sqlite3DbFreeNN(db, p);
    p = pPrior;
    bFree = 1;
  }
}

/*
** Initialize a SelectDest structure.
*/
void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
  pDest->eDest = (u8)eDest;
  pDest->iSDParm = iParm;
  pDest->iSDParm2 = 0;
  pDest->zAffSdst = 0;
  pDest->iSdst = 0;
  pDest->nSdst = 0;
}


/*
125
126
127
128
129
130
131
132

133
134

135
136
137
138
139
140
141
131
132
133
134
135
136
137

138
139

140
141
142
143
144
145
146
147







-
+

-
+







  Expr *pWhere,         /* the WHERE clause */
  ExprList *pGroupBy,   /* the GROUP BY clause */
  Expr *pHaving,        /* the HAVING clause */
  ExprList *pOrderBy,   /* the ORDER BY clause */
  u32 selFlags,         /* Flag parameters, such as SF_Distinct */
  Expr *pLimit          /* LIMIT value.  NULL means not used */
){
  Select *pNew, *pAllocated;
  Select *pNew;
  Select standin;
  pAllocated = pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
  pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
  if( pNew==0 ){
    assert( pParse->db->mallocFailed );
    pNew = &standin;
  }
  if( pEList==0 ){
    pEList = sqlite3ExprListAppend(pParse, 0,
                                   sqlite3Expr(pParse->db,TK_ASTERISK,0));
161
162
163
164
165
166
167
168

169
170
171

172

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

174
175
176
177
178

179
180
181
182
183
184
185
186







-
+



+
-
+







  pNew->pWith = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
  pNew->pWin = 0;
  pNew->pWinDefn = 0;
#endif
  if( pParse->db->mallocFailed ) {
    clearSelect(pParse->db, pNew, pNew!=&standin);
    pAllocated = 0;
    pNew = 0;
  }else{
    assert( pNew->pSrc!=0 || pParse->nErr>0 );
  }
  assert( pNew!=&standin );
  return pAllocated;
  return pNew;
}


/*
** Delete the given Select structure and all of its substructures.
*/
void sqlite3SelectDelete(sqlite3 *db, Select *p){
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
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







-
+

-
-
-
-
+
+


















-
+
-






-
-
+
+
-
-







  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){
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;
  for(i=0; i<pTab->nCol; i++){
    if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
  }
  return -1;
}

/*
** Search the first N tables in pSrc, from left to right, looking for a
** table that has a column named zCol.  
**
** When found, set *piTab and *piCol to the table index and column index
** of the matching column and return TRUE.
**
** If not found, return FALSE.
*/
static int tableAndColumnIndex(
  SrcList *pSrc,       /* Array of tables to search */
  int N,               /* Number of tables in pSrc->a[] to search */
  const char *zCol,    /* Name of the column we are looking for */
  int *piTab,          /* Write index of pSrc->a[] here */
  int *piCol,          /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
  int *piCol           /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
  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 
    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;
      }
      return 1;
    }
  }
347
348
349
350
351
352
353
354

355
356

357
358
359
360
361
362
363
349
350
351
352
353
354
355

356
357

358
359
360
361
362
363
364
365







-
+

-
+







  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;
    pEq->iRightJoinTable = (i16)pE2->iTable;
  }
  *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
  *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
}

/*
** Set the EP_FromJoin property on all terms of the given expression.
** And set the Expr.iRightJoinTable to iTable for every term in the
** expression.
**
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
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







-
+




-
+



-
+


-
+




-
+











-
-
-







** The where clause needs to defer the handling of the t1.x=5
** term until after the t2 loop of the join.  In that way, a
** NULL t2 row will be inserted whenever t1.x!=5.  If we do not
** defer the handling of t1.x=5, it will be processed immediately
** after the t1 loop and rows with t1.x!=5 will never appear in
** the output, which is incorrect.
*/
void sqlite3SetJoinExpr(Expr *p, int iTable){
static void setJoinExpr(Expr *p, int iTable){
  while( p ){
    ExprSetProperty(p, EP_FromJoin);
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    ExprSetVVAProperty(p, EP_NoReduce);
    p->iRightJoinTable = iTable;
    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);
        setJoinExpr(p->x.pList->a[i].pExpr, iTable);
      }
    }
    sqlite3SetJoinExpr(p->pLeft, iTable);
    setJoinExpr(p->pLeft, iTable);
    p = p->pRight;
  } 
}

/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
/* Undo the work of setJoinExpr().  In the expression tree p, convert every
** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
** an ordinary term that omits the EP_FromJoin mark.
**
** 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);
      }
    }
    unsetJoinExpr(p->pLeft, iTable);
438
439
440
441
442
443
444
445
446


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


444
445
446
447
448
449
450
451
452







-
-
+
+







** 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 */
  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;
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
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







-

-
+

-
+
















-
-
+
+



















-
+

-
+







        return 1;
      }
      for(j=0; j<pRightTab->nCol; j++){
        char *zName;   /* Name of column in the right table */
        int iLeft;     /* Matching left table */
        int iLeftCol;  /* Matching column in the left table */

        if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue;
        zName = pRightTab->aCol[j].zName;
        if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){
        if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){
          addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
                isOuter, &p->pWhere);
                       isOuter, &p->pWhere);
        }
      }
    }

    /* Disallow both ON and USING clauses in the same join
    */
    if( pRight->pOn && pRight->pUsing ){
      sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
        "clauses in the same join");
      return 1;
    }

    /* Add the ON clause to the end of the WHERE clause, connected by
    ** an AND operator.
    */
    if( pRight->pOn ){
      if( isOuter ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor);
      p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
      if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
      p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
      pRight->pOn = 0;
    }

    /* Create extra terms on the WHERE clause for each column named
    ** in the USING clause.  Example: If the two tables to be joined are 
    ** A and B and the USING clause names X, Y, and Z, then add this
    ** to the WHERE clause:    A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
    ** Report an error if any column mentioned in the USING clause is
    ** not contained in both tables to be joined.
    */
    if( pRight->pUsing ){
      IdList *pList = pRight->pUsing;
      for(j=0; j<pList->nId; j++){
        char *zName;     /* 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);
        iRightCol = columnIndex(pRightTab, zName);
        if( iRightCol<0
         || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0)
         || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol)
        ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }
        addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
                     isOuter, &p->pWhere);
661
662
663
664
665
666
667
668

669
670
671
672
673
674
675
676
677
678
679
680
659
660
661
662
663
664
665

666
667
668
669
670

671
672
673
674
675
676
677







-
+




-







    }
    VdbeCoverage(v);
    sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat);
    pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
    if( pParse->db->mallocFailed ) return;
    pOp->p2 = nKey + nData;
    pKI = pOp->p4.pKeyInfo;
    memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */
    memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
    sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
    testcase( pKI->nAllField > pKI->nKeyField+2 );
    pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
                                           pKI->nAllField-pKI->nKeyField-1);
    pOp = 0; /* Ensure pOp not used after sqltie3VdbeAddOp3() */
    addrJmp = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
    pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse);
    pSort->regReturn = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
    sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
    if( iLimit ){
915
916
917
918
919
920
921
922

923
924
925
926
927
928
929
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926







-
+







    pParse->nMem += nResultCol;
  }
  pDest->nSdst = nResultCol;
  regOrig = regResult = pDest->iSdst;
  if( srcTab>=0 ){
    for(i=0; i<nResultCol; i++){
      sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
      VdbeComment((v, "%s", p->pEList->a[i].zEName));
      VdbeComment((v, "%s", p->pEList->a[i].zName));
    }
  }else if( eDest!=SRT_Exists ){
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
    ExprList *pExtra = 0;
#endif
    /* If the destination is an EXISTS(...) expression, the actual
    ** values returned by the SELECT are not required.
981
982
983
984
985
986
987
988

989
990
991
992
993
994
995
996
978
979
980
981
982
983
984

985

986
987
988
989
990
991
992







-
+
-








      testcase( regOrig );
      testcase( eDest==SRT_Set );
      testcase( eDest==SRT_Mem );
      testcase( eDest==SRT_Coroutine );
      testcase( eDest==SRT_Output );
      assert( eDest==SRT_Set || eDest==SRT_Mem 
           || eDest==SRT_Coroutine || eDest==SRT_Output
           || eDest==SRT_Coroutine || eDest==SRT_Output );
           || eDest==SRT_Upfrom );
    }
    sRowLoadInfo.regResult = regResult;
    sRowLoadInfo.ecelFlags = ecelFlags;
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
    sRowLoadInfo.pExtra = pExtra;
    sRowLoadInfo.regExtraResult = regResult + nResultCol;
    if( pExtra ) nResultCol += pExtra->nExpr;
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039







-







        ** row is all NULLs.
        */
        sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
        pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct);
        pOp->opcode = OP_Null;
        pOp->p1 = 1;
        pOp->p2 = regPrev;
        pOp = 0;  /* Ensure pOp is not used after sqlite3VdbeAddOp() */

        iJump = sqlite3VdbeCurrentAddr(v) + nResultCol;
        for(i=0; i<nResultCol; i++){
          CollSeq *pColl = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr);
          if( i<nResultCol-1 ){
            sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
            VdbeCoverage(v);
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
1126
1127
1128
1129
1130
1131
1132
























1133
1134
1135
1136
1137
1138
1139







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







        sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
        sqlite3ReleaseTempReg(pParse, r2);
      }
      sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1);
      break;
    }

    case SRT_Upfrom: {
      if( pSort ){
        pushOntoSorter(
            pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
      }else{
        int i2 = pDest->iSDParm2;
        int r1 = sqlite3GetTempReg(pParse);

        /* If the UPDATE FROM join is an aggregate that matches no rows, it
        ** might still be trying to return one row, because that is what
        ** aggregates do.  Don't record that empty row in the output table. */
        sqlite3VdbeAddOp2(v, OP_IsNull, regResult, iBreak); VdbeCoverage(v);

        sqlite3VdbeAddOp3(v, OP_MakeRecord,
                          regResult+(i2<0), nResultCol-(i2<0), r1);
        if( i2<0 ){
          sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, regResult);
        }else{
          sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, i2);
        }
      }
      break;
    }

#ifndef SQLITE_OMIT_SUBQUERY
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
    ** then there should be a single item on the stack.  Write this
    ** item into the set table with bogus data.
    */
    case SRT_Set: {
      if( pSort ){
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162







-







        sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, 
            r1, pDest->zAffSdst, nResultCol);
        sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
        sqlite3ReleaseTempReg(pParse, r1);
      }
      break;
    }


    /* If any row exist in the result set, record that fact and abort.
    */
    case SRT_Exists: {
      sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm);
      /* The LIMIT clause will terminate the loop for us */
      break;
1300
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310
1311
1312
1313
1314
1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283
1284







-
+







** Allocate a KeyInfo object sufficient for an index of N key columns and
** X extra columns.
*/
KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
  int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*);
  KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
  if( p ){
    p->aSortFlags = (u8*)&p->aColl[N+X];
    p->aSortOrder = (u8*)&p->aColl[N+X];
    p->nKeyField = (u16)N;
    p->nAllField = (u16)(N+X);
    p->enc = ENC(db);
    p->db = db;
    p->nRef = 1;
    memset(&p[1], 0, nExtra);
  }else{
1377
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392
1393

1394
1395
1396
1397
1398
1399
1400
1347
1348
1349
1350
1351
1352
1353

1354
1355
1356
1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368
1369
1370







-
+








-
+








  nExpr = pList->nExpr;
  pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1);
  if( pInfo ){
    assert( sqlite3KeyInfoIsWriteable(pInfo) );
    for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
      pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
      pInfo->aSortFlags[i-iStart] = pItem->sortFlags;
      pInfo->aSortOrder[i-iStart] = pItem->sortOrder;
    }
  }
  return pInfo;
}

/*
** Name of the connection operator, used for error messages.
*/
const char *sqlite3SelectOpName(int id){
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;
  }
1562
1563
1564
1565
1566
1567
1568
1569

1570
1571
1572
1573
1574
1575
1576
1532
1533
1534
1535
1536
1537
1538

1539
1540
1541
1542
1543
1544
1545
1546







-
+







      int iRead;
      if( aOutEx[i].u.x.iOrderByCol ){
        iRead = aOutEx[i].u.x.iOrderByCol-1;
      }else{
        iRead = iCol--;
      }
      sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
      VdbeComment((v, "%s", aOutEx[i].zEName));
      VdbeComment((v, "%s", aOutEx[i].zName?aOutEx[i].zName : aOutEx[i].zSpan));
    }
  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow);
      sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
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
1557
1558
1559
1560
1561
1562
1563











1564
1565
1566
1567
1568
1569
1570







-
-
-
-
-
-
-
-
-
-
-







      break;
    }
    case SRT_Mem: {
      /* The LIMIT clause will terminate the loop for us */
      break;
    }
#endif
    case SRT_Upfrom: {
      int i2 = pDest->iSDParm2;
      int r1 = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp3(v, OP_MakeRecord,regRow+(i2<0),nColumn-(i2<0),r1);
      if( i2<0 ){
        sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, regRow);
      }else{
        sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regRow, i2);
      }
      break;
    }
    default: {
      assert( eDest==SRT_Output || eDest==SRT_Coroutine ); 
      testcase( eDest==SRT_Output );
      testcase( eDest==SRT_Coroutine );
      if( eDest==SRT_Output ){
        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
      }else{
1680
1681
1682
1683
1684
1685
1686


1687
1688
1689
1690
1691
1692
1693
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654







+
+







  char const *zOrigDb = 0;
  char const *zOrigTab = 0;
  char const *zOrigCol = 0;
#endif

  assert( pExpr!=0 );
  assert( pNC->pSrcList!=0 );
  assert( pExpr->op!=TK_AGG_COLUMN );  /* This routine runes before aggregates
                                       ** are processed */
  switch( pExpr->op ){
    case TK_COLUMN: {
      /* The expression is a column. Locate the table the column is being
      ** extracted from in NameContext.pSrcList. This table may be real
      ** database table or a subquery.
      */
      Table *pTab = 0;            /* Table structure column is extracted from */
1907
1908
1909
1910
1911
1912
1913
1914

1915
1916

1917
1918
1919
1920
1921
1922
1923
1868
1869
1870
1871
1872
1873
1874

1875
1876

1877
1878
1879
1880
1881
1882
1883
1884







-
+

-
+







  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p = pEList->a[i].pExpr;

    assert( p!=0 );
    assert( p->op!=TK_AGG_COLUMN );  /* Agg processing has not run yet */
    assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
    if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){
    if( pEList->a[i].zName ){
      /* An AS clause always takes first priority */
      char *zName = pEList->a[i].zEName;
      char *zName = pEList->a[i].zName;
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
    }else if( srcName && p->op==TK_COLUMN ){
      char *zCol;
      int iCol = p->iColumn;
      pTab = p->y.pTab;
      assert( pTab!=0 );
      if( iCol<0 ) iCol = pTab->iPKey;
1931
1932
1933
1934
1935
1936
1937
1938

1939
1940
1941
1942
1943
1944
1945
1892
1893
1894
1895
1896
1897
1898

1899
1900
1901
1902
1903
1904
1905
1906







-
+







        char *zName = 0;
        zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC);
      }else{
        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
      }
    }else{
      const char *z = pEList->a[i].zEName;
      const char *z = pEList->a[i].zSpan;
      z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z);
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC);
    }
  }
  generateColumnTypes(pParse, pTabList, pEList);
}

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







-






-
+











-
+


-
-
+
+



+
-
+


+
+







-
+


-
+



















-







  int i, j;                   /* Loop counters */
  u32 cnt;                    /* Index added to make the name unique */
  Column *aCol, *pCol;        /* For looping over result columns */
  int nCol;                   /* Number of columns in the result set */
  char *zName;                /* Column name */
  int nName;                  /* Size of name in zName[] */
  Hash ht;                    /* Hash table of column names */
  Table *pTab;

  sqlite3HashInit(&ht);
  if( pEList ){
    nCol = pEList->nExpr;
    aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
    testcase( aCol==0 );
    if( NEVER(nCol>32767) ) nCol = 32767;
    if( nCol>32767 ) nCol = 32767;
  }else{
    nCol = 0;
    aCol = 0;
  }
  assert( nCol==(i16)nCol );
  *pnCol = nCol;
  *paCol = aCol;

  for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
    /* Get an appropriate name for the column
    */
    if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){
    if( (zName = pEList->a[i].zName)!=0 ){
      /* If the column contains an "AS <name>" phrase, use <name> as the name */
    }else{
      Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
      while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){
      Expr *pColExpr = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
      while( pColExpr->op==TK_DOT ){
        pColExpr = pColExpr->pRight;
        assert( pColExpr!=0 );
      }
      assert( pColExpr->op!=TK_AGG_COLUMN );
      if( pColExpr->op==TK_COLUMN && (pTab = pColExpr->y.pTab)!=0 ){
      if( pColExpr->op==TK_COLUMN ){
        /* For columns use the column name name */
        int iCol = pColExpr->iColumn;
        Table *pTab = pColExpr->y.pTab;
        assert( pTab!=0 );
        if( iCol<0 ) iCol = pTab->iPKey;
        zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
      }else if( pColExpr->op==TK_ID ){
        assert( !ExprHasProperty(pColExpr, EP_IntValue) );
        zName = pColExpr->u.zToken;
      }else{
        /* Use the original text of the column expression as its name */
        zName = pEList->a[i].zEName;
        zName = pEList->a[i].zSpan;
      }
    }
    if( zName && !sqlite3IsTrueOrFalse(zName) ){
    if( zName ){
      zName = sqlite3DbStrDup(db, zName);
    }else{
      zName = sqlite3MPrintf(db,"column%d",i+1);
    }

    /* Make sure the column name is unique.  If the name is not unique,
    ** append an integer to the name so that it becomes unique.
    */
    cnt = 0;
    while( zName && sqlite3HashFind(&ht, zName)!=0 ){
      nName = sqlite3Strlen30(zName);
      if( nName>0 ){
        for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){}
        if( zName[j]==':' ) nName = j;
      }
      zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
      if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
    }
    pCol->zName = zName;
    pCol->hName = sqlite3StrIHash(zName);
    sqlite3ColumnPropertiesFromName(0, pCol);
    if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
      sqlite3OomFault(db);
    }
  }
  sqlite3HashClear(&ht);
  if( db->mallocFailed ){
2068
2069
2070
2071
2072
2073
2074
2075

2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110

2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123

2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138



2139
2140
2141
2142
2143

2144
2145
2146
2147
2148
2149
2150
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







-
+
-



















-













-
+












-
+















+
+
+




-
+







**
** This routine requires that all identifiers in the SELECT
** statement be resolved.
*/
void sqlite3SelectAddColumnTypeAndCollation(
  Parse *pParse,        /* Parsing contexts */
  Table *pTab,          /* Add column type information to this table */
  Select *pSelect,      /* SELECT used to determine types and collations */
  Select *pSelect       /* SELECT used to determine types and collations */
  char aff              /* Default affinity for columns */
){
  sqlite3 *db = pParse->db;
  NameContext sNC;
  Column *pCol;
  CollSeq *pColl;
  int i;
  Expr *p;
  struct ExprList_item *a;

  assert( pSelect!=0 );
  assert( (pSelect->selFlags & SF_Resolved)!=0 );
  assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
  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);
      pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
      if( pCol->zName ){
        memcpy(&pCol->zName[n+1], zType, m+1);
        pCol->colFlags |= COLFLAG_HASTYPE;
      }
    }
    if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
    if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
    pColl = sqlite3ExprCollSeq(pParse, p);
    if( pColl && pCol->zColl==0 ){
      pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
    }
  }
  pTab->szTabRow = 1; /* Any non-zero value works */
}

/*
** Given a SELECT statement, generate a Table structure that describes
** the result set of that SELECT.
*/
Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){
Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
  Table *pTab;
  sqlite3 *db = pParse->db;
  u64 savedFlags;

  savedFlags = db->flags;
  db->flags &= ~(u64)SQLITE_FullColNames;
  db->flags |= SQLITE_ShortColNames;
  sqlite3SelectPrep(pParse, pSelect, 0);
  db->flags = savedFlags;
  if( pParse->nErr ) return 0;
  while( pSelect->pPrior ) pSelect = pSelect->pPrior;
  pTab = sqlite3DbMallocZero(db, sizeof(Table) );
  if( pTab==0 ){
    return 0;
  }
  /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
  ** is disabled */
  assert( db->lookaside.bDisable );
  pTab->nTabRef = 1;
  pTab->zName = 0;
  pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
  sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
  sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff);
  sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
  pTab->iPKey = -1;
  if( db->mallocFailed ){
    sqlite3DeleteTable(db, pTab);
    return 0;
  }
  return pTab;
}
2290
2291
2292
2293
2294
2295
2296
2297

2298
2299
2300
2301
2302
2303
2304
2253
2254
2255
2256
2257
2258
2259

2260
2261
2262
2263
2264
2265
2266
2267







-
+







        pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1);
        if( pColl==0 ) pColl = db->pDfltColl;
        pOrderBy->a[i].pExpr =
          sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
      }
      assert( sqlite3KeyInfoIsWriteable(pRet) );
      pRet->aColl[i] = pColl;
      pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags;
      pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder;
    }
  }

  return pRet;
}

#ifndef SQLITE_OMIT_CTE
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2306
2307
2308
2309
2310
2311
2312

2313
2314
2315
2316
2317
2318
2319







-







  Select *p,            /* The recursive SELECT to be coded */
  SelectDest *pDest     /* What to do with query results */
){
  SrcList *pSrc = p->pSrc;      /* The FROM clause of the recursive query */
  int nCol = p->pEList->nExpr;  /* Number of columns in the recursive table */
  Vdbe *v = pParse->pVdbe;      /* The prepared statement under construction */
  Select *pSetup = p->pPrior;   /* The setup query */
  Select *pFirstRec;            /* Left-most recursive term */
  int addrTop;                  /* Top of the loop */
  int addrCont, addrBreak;      /* CONTINUE and BREAK addresses */
  int iCurrent = 0;             /* The Current table */
  int regCurrent;               /* Register holding Current table */
  int iQueue;                   /* The Queue table */
  int iDistinct = 0;            /* To ensure unique results if UNION */
  int eDest = SRT_Fifo;         /* How to write to Queue */
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2381
2382
2383
2384
2385
2386
2387

















2388

2389
2390
2391
2392
2393
2394
2395







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

-







    p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0);
    p->selFlags |= SF_UsesEphemeral;
  }

  /* Detach the ORDER BY clause from the compound SELECT */
  p->pOrderBy = 0;

  /* Figure out how many elements of the compound SELECT are part of the
  ** recursive query.  Make sure no recursive elements use aggregate
  ** functions.  Mark the recursive elements as UNION ALL even if they
  ** are really UNION because the distinctness will be enforced by the
  ** iDistinct table.  pFirstRec is left pointing to the left-most
  ** recursive term of the CTE.
  */
  pFirstRec = p;
  for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){
    if( pFirstRec->selFlags & SF_Aggregate ){
      sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
      goto end_of_recursive_query;
    }
    pFirstRec->op = TK_ALL;
    if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break;
  }

  /* Store the results of the setup-query in Queue. */
  pSetup = pFirstRec->pPrior;
  pSetup->pNext = 0;
  ExplainQueryPlan((pParse, 1, "SETUP"));
  rc = sqlite3Select(pParse, pSetup, &destQueue);
  pSetup->pNext = p;
  if( rc ) goto end_of_recursive_query;

  /* Find the next row in the Queue and output that row */
2470
2471
2472
2473
2474
2475
2476



2477
2478
2479
2480
2481






2482
2483
2484
2485
2486
2487
2488
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423





2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436







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







    VdbeCoverage(v);
  }
  sqlite3VdbeResolveLabel(v, addrCont);

  /* Execute the recursive SELECT taking the single row in Current as
  ** the value for the recursive-table. Store the results in the Queue.
  */
  if( p->selFlags & SF_Aggregate ){
    sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
  }else{
  pFirstRec->pPrior = 0;
  ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
  sqlite3Select(pParse, p, &destQueue);
  assert( pFirstRec->pPrior==0 );
  pFirstRec->pPrior = pSetup;
    p->pPrior = 0;
    ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
    sqlite3Select(pParse, p, &destQueue);
    assert( p->pPrior==0 );
    p->pPrior = pSetup;
  }

  /* Keep running the loop until the Queue is empty */
  sqlite3VdbeGoto(v, addrTop);
  sqlite3VdbeResolveLabel(v, addrBreak);

end_of_recursive_query:
  sqlite3ExprListDelete(pParse->db, p->pOrderBy);
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2472
2473
2474
2475
2476
2477
2478



2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494










2495
2496
2497
2498
2499
2500
2501







-
-
-
















-
-
-
-
-
-
-
-
-
-







  int rc = 0;
  int bShowAll = p->pLimit==0;
  assert( p->selFlags & SF_MultiValue );
  do{
    assert( p->selFlags & SF_Values );
    assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
    assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( p->pWin ) return -1;
#endif
    if( p->pPrior==0 ) break;
    assert( p->pPrior->pNext==p );
    p = p->pPrior;
    nRow += bShowAll;
  }while(1);
  ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow,
                    nRow==1 ? "" : "S"));
  while( p ){
    selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1);
    if( !bShowAll ) break;
    p->nSelectRow = nRow;
    p = p->pNext;
  }
  return rc;
}

/*
** Return true if the SELECT statement which is known to be the recursive
** part of a recursive CTE still has its anchor terms attached.  If the
** anchor terms have already been removed, then return false.
*/
static int hasAnchor(Select *p){
  while( p && (p->selFlags & SF_Recursive)!=0 ){ p = p->pPrior; }
  return p!=0;
}

/*
** This routine is called to process a compound query form from
** two or more separate queries using UNION, UNION ALL, EXCEPT, or
** INTERSECT
**
** "p" points to the right-most of the two queries.  the query on the
** left is p->pPrior.  The left query could also be a compound query
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
2536
2537
2538
2539
2540
2541
2542

2543
2544
2545


2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567

2568

2569
2570
2571
2572
2573
2574
2575
2576
2577

2578
2579
2580
2581
2582
2583
2584
2585







-



-
-
+
+
+
+
+
+
















-
+
-









-
+







  sqlite3 *db;          /* Database connection */

  /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
  ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
  */
  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 );
  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 ){
    assert( p->pEList );
    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
    dest.eDest = SRT_Table;
  }

  /* Special handling for a compound-select that originates as a VALUES clause.
  */
  if( p->selFlags & SF_MultiValue ){
    rc = multiSelectValues(pParse, p, &dest);
    if( rc>=0 ) goto multi_select_end;
    goto multi_select_end;
    rc = SQLITE_OK;
  }

  /* Make sure all SELECTs in the statement have the same number of elements
  ** in their result sets.
  */
  assert( p->pEList && pPrior->pEList );
  assert( p->pEList->nExpr==pPrior->pEList->nExpr );

#ifndef SQLITE_OMIT_CTE
  if( (p->selFlags & SF_Recursive)!=0 && hasAnchor(p) ){
  if( p->selFlags & SF_Recursive ){
    generateWithRecursiveQuery(pParse, p, &dest);
  }else
#endif

  /* Compound SELECTs that have an ORDER BY clause are handled separately.
  */
  if( p->pOrderBy ){
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
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







-
+




















-
-
+
+







        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;
        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( p->pLimit
         && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit)
        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);
        }
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2662
2663
2664
2665
2666
2667
2668

2669
2670
2671
2672
2673
2674
2675







-







          assert( p->pOrderBy==0 );
          addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
          assert( p->addrOpenEphm[0] == -1 );
          p->addrOpenEphm[0] = addr;
          findRightmost(p)->selFlags |= SF_UsesEphemeral;
          assert( p->pEList );
        }
          
  
        /* Code the SELECT statements to our left
        */
        assert( !pPrior->pOrderBy );
        sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
        rc = sqlite3Select(pParse, pPrior, &uniondest);
        if( rc ){
2749
2750
2751
2752
2753
2754
2755
2756

2757
2758


2759

2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776

2777

2778
2779
2780
2781
2782
2783
2784
2685
2686
2687
2688
2689
2690
2691

2692
2693
2694
2695
2696

2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712


2713
2714
2715
2716
2717
2718
2719
2720
2721
2722







-
+


+
+
-
+















-
-
+

+







          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)));
                          selectOpName(p->op)));
        rc = sqlite3Select(pParse, p, &uniondest);
        testcase( rc!=SQLITE_OK );
        /* Query flattening in sqlite3Select() might refill p->pOrderBy.
        ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
        assert( p->pOrderBy==0 );
        sqlite3ExprListDelete(db, p->pOrderBy);
        pDelete = p->pPrior;
        p->pPrior = pPrior;
        p->pOrderBy = 0;
        if( p->op==TK_UNION ){
          p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
        }
        sqlite3ExprDelete(db, p->pLimit);
        p->pLimit = pLimit;
        p->iLimit = 0;
        p->iOffset = 0;
  
        /* Convert the data in the temporary table into whatever form
        ** it is that we currently need.
        */
        assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
        assert( p->pEList || db->mallocFailed );
        if( dest.eDest!=priorOp && db->mallocFailed==0 ){
        if( dest.eDest!=priorOp ){
          int iCont, iBreak, iStart;
          assert( p->pEList );
          iBreak = sqlite3VdbeMakeLabel(pParse);
          iCont = sqlite3VdbeMakeLabel(pParse);
          computeLimitRegisters(pParse, p, iBreak);
          sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
          iStart = sqlite3VdbeCurrentAddr(v);
          selectInnerLoop(pParse, p, unionTab,
                          0, 0, &dest, iCont, iBreak);
2825
2826
2827
2828
2829
2830
2831
2832

2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2763
2764
2765
2766
2767
2768
2769

2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783

2784
2785
2786
2787
2788
2789
2790







-
+













-







        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)));
                          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;
        }
        sqlite3ExprDelete(db, p->pLimit);
        p->pLimit = pLimit;
  
        /* Generate code to take the intersection of the two temporary
        ** tables.
        */
        if( rc ) break;
        assert( p->pEList );
        iBreak = sqlite3VdbeMakeLabel(pParse);
        iCont = sqlite3VdbeMakeLabel(pParse);
        computeLimitRegisters(pParse, p, iBreak);
        sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
        r1 = sqlite3GetTempReg(pParse);
        iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2804
2805
2806
2807
2808
2809
2810

2811
2812
2813
2814
2815
2816
2817







-







  
  #ifndef SQLITE_OMIT_EXPLAIN
    if( p->pNext==0 ){
      ExplainQueryPlanPop(pParse);
    }
  #endif
  }
  if( pParse->nErr ) goto multi_select_end;
  
  /* Compute collating sequences used by 
  ** temporary tables needed to implement the compound select.
  ** Attach the KeyInfo structure to all temporary tables.
  **
  ** This section is run by the right-most SELECT statement only.
  ** SELECT statements to the left always skip this part.  The right-most
2934
2935
2936
2937
2938
2939
2940
2941

2942
2943
2944
2945
2946
2947
2948
2949
2870
2871
2872
2873
2874
2875
2876

2877

2878
2879
2880
2881
2882
2883
2884







-
+
-







** 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",
      " do not have the same number of result columns", selectOpName(p->op));
      sqlite3SelectOpName(p->op));
  }
}

/*
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**
3028
3029
3030
3031
3032
3033
3034
3035

3036
3037
3038
3039
3040


3041
3042
3043
3044
3045
3046
3047
2963
2964
2965
2966
2967
2968
2969

2970

2971
2972


2973
2974
2975
2976
2977
2978
2979
2980
2981







-
+
-


-
-
+
+







                           pIn->iSdst, pIn->nSdst);
      sqlite3ReleaseTempReg(pParse, r1);
      break;
    }

    /* 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
    ** of the scan loop.
    ** 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);
      assert( pIn->nSdst==1 || pParse->nErr>0 );  testcase( pIn->nSdst!=1 );
      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
      /* 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.
3205
3206
3207
3208
3209
3210
3211
3212

3213
3214
3215
3216
3217
3218
3219
3139
3140
3141
3142
3143
3144
3145

3146
3147
3148
3149
3150
3151
3152
3153







-
+







  int addr1;            /* Jump instructions that get retargetted */
  int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
  KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
  KeyInfo *pKeyMerge;   /* Comparison information for merging rows */
  sqlite3 *db;          /* Database connection */
  ExprList *pOrderBy;   /* The ORDER BY clause */
  int nOrderBy;         /* Number of terms in the ORDER BY clause */
  u32 *aPermute;        /* Mapping from ORDER BY terms to result set columns */
  int *aPermute;        /* Mapping from ORDER BY terms to result set columns */

  assert( p->pOrderBy!=0 );
  assert( pKeyDup==0 ); /* "Managed" code needs this.  Ticket #3382. */
  db = pParse->db;
  v = pParse->pVdbe;
  assert( v!=0 );       /* Already thrown the error if VDBE alloc failed */
  labelEnd = sqlite3VdbeMakeLabel(pParse);
3254
3255
3256
3257
3258
3259
3260
3261

3262
3263
3264
3265
3266
3267
3268
3188
3189
3190
3191
3192
3193
3194

3195
3196
3197
3198
3199
3200
3201
3202







-
+







  /* Compute the comparison permutation and keyinfo that is used with
  ** the permutation used to determine if the next
  ** row of results comes from selectA or selectB.  Also add explicit
  ** collations to the ORDER BY clause terms so that when the subqueries
  ** to the right and the left are evaluated, they use the correct
  ** collation.
  */
  aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1));
  aPermute = sqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1));
  if( aPermute ){
    struct ExprList_item *pItem;
    aPermute[0] = nOrderBy;
    for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
      assert( pItem->u.x.iOrderByCol>0 );
      assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
      aPermute[i] = pItem->u.x.iOrderByCol - 1;
3290
3291
3292
3293
3294
3295
3296
3297

3298
3299
3300
3301
3302
3303
3304
3224
3225
3226
3227
3228
3229
3230

3231
3232
3233
3234
3235
3236
3237
3238







-
+







    pParse->nMem += nExpr+1;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
    pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1);
    if( pKeyDup ){
      assert( sqlite3KeyInfoIsWriteable(pKeyDup) );
      for(i=0; i<nExpr; i++){
        pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
        pKeyDup->aSortFlags[i] = 0;
        pKeyDup->aSortOrder[i] = 0;
      }
    }
  }
 
  /* Separate the left and the right query from one another
  */
  p->pPrior = 0;
3325
3326
3327
3328
3329
3330
3331
3332

3333
3334
3335
3336
3337
3338
3339
3259
3260
3261
3262
3263
3264
3265

3266
3267
3268
3269
3270
3271
3272
3273







-
+







  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)));
  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"));
3509
3510
3511
3512
3513
3514
3515
3516

3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546


3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
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
3443
3444
3445
3446
3447
3448
3449

3450



3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467

3468
3469
3470
3471
3472
3473
3474
3475

3476
3477
3478
3479
3480












3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493








3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512

3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531



















































































































3532
3533
3534
3535
3536
3537
3538







-
+
-
-
-

















-








-
+
+



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













-
-
-
-
-
-
-
-



















-
+


















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







){
  if( pExpr==0 ) return 0;
  if( ExprHasProperty(pExpr, EP_FromJoin)
   && pExpr->iRightJoinTable==pSubst->iTable
  ){
    pExpr->iRightJoinTable = pSubst->iNewTable;
  }
  if( pExpr->op==TK_COLUMN
  if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
   && pExpr->iTable==pSubst->iTable
   && !ExprHasProperty(pExpr, EP_FixedCol)
  ){
    if( pExpr->iColumn<0 ){
      pExpr->op = TK_NULL;
    }else{
      Expr *pNew;
      Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
      Expr ifNullRow;
      assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
      assert( pExpr->pRight==0 );
      if( sqlite3ExprIsVector(pCopy) ){
        sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
      }else{
        sqlite3 *db = pSubst->pParse->db;
        if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
          memset(&ifNullRow, 0, sizeof(ifNullRow));
          ifNullRow.op = TK_IF_NULL_ROW;
          ifNullRow.pLeft = pCopy;
          ifNullRow.iTable = pSubst->iNewTable;
          ifNullRow.flags = EP_IfNullRow;
          pCopy = &ifNullRow;
        }
        testcase( ExprHasProperty(pCopy, EP_Subquery) );
        pNew = sqlite3ExprDup(db, pCopy, 0);
        if( pNew && pSubst->isLeftJoin ){
          ExprSetProperty(pNew, EP_CanBeNull);
        }
        if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){
          sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
          pNew->iRightJoinTable = pExpr->iRightJoinTable;
          ExprSetProperty(pNew, EP_FromJoin);
        }
        sqlite3ExprDelete(db, pExpr);
        pExpr = pNew;

        /* Ensure that the expression now has an implicit collation sequence,
        ** just as it did when it was a column of a view or sub-query. */
        if( pExpr ){
          if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){
            CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
            pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, 
                (pColl ? pColl->zName : "BINARY")
            );
          }
          ExprClearProperty(pExpr, EP_Collate);
        }
      }
    }
  }else{
    if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
      pExpr->iTable = pSubst->iNewTable;
    }
    pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
    pExpr->pRight = substExpr(pSubst, pExpr->pRight);
    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
      substSelect(pSubst, pExpr->x.pSelect, 1);
    }else{
      substExprList(pSubst, pExpr->x.pList);
    }
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( ExprHasProperty(pExpr, EP_WinFunc) ){
      Window *pWin = pExpr->y.pWin;
      pWin->pFilter = substExpr(pSubst, pWin->pFilter);
      substExprList(pSubst, pWin->pPartition);
      substExprList(pSubst, pWin->pOrderBy);
    }
#endif
  }
  return pExpr;
}
static void substExprList(
  SubstContext *pSubst, /* Description of the substitution */
  ExprList *pList       /* List to scan and in which to make substitutes */
){
  int i;
  if( pList==0 ) return;
  for(i=0; i<pList->nExpr; i++){
    pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr);
  }
}
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;
  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);
    p->pWhere = substExpr(pSubst, p->pWhere);
    pSrc = p->pSrc;
    assert( pSrc!=0 );
    for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
      substSelect(pSubst, pItem->pSelect, 1);
      if( pItem->fg.isTabFunc ){
        substExprList(pSubst, pItem->u1.pFuncArg);
      }
    }
  }while( doPrior && (p = p->pPrior)!=0 );
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** 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.
**
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3572
3573
3574
3575
3576
3577
3578

3579
3580
3581
3582
3583
3584
3585







-







**             from 2015-02-09.)
**
**   (3)  If the subquery is the right operand of a LEFT JOIN then
**        (3a) the subquery may not be a join and
**        (3b) the FROM clause of the subquery may not contain a virtual
**             table and
**        (3c) the outer query may not be an aggregate.
**        (3d) the outer query may not be DISTINCT.
**
**   (4)  The subquery can not be DISTINCT.
**
**  (**)  At one point restrictions (4) and (5) defined a subset of DISTINCT
**        sub-queries that were excluded from this optimization. Restriction 
**        (4) has since been expanded to exclude all DISTINCT subqueries.
**
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
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







-
+
-
-
+















-
-
+
+















+
-
-
+
+







**  (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
**              (17d2) DISTINCT, or
**        (17e) the subquery may not contain window functions, and
**        (17f) the subquery must not be the RHS of a LEFT JOIN.
**              (17d3) a 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.
**        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
**  (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
**        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
3903
3904
3905
3906
3907
3908
3909
3910

3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3698
3699
3700
3701
3702
3703
3704

3705
3706


3707
3708
3709
3710
3711
3712
3713







-
+

-
-







  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 */
  struct SrcList_item *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;
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984

3985
3986

3987
3988
3989
3990
3991
3992
3993
3768
3769
3770
3771
3772
3773
3774



3775


3776
3777
3778
3779
3780
3781
3782
3783







-
-
-
+
-
-
+







  ** aggregates are processed - there is no mechanism to determine if
  ** the LEFT JOIN table should be all-NULL.
  **
  ** See also tickets #306, #350, and #3300.
  */
  if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
    isLeftJoin = 1;
    if( pSubSrc->nSrc>1                   /* (3a) */
     || isAgg                             /* (3b) */
     || IsVirtual(pSubSrc->a[0].pTab)     /* (3c) */
    if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){
     || (p->selFlags & SF_Distinct)!=0    /* (3d) */
    ){
      /*  (3a)             (3c)     (3b) */
      return 0;
    }
  }
#ifdef SQLITE_EXTRA_IFNULLROW
  else if( iFrom>0 && !isAgg ){
    /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
    ** every reference to any result column from subquery in a join, even
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
3792
3793
3794
3795
3796
3797
3798


3799
3800
3801
3802
3803
3804
3805

3806
3807
3808
3809



3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822




3823
3824
3825
3826
3827


3828
3829



3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842











3843
3844
3845
3846
3847
3848
3849







-
-
+
+





-




-
-
-













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











-
-
-
-
-
-
-
-
-
-
-







  ** 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) */
    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->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;

  }

  /* 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
    if( pSrc->nSrc>1 ){
      if( pParse->nSelect>500 ) return 0;
  ** subquery is a join, then the flattening has already been stopped by
  ** restriction (17d3)
      aCsrMap = sqlite3DbMallocZero(db, pParse->nTab*sizeof(int));
    }
  }
  */
  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;

  /* 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> 
  **
  ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block
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
4190
4191
3874
3875
3876
3877
3878
3879
3880


3881
3882
3883
3884
3885
3886
3887
3888
3889

3890
3891
3892




3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905





3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
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







-
-

+





+

-



-
-
-
-







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












-
-
-
-
+
+



















-



-




+
-
-
+
+
+
+
+
+
+

-
+







  ** 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->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;
    pSubitem->pTab = pItemTab;
    if( pNew==0 ){
      p->pPrior = pPrior;
    }else{
      pNew->selId = ++pParse->nSelect;
      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));
    }
    if( db->mallocFailed ) return 1;
  }

  /* Begin flattening the iFrom-th entry of the FROM clause 
  ** in the outer query.
  */
    assert( pSubitem->pSelect==0 );
  }
  sqlite3DbFree(db, aCsrMap);
  if( db->mallocFailed ){
    pSubitem->pSelect = pSub1;
  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;
    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 );
      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.
  */
  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( pSrc ){
    if( pParent==p ){
      jointype = pSubitem->fg.jointype;     /* First time through the loop */
      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:
    **
4223
4224
4225
4226
4227
4228
4229
4230

4231
4232
4233
4234
4235
4236
4237
4006
4007
4008
4009
4010
4011
4012

4013
4014
4015
4016
4017
4018
4019
4020







-
+







    **   SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
    **   \                     \_____________ subquery __________/          /
    **    \_____________________ outer query ______________________________/
    **
    ** We look at every expression in the outer query and every place we see
    ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
    */
    if( pSub->pOrderBy && (pParent->selFlags & SF_NoopOrderBy)==0 ){
    if( pSub->pOrderBy ){
      /* At this point, any non-zero iOrderByCol values indicate that the
      ** ORDER BY column expression is identical to the iOrderByCol'th
      ** expression returned by SELECT statement pSub. Since these values
      ** do not necessarily correspond to columns in SELECT statement pParent,
      ** zero them before transfering the ORDER BY clause.
      **
      ** Not doing this may cause an error if a subsequent call to this
4245
4246
4247
4248
4249
4250
4251
4252

4253
4254
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
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
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







-
+

-
-
-
-
-
+
-
-










-
-
-
+
+
+
+
-











-
-
-
-
-
-





-
-







      assert( pParent->pOrderBy==0 );
      pParent->pOrderBy = pOrderBy;
      pSub->pOrderBy = 0;
    }
    pWhere = pSub->pWhere;
    pSub->pWhere = 0;
    if( isLeftJoin>0 ){
      sqlite3SetJoinExpr(pWhere, iNewParent);
      setJoinExpr(pWhere, iNewParent);
    }
    if( pWhere ){
      if( pParent->pWhere ){
        pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
      }else{
        pParent->pWhere = pWhere;
    pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
      }
    }
    if( db->mallocFailed==0 ){
      SubstContext x;
      x.pParse = pParse;
      x.iTable = iParent;
      x.iNewTable = iNewParent;
      x.isLeftJoin = isLeftJoin;
      x.pEList = pSub->pEList;
      substSelect(&x, pParent, 0);
    }
  
    /* The flattened query is a compound if either the inner or the
    ** outer query is a compound. */
    pParent->selFlags |= pSub->selFlags & SF_Compound;
    /* The flattened query is distinct if either the inner or the
    ** outer query is distinct. 
    */
    pParent->selFlags |= pSub->selFlags & SF_Distinct;
    assert( (pSub->selFlags & SF_Distinct)==0 ); /* restriction (17b) */
  
    /*
    ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
    **
    ** One is tempted to try to add a and b to combine the limits.  But this
    ** does not work if either limit is negative.
    */
    if( pSub->pLimit ){
      pParent->pLimit = pSub->pLimit;
      pSub->pLimit = 0;
    }

    /* Recompute the SrcList_item.colUsed masks for the flattened
    ** tables. */
    for(i=0; i<nSubSrc; i++){
      recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]);
    }
  }

  /* Finially, delete what is left of the subquery and return
  ** 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);
  }
4319
4320
4321
4322
4323
4324
4325
4326

4327
4328
4329
4330
4331
4332
4333
4334
4335



4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354




4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365

4366
4367
4368
4369
4370
4371
4372
4088
4089
4090
4091
4092
4093
4094

4095




4096
4097



4098
4099
4100

4101
4102
4103







4104
4105
4106
4107




4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130







-
+
-
-
-
-


-
-
-
+
+
+
-



-
-
-
-
-
-
-




-
-
-
-
+
+
+
+











+







  int nConst;      /* Number for COLUMN=CONSTANT terms */
  int nChng;       /* Number of times a constant is propagated */
  Expr **apExpr;   /* [i*2] is COLUMN and [i*2+1] is VALUE */
};

/*
** Add a new entry to the pConst object.  Except, do not add duplicate
** pColumn entires.  Also, do not add if doing so would not be appropriate.
** pColumn entires.
**
** The caller guarantees the pColumn is a column and pValue is a constant.
** This routine has to do some additional checks before completing the
** insert.
*/
static void constInsert(
  WhereConst *pConst,  /* The WhereConst into which we are inserting */
  Expr *pColumn,       /* The COLUMN part of the constraint */
  Expr *pValue,        /* The VALUE part of the constraint */
  WhereConst *pConst,      /* The WhereConst into which we are inserting */
  Expr *pColumn,           /* The COLUMN part of the constraint */
  Expr *pValue             /* The VALUE part of the constraint */
  Expr *pExpr          /* Overall expression: COLUMN=VALUE or VALUE=COLUMN */
){
  int i;
  assert( pColumn->op==TK_COLUMN );
  assert( sqlite3ExprIsConstant(pValue) );

  if( ExprHasProperty(pColumn, EP_FixedCol) ) return;
  if( sqlite3ExprAffinity(pValue)!=0 ) return;
  if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){
    return;
  }

  /* 2018-10-25 ticket [cf5ed20f]
  ** Make sure the same pColumn is not inserted more than once */
  for(i=0; i<pConst->nConst; i++){
    const Expr *pE2 = pConst->apExpr[i*2];
    assert( pE2->op==TK_COLUMN );
    if( pE2->iTable==pColumn->iTable
     && pE2->iColumn==pColumn->iColumn
    const Expr *pExpr = pConst->apExpr[i*2];
    assert( pExpr->op==TK_COLUMN );
    if( pExpr->iTable==pColumn->iTable
     && pExpr->iColumn==pColumn->iColumn
    ){
      return;  /* Already present.  Return without doing anything. */
    }
  }

  pConst->nConst++;
  pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
                         pConst->nConst*2*sizeof(Expr*));
  if( pConst->apExpr==0 ){
    pConst->nConst = 0;
  }else{
    if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft;
    pConst->apExpr[pConst->nConst*2-2] = pColumn;
    pConst->apExpr[pConst->nConst*2-1] = pValue;
  }
}

/*
** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395













4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409

4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
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







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













-
+
-
-
-
-







    return;
  }
  if( pExpr->op!=TK_EQ ) return;
  pRight = pExpr->pRight;
  pLeft = pExpr->pLeft;
  assert( pRight!=0 );
  assert( pLeft!=0 );
  if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){
    constInsert(pConst,pRight,pLeft,pExpr);
  }
  if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){
    constInsert(pConst,pLeft,pRight,pExpr);
  if( pRight->op==TK_COLUMN
   && !ExprHasProperty(pRight, EP_FixedCol)
   && sqlite3ExprIsConstant(pLeft)
   && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight))
  ){
    constInsert(pConst, pRight, pLeft);
  }else
  if( pLeft->op==TK_COLUMN
   && !ExprHasProperty(pLeft, EP_FixedCol)
   && sqlite3ExprIsConstant(pRight)
   && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight))
  ){
    constInsert(pConst, pLeft, pRight);
  }
}

/*
** This is a Walker expression callback.  pExpr is a candidate expression
** to be replaced by a value.  If pExpr is equivalent to one of the
** columns named in pWalker->u.pConst, then overwrite it with its
** corresponding value.
*/
static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
  int i;
  WhereConst *pConst;
  if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
  if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){
  if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue;
    testcase( ExprHasProperty(pExpr, EP_FixedCol) );
    testcase( ExprHasProperty(pExpr, EP_FromJoin) );
    return WRC_Continue;
  }
  pConst = pWalker->u.pConst;
  for(i=0; i<pConst->nConst; i++){
    Expr *pColumn = pConst->apExpr[i*2];
    if( pColumn==pExpr ) continue;
    if( pColumn->iTable!=pExpr->iTable ) continue;
    if( pColumn->iColumn!=pExpr->iColumn ) continue;
    /* A match is found.  Add the EP_FixedCol property */
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437




4438
4439
4440
4441
4442
4443
4444
4190
4191
4192
4193
4194
4195
4196



4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207







-
-
-
+
+
+
+







  return WRC_Prune;
}

/*
** The WHERE-clause constant propagation optimization.
**
** If the WHERE clause contains terms of the form COLUMN=CONSTANT or
** CONSTANT=COLUMN that are top-level AND-connected terms that are not
** part of a ON clause from a LEFT JOIN, then throughout the query
** replace all other occurrences of COLUMN with CONSTANT.
** CONSTANT=COLUMN that must be tree (in other words, if the terms top-level
** AND-connected terms that are not part of a ON clause from a LEFT JOIN)
** then throughout the query replace all other occurrences of COLUMN
** with CONSTANT within the WHERE clause.
**
** For example, the query:
**
**      SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b
**
** Is transformed into
**
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4252
4253
4254
4255
4256
4257
4258





























4259
4260
4261
4262
4263
4264
4265







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







      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;
**
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
4619
4620
4621
4299
4300
4301
4302
4303
4304
4305


4306
4307












4308




4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322

4323
4324
4325




4326




4327
4328
4329
4330
4331
4332
4333







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














-
+


-
-
-
-
+
-
-
-
-







**           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 
**   (6) The inner query features one or more window-functions (since 
**       changes to the WHERE clause of the inner query could change the 
**       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.
**       window over which window functions are 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;
  if( pSubq->selFlags & SF_Recursive ) return 0;  /* restriction (2) */

#ifndef SQLITE_OMIT_WINDOWFUNC
  if( pSubq->pPrior ){
    Select *pSel;
    for(pSel=pSubq; pSel; pSel=pSel->pPrior){
      if( pSel->pWin ) return 0;    /* restriction (6b) */
  if( pSubq->pWin ) return 0;    /* restriction (6) */
    }
  }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.
  */
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
4673
4674
4675
4676
4677
4678
4354
4355
4356
4357
4358
4359
4360

4361
4362
4363
4364
4365
4366
4367
4368
4369
4370








4371

4372
4373

4374
4375
4376
4377
4378
4379
4380
4381







-










-
-
-
-
-
-
-
-

-
+

-
+







    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);
        pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
      }else{
        pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
        pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
      }
      pSubq = pSubq->pPrior;
    }
  }
  return nChng;
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
4694
4695
4696
4697
4698
4699
4700
4701

4702
4703
4704
4705
4706

4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717

4718
4719
4720
4721

4722
4723
4724
4725
4726
4727

4728
4729
4730
4731
4732
4733
4734
4397
4398
4399
4400
4401
4402
4403

4404
4405
4406
4407


4408






4409
4410
4411


4412

4413
4414

4415
4416
4417
4418
4419
4420

4421
4422
4423
4424
4425
4426
4427
4428







-
+



-
-
+
-
-
-
-
-
-



-
-
+
-


-
+





-
+







** analysis.
*/
static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
  int eRet = WHERE_ORDERBY_NORMAL;      /* Return value */
  ExprList *pEList = pFunc->x.pList;    /* Arguments to agg function */
  const char *zFunc;                    /* Name of aggregate function pFunc */
  ExprList *pOrderBy;
  u8 sortFlags = 0;
  u8 sortOrder;

  assert( *ppMinMax==0 );
  assert( pFunc->op==TK_AGG_FUNCTION );
  assert( !IsWindowFunc(pFunc) );
  if( pEList==0 
  if( pEList==0 || pEList->nExpr!=1 ) return eRet;
   || 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;
    sortOrder = SQLITE_SO_ASC;
    }
  }else if( sqlite3StrICmp(zFunc, "max")==0 ){
    eRet = WHERE_ORDERBY_MAX;
    sortFlags = KEYINFO_ORDER_DESC;
    sortOrder = SQLITE_SO_DESC;
  }else{
    return eRet;
  }
  *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
  assert( pOrderBy!=0 || db->mallocFailed );
  if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags;
  if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder;
  return eRet;
}

/*
** The select statement passed as the first argument is an aggregate query.
** The second argument is the associated aggregate-info object. This 
** function tests if the SELECT is of the form:
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
4448
4449
4450
4451
4452
4453
4454

4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466




4467
4468
4469
4470
4471













4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484

4485
4486
4487
4488
4489
4490
4491







-
+











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


-







  pExpr = p->pEList->a[0].pExpr;
  assert( pTab && !pTab->pSelect && pExpr );

  if( IsVirtual(pTab) ) return 0;
  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
  if( NEVER(pAggInfo->nFunc==0) ) return 0;
  if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
  if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
  if( pExpr->flags&EP_Distinct ) return 0;

  return pTab;
}

/*
** 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;
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;
  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;
    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:
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4514
4515
4516
4517
4518
4519
4520








4521
4522
4523
4524
4525
4526
4527







-
-
-
-
-
-
-
-







  Token dummy;

  if( p->pPrior==0 ) return WRC_Continue;
  if( p->pOrderBy==0 ) return WRC_Continue;
  for(pX=p; pX && (pX->op==TK_ALL || pX->op==TK_SELECT); pX=pX->pPrior){}
  if( pX==0 ) return WRC_Continue;
  a = p->pOrderBy->a;
#ifndef SQLITE_OMIT_WINDOWFUNC
  /* If iOrderByCol is already non-zero, then it has already been matched
  ** to a result column of the SELECT statement. This occurs when the
  ** SELECT is rewritten for window-functions processing and then passed
  ** to sqlite3SelectPrep() and similar a second time. The rewriting done
  ** by this function is not required in this case. */
  if( a[0].u.x.iOrderByCol ) return WRC_Continue;
#endif
  for(i=p->pOrderBy->nExpr-1; i>=0; i--){
    if( a[i].pExpr->flags & EP_Collate ) break;
  }
  if( i<0 ) return WRC_Continue;

  /* If we reach this point, that means the transformation is required. */

4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879

4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900

4901
4902
4903
4904



4905
4906
4907
4908
4909
4910
4911
4912







4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929

4930
4931
4932
4933
4934

4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946


4947
4948

4949
4950
4951




4952
4953
4954
4955



4956
4957

4958
4959
4960


4961


4962
4963


4964
4965
4966
4967
4968
4969

4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994

4995
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
4539
4540
4541
4542
4543
4544
4545



4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559

4560
4561
4562
4563
4564
4565
4566
4567
4568
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
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

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
4697
4698
4699
4700
4701
4702
4703


4704




4705


4706
4707
4708
4709


4710
4711








4712
4713
4714
4715




4716

4717



4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728

4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744

4745

4746
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







-
-
-














-
+




















-
+


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

















+




-
+
-
-
-
-
-





-
-
+
+
-
-
+

-
-
+
+
+
+

-
-
-
+
+
+

-
+
-
-
-
+
+

+
+
-
-
+
+


-
-
-
-
+
-
-
-
-
-


-




-


-
-







-
+

-
+


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






-
+

-
-
-
-
-
-
+
-

-
+

-
+

-
+
-

-
+



-
+

+

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




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

-
+
-
-
-











-
+















-

-
+
+

















-
+















-
+


















-
+







  p->pWhere = 0;
  pNew->pGroupBy = 0;
  pNew->pHaving = 0;
  pNew->pOrderBy = 0;
  p->pPrior = 0;
  p->pNext = 0;
  p->pWith = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
  p->pWinDefn = 0;
#endif
  p->selFlags &= ~SF_Compound;
  assert( (p->selFlags & SF_Converted)==0 );
  p->selFlags |= SF_Converted;
  assert( pNew->pPrior!=0 );
  pNew->pPrior->pNext = pNew;
  pNew->pLimit = 0;
  return WRC_Continue;
}

/*
** 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){
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 */
  SrcItem *pItem,                 /* FROM clause element to resolve */
  struct SrcList_item *pItem,     /* FROM clause element to resolve */
  With **ppContext                /* OUT: WITH clause return value belongs to */
){
  const char *zName = pItem->zName;
  With *p;
  const char *zName;
  if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){
    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];
    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 ){
    if( bFree ) pParse->pWithToFree = pWith;
      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
** a WITH clause on the stack currently maintained by the parser. And,
** if currently processing a CTE expression, if it is a recursive
** CTE expression, through routine checks to see if the reference is
** a recursive reference to the CTE.
** reference to the current CTE.
**
** If pFrom matches a CTE according to either of these two above, pFrom->pTab
** and other fields are populated accordingly.
** 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.
**
** Return 0 if no match is found. 
** Return 1 if a match is found.
** Return 2 if an error condition is detected.
** 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 resolveFromTermToCte(
static int withExpand(
  Parse *pParse,                  /* The parsing context */
  Walker *pWalker,                /* Current tree walker */
  SrcItem *pFrom                  /* The FROM clause term to check */
  Walker *pWalker, 
  struct SrcList_item *pFrom
){
  Parse *pParse = pWalker->pParse;
  sqlite3 *db = pParse->db;
  Cte *pCte;               /* Matched CTE (or NULL if no match) */
  With *pWith;             /* The matching WITH */
  struct Cte *pCte;               /* Matched CTE (or NULL if no match) */
  With *pWith;                    /* WITH clause that pCte belongs to */

  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;
      return SQLITE_ERROR;
    }
    if( cannotBeFunction(pParse, pFrom) ) return 2;
    if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR;

    assert( pFrom->pTab==0 );
    pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ) return 2;
    pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ) return WRC_Abort;
    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;
    if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
    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;
    pSel = pFrom->pSelect;
    bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
    while( bMayRecursive && pRecTerm->op==pSel->op ){
    if( bMayRecursive ){
      int i;
      SrcList *pSrc = pRecTerm->pSrc;
      SrcList *pSrc = pFrom->pSelect->pSrc;
      assert( pRecTerm->pPrior!=0 );
      for(i=0; i<pSrc->nSrc; i++){
        SrcItem *pItem = &pSrc->a[i];
        struct SrcList_item *pItem = &pSrc->a[i];
        if( pItem->zDatabase==0 
         && pItem->zName!=0 
         && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
        ){
          ){
          pItem->pTab = pTab;
          pItem->fg.isRecursive = 1;
          pTab->nTabRef++;
          pItem->fg.isRecursive = 1;
          if( pRecTerm->selFlags & SF_Recursive ){
            sqlite3ErrorMsg(pParse,
               "multiple references to recursive table: %s", pCte->zName
            );
            return 2;
          }
          pSel->selFlags |= SF_Recursive;
        }
      }
    }

    /* Only one recursive reference is permitted. */ 
    if( pTab->nTabRef>2 ){
      sqlite3ErrorMsg(
          pParse, "multiple references to recursive table: %s", pCte->zName
      );
      return SQLITE_ERROR;
    }
          pRecTerm->selFlags |= SF_Recursive;
          if( iRecTab<0 ) iRecTab = pParse->nTab++;
    assert( pTab->nTabRef==1 || 
          pItem->iCursor = iRecTab;
        }
      }
      if( (pRecTerm->selFlags & SF_Recursive)==0 ) break;
            ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
      pRecTerm = pRecTerm->pPrior;
    }

    pCte->zCteErr = "circular reference: %s";
    pSavedWith = pParse->pWith;
    pParse->pWith = pWith;
    if( pSel->selFlags & SF_Recursive ){
      int rc;
    if( bMayRecursive ){
      Select *pPrior = pSel->pPrior;
      assert( pRecTerm!=0 );
      assert( (pRecTerm->selFlags & SF_Recursive)==0 );
      assert( pRecTerm->pNext!=0 );
      assert( (pRecTerm->pNext->selFlags & SF_Recursive)!=0 );
      assert( pRecTerm->pWith==0 );
      pRecTerm->pWith = pSel->pWith;
      rc = sqlite3WalkSelect(pWalker, pRecTerm);
      pRecTerm->pWith = 0;
      assert( pPrior->pWith==0 );
      pPrior->pWith = pSel->pWith;
      sqlite3WalkSelect(pWalker, pPrior);
      pPrior->pWith = 0;
      if( rc ){
        pParse->pWith = pSavedWith;
        return 2;
      }
    }else{
      if( sqlite3WalkSelect(pWalker, pSel) ){
      sqlite3WalkSelect(pWalker, pSel);
        pParse->pWith = pSavedWith;
        return 2;
      }
    }
    pParse->pWith = pWith;

    for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
    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;
        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 1;  /* Success */
  }
  return 0;  /* No match */

  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.
**
** This function is used as the xSelectCallback2() callback by
** sqlite3SelectExpand() when walking a SELECT tree to resolve table
** names and other FROM clause elements. 
*/
static void selectPopWith(Walker *pWalker, Select *p){
  Parse *pParse = pWalker->pParse;
  if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){
    With *pWith = findRightmost(p)->pWith;
    if( pWith!=0 ){
      assert( pParse->pWith==pWith || pParse->nErr );
      assert( pParse->pWith==pWith );
      pParse->pWith = pWith->pOuter;
    }
  }
}
#else
#define selectPopWith 0
#endif

/*
** 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){
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;
  if( pFrom->zAlias ){
    pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
  }else{
    pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId);
  }
  while( pSel->pPrior ){ pSel = pSel->pPrior; }
  sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
  pTab->iPKey = -1;
  pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
  pTab->tabFlags |= TF_Ephemeral;

  return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
  return SQLITE_OK;
}

/*
** This routine is a Walker callback for "expanding" a SELECT statement.
** "Expanding" means to do the following:
**
**    (1)  Make sure VDBE cursor numbers have been assigned to every
5185
5186
5187
5188
5189
5190
5191
5192

5193
5194
5195

5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230






5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261

5262
5263
5264
5265
5266
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
4822
4823
4824
4825
4826
4827
4828

4829
4830
4831

4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845




4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861


4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876






4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891

4892
4893
4894

4895
4896

















4897
4898
4899

4900

4901
4902
4903
4904
4905
4906

4907
4908
4909
4910
4911
4912
4913

4914
4915
4916
4917
4918
4919
4920
4921







-
+


-
+













-
-
-
-
















-
-
+
+
+
+
+
+









-
-
-
-
-
-















-
+


-


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



-

-






-
+






-
+







**         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;
  int i, j, k;
  SrcList *pTabList;
  ExprList *pEList;
  SrcItem *pFrom;
  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  ){
    return WRC_Abort;
  }
  assert( p->pSrc!=0 );
  if( (selFlags & SF_Expanded)!=0 ){
    return WRC_Prune;
  }
  if( pWalker->eCode ){
    /* Renumber selId because it has been copied from a view */
    p->selId = ++pParse->nSelect;
  }
  pTabList = p->pSrc;
  pEList = p->pEList;
  sqlite3WithPush(pParse, p->pWith, 0);

  /* Make sure cursor numbers have been assigned to all entries in
  ** the FROM clause of the SELECT statement.
  */
  sqlite3SrcListAssignCursors(pParse, pTabList);

  /* Look up every table named in the FROM clause of the select.  If
  ** an entry of the FROM clause is a subquery instead of a table or view,
  ** 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->fg.isRecursive ) continue;
    assert( pFrom->pTab==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
#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",
           pTab->zName);
        pFrom->pTab = 0;
        return WRC_Abort;
      }
      pTab->nTabRef++;
      if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
        return WRC_Abort;
      }
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
#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)
         && pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0)
        ){
          sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"",
                                  pTab->zName);
        }
#endif
        pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
        nCol = pTab->nCol;
        pTab->nCol = -1;
        pWalker->eCode = 1;  /* Turn on Select.selId renumbering */
        sqlite3WalkSelect(pWalker, pFrom->pSelect);
        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) ){
    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) ){
  if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){
    return WRC_Abort;
  }

  /* For every "*" that occurs in the column list, insert the names of
  ** all columns in all tables.  And for every TABLE.* insert the names
  ** of all columns in TABLE.  The parser inserted a special expression
  ** with the TK_ASTERISK operator for each "*" that it found in the column
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352




5353
5354
5355
5356
5357
5358
5359
4954
4955
4956
4957
4958
4959
4960



4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971







-
-
-
+
+
+
+







      if( pE->op!=TK_ASTERISK
       && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK)
      ){
        /* This particular expression does not need to be expanded.
        */
        pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
        if( pNew ){
          pNew->a[pNew->nExpr-1].zEName = a[k].zEName;
          pNew->a[pNew->nExpr-1].eEName = a[k].eEName;
          a[k].zEName = 0;
          pNew->a[pNew->nExpr-1].zName = a[k].zName;
          pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan;
          a[k].zName = 0;
          a[k].zSpan = 0;
        }
        a[k].pExpr = 0;
      }else{
        /* This expression is a "*" or a "TABLE.*" and needs to be
        ** expanded. */
        int tableSeen = 0;      /* Set to 1 when TABLE matches */
        char *zTName = 0;       /* text of name of TABLE */
5384
5385
5386
5387
5388
5389
5390
5391

5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409

5410
5411
5412
5413
5414
5415
5416
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







-
+

















-
+







            char *zName = pTab->aCol[j].zName;
            char *zColname;  /* The computed column name */
            char *zToFree;   /* Malloced string that needs to be freed */
            Token sColname;  /* Computed column name as a token */

            assert( zName );
            if( zTName && pSub
             && sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0
             && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0
            ){
              continue;
            }

            /* If a column is marked as 'hidden', omit it from the expanded
            ** result-set list unless the SELECT has the SF_IncludeHidden
            ** bit set.
            */
            if( (p->selFlags & SF_IncludeHidden)==0
             && IsHiddenColumn(&pTab->aCol[j]) 
            ){
              continue;
            }
            tableSeen = 1;

            if( i>0 && zTName==0 ){
              if( (pFrom->fg.jointype & JT_NATURAL)!=0
                && tableAndColumnIndex(pTabList, i, zName, 0, 0, 1)
                && tableAndColumnIndex(pTabList, i, zName, 0, 0)
              ){
                /* In a NATURAL join, omit the join columns from the 
                ** table to the right of the join */
                continue;
              }
              if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){
                /* In a join with a USING clause, omit columns in the
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
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







-
+

-

-
-
+
+

-
+

-
+

-
+







              }
            }else{
              pExpr = pRight;
            }
            pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
            sqlite3TokenInit(&sColname, zColname);
            sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
            if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
            if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
              struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
              sqlite3DbFree(db, pX->zEName);
              if( pSub ){
                pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName);
                testcase( pX->zEName==0 );
                pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan);
                testcase( pX->zSpan==0 );
              }else{
                pX->zEName = sqlite3MPrintf(db, "%s.%s.%s",
                pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s",
                                           zSchemaName, zTabName, zColname);
                testcase( pX->zEName==0 );
                testcase( pX->zSpan==0 );
              }
              pX->eEName = ENAME_TAB;
              pX->bSpanIsTab = 1;
            }
            sqlite3DbFree(db, zToFree);
          }
        }
        if( !tableSeen ){
          if( zTName ){
            sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
5474
5475
5476
5477
5478
5479
5480























5481
5482
5483
5484
5485
5486
5487
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







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







    }
    if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
      p->selFlags |= SF_ComplexResult;
    }
  }
  return WRC_Continue;
}

/*
** No-op routine for the parse-tree walker.
**
** When this routine is the Walker.xExprCallback then expression trees
** are walked without any actions being taken at each node.  Presumably,
** when this routine is used for Walker.xExprCallback then 
** Walker.xSelectCallback is set to do something useful for every 
** subquery in the parser tree.
*/
int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  return WRC_Continue;
}

/*
** No-op routine for the parse-tree walker for SELECT statements.
** subquery in the parser tree.
*/
int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  return WRC_Continue;
}

#if SQLITE_DEBUG
/*
** Always assert.  This xSelectCallback2 implementation proves that the
** xSelectCallback2 is never invoked.
*/
void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5143
5144
5145
5146
5147
5148
5149

5150
5151
5152
5153
5154
5155
5156







-







  if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){
    w.xSelectCallback = convertCompoundSelectToSubquery;
    w.xSelectCallback2 = 0;
    sqlite3WalkSelect(&w, pSelect);
  }
  w.xSelectCallback = selectExpander;
  w.xSelectCallback2 = selectPopWith;
  w.eCode = 0;
  sqlite3WalkSelect(&w, pSelect);
}


#ifndef SQLITE_OMIT_SUBQUERY
/*
** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo()
5532
5533
5534
5535
5536
5537
5538
5539

5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554

5555
5556
5557
5558
5559
5560
5561
5562
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







-
+














-
+
-







** 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;
  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++){
    Table *pTab = pFrom->pTab;
    assert( pTab!=0 );
    if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
      /* A sub-query in the FROM clause of a SELECT */
      Select *pSel = pFrom->pSelect;
      if( pSel ){
        while( pSel->pPrior ) pSel = pSel->pPrior;
        sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel,
        sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel);
                                               SQLITE_AFF_NONE);
      }
    }
  }
}
#endif


5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640

5641
5642
5643
5644
5645
5646
5647
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







-
















-
+







*/
static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
  Vdbe *v = pParse->pVdbe;
  int i;
  struct AggInfo_func *pFunc;
  int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
  if( nReg==0 ) return;
  if( pParse->nErr || pParse->db->mallocFailed ) return;
#ifdef SQLITE_DEBUG
  /* Verify that all AggInfo registers are within the range specified by
  ** AggInfo.mnReg..AggInfo.mxReg */
  assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
  for(i=0; i<pAggInfo->nColumn; i++){
    assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg
         && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg );
  }
  for(i=0; i<pAggInfo->nFunc; i++){
    assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg
         && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg );
  }
#endif
  sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
  for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
    if( pFunc->iDistinct>=0 ){
      Expr *pE = pFunc->pFExpr;
      Expr *pE = pFunc->pExpr;
      assert( !ExprHasProperty(pE, EP_xIsSelect) );
      if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
        sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
           "argument");
        pFunc->iDistinct = -1;
      }else{
        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0);
5657
5658
5659
5660
5661
5662
5663
5664
5665


5666
5667
5668
5669
5670
5671
5672
5288
5289
5290
5291
5292
5293
5294


5295
5296
5297
5298
5299
5300
5301
5302
5303







-
-
+
+







** in the AggInfo structure.
*/
static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
  Vdbe *v = pParse->pVdbe;
  int i;
  struct AggInfo_func *pF;
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    ExprList *pList = pF->pFExpr->x.pList;
    assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) );
    ExprList *pList = pF->pExpr->x.pList;
    assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
    sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
    sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
  }
}


/*
5687
5688
5689
5690
5691
5692
5693
5694
5695


5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729

5730
5731
5732
5733
5734
5735
5736
5737
5318
5319
5320
5321
5322
5323
5324


5325
5326























5327
5328
5329
5330
5331
5332
5333
5334
5335


5336

5337
5338
5339
5340
5341
5342
5343







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









-
-
+
-







  struct AggInfo_col *pC;

  pAggInfo->directMode = 1;
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    int nArg;
    int addrNext = 0;
    int regAgg;
    ExprList *pList = pF->pFExpr->x.pList;
    assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) );
    ExprList *pList = pF->pExpr->x.pList;
    assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
    assert( !IsWindowFunc(pF->pFExpr) );
    if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
      Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
      if( pAggInfo->nAccumulator 
       && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) 
       && regAcc
      ){
        /* If regAcc==0, there there exists some min() or max() function
        ** without a FILTER clause that will ensure the magnet registers
        ** are populated. */
        if( regHit==0 ) regHit = ++pParse->nMem;
        /* If this is the first row of the group (regAcc contains 0), clear the
        ** "magnet" register regHit so that the accumulator registers
        ** are populated if the FILTER clause jumps over the the 
        ** invocation of min() or max() altogether. Or, if this is not
        ** the first row (regAcc contains 1), set the magnet register so that
        ** the accumulators are not populated unless the min()/max() is invoked
        ** and indicates that they should be.  */
        sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit);
      }
      addrNext = sqlite3VdbeMakeLabel(pParse);
      sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL);
    }
    if( pList ){
      nArg = pList->nExpr;
      regAgg = sqlite3GetTempRange(pParse, nArg);
      sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
    }else{
      nArg = 0;
      regAgg = 0;
    }
    if( pF->iDistinct>=0 ){
      if( addrNext==0 ){ 
        addrNext = sqlite3VdbeMakeLabel(pParse);
      addrNext = sqlite3VdbeMakeLabel(pParse);
      }
      testcase( nArg==0 );  /* Error condition */
      testcase( nArg>1 );   /* Also an error */
      codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
    }
    if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
      CollSeq *pColl = 0;
      struct ExprList_item *pItem;
5757
5758
5759
5760
5761
5762
5763
5764

5765
5766
5767
5768
5769

5770
5771
5772
5773
5774
5775
5776
5363
5364
5365
5366
5367
5368
5369

5370
5371

5372
5373

5374
5375
5376
5377
5378
5379
5380
5381







-
+

-


-
+







  if( regHit==0 && pAggInfo->nAccumulator ){
    regHit = regAcc;
  }
  if( regHit ){
    addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
  }
  for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
    sqlite3ExprCode(pParse, pC->pCExpr, pC->iMem);
    sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
  }

  pAggInfo->directMode = 0;
  if( addrHitTest ){
    sqlite3VdbeJumpHereOrPopInst(v, addrHitTest);
    sqlite3VdbeJumpHere(v, addrHitTest);
  }
}

/*
** Add a single OP_Explain instruction to the VDBE to explain a simple
** count(*) query ("SELECT count(*) FROM pTab").
*/
5803
5804
5805
5806
5807
5808
5809
5810

5811
5812
5813
5814

5815
5816
5817
5818

5819
5820
5821
5822
5823
5824
5825
5408
5409
5410
5411
5412
5413
5414

5415


5416

5417
5418
5419
5420

5421
5422
5423
5424
5425
5426
5427
5428







-
+
-
-

-
+



-
+







** 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) 
    if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){
     && ExprAlwaysFalse(pExpr)==0
    ){
      sqlite3 *db = pWalker->pParse->db;
      Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1");
      Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
      if( pNew ){
        Expr *pWhere = pS->pWhere;
        SWAP(Expr, *pNew, *pExpr);
        pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
        pNew = sqlite3ExprAnd(db, pWhere, pNew);
        pS->pWhere = pNew;
        pWalker->eCode = 1;
      }
    }
    return WRC_Prune;
  }
  return WRC_Continue;
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
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919

5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5459
5460
5461
5462
5463
5464
5465

5466
5467

5468
5469

5470


5471
5472
5473
5474
5475

5476


5477
5478

5479
5480
5481
5482
5483

5484
5485
5486
5487
5488
5489
5490
5491
5492
5493









5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508

5509

5510
5511
5512
5513
5514
5515
5516
5517
5518
5519


5520
5521
5522
5523
5524
5525
5526







-
+

-
+

-
+
-
-





-
+
-
-


-
+




-
+









-
-
-
-
-
-
-
-
-















-
+
-










-
-







}

/*
** 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(
static struct SrcList_item *isSelfJoinView(
  SrcList *pTabList,           /* Search for self-joins in this FROM clause */
  SrcItem *pThis               /* Search for prior reference to this subquery */
  struct SrcList_item *pThis   /* Search for prior reference to this subquery */
){
  SrcItem *pItem;
  struct SrcList_item *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 );
    if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
    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 ){
    if( 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 ){
    if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
      /* 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)
**
** Into this:
**
**    SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2)
**
** The transformation only works if all of the following are true:
**
**   *  The subquery is a UNION ALL of two or more terms
**   *  The subquery does not have a LIMIT clause
**   *  There is no WHERE or GROUP BY or HAVING clauses on the subqueries
**   *  The outer query is a simple count(*) with no WHERE clause or other
**   *  The outer query is a simple count(*)
**      extraneous syntax.
**
** Return TRUE if the optimization is undertaken.
*/
static int countOfViewOptimization(Parse *pParse, Select *p){
  Select *pSub, *pPrior;
  Expr *pExpr;
  Expr *pCount;
  sqlite3 *db;
  if( (p->selFlags & SF_Aggregate)==0 ) return 0;   /* This is an aggregate */
  if( p->pEList->nExpr!=1 ) return 0;               /* Single result column */
  if( p->pWhere ) return 0;
  if( p->pGroupBy ) return 0;
  pExpr = p->pEList->a[0].pExpr;
  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;        /* Result is an aggregate */
  if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0;  /* Is count() */
  if( pExpr->x.pList!=0 ) return 0;                 /* Must be count(*) */
  if( p->pSrc->nSrc!=1 ) return 0;                  /* One table in FROM  */
  pSub = p->pSrc->a[0].pSelect;
  if( pSub==0 ) return 0;                           /* The FROM is a subquery */
6011
6012
6013
6014
6015
6016
6017
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
6082
6083
6084
6085
6086
6087
6088
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
6120
6121
6122

6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
5598
5599
5600
5601
5602
5603
5604

5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631





5632
5633
5634
5635
5636
5637


5638








5639


5640

5641

5642
5643
5644
5645
5646
5647
5648
5649
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







-



+











+











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

-













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





-
+
-
-



-
+










-
+




-
+



-
-
-
-
-







  Vdbe *v;               /* The virtual machine under construction */
  int isAgg;             /* True for select lists like "count(*)" */
  ExprList *pEList = 0;  /* List of columns to extract. */
  SrcList *pTabList;     /* List of tables to select from */
  Expr *pWhere;          /* The WHERE clause.  May be NULL */
  ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
  Expr *pHaving;         /* The HAVING clause.  May be NULL */
  AggInfo *pAggInfo = 0; /* Aggregate information */
  int rc = 1;            /* Value to return from this function */
  DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */
  SortCtx sSort;         /* Info on how to code the ORDER BY clause */
  AggInfo sAggInfo;      /* Information used by aggregate queries */
  int iEnd;              /* Address of the end of the query */
  sqlite3 *db;           /* The database connection */
  ExprList *pMinMaxOrderBy = 0;  /* Added ORDER BY for min/max queries */
  u8 minMaxFlag;                 /* Flag for min/max queries */

  db = pParse->db;
  v = sqlite3GetVdbe(pParse);
  if( p==0 || db->mallocFailed || pParse->nErr ){
    return 1;
  }
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
  memset(&sAggInfo, 0, sizeof(sAggInfo));
#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( IgnorableOrderby(pDest) ){
    assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || 
           pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
           pDest->eDest==SRT_Queue  || pDest->eDest==SRT_DistFifo ||
           pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo);
    /* If ORDER BY makes no difference in the output then neither does
    if( p->pOrderBy ){
#if SELECTTRACE_ENABLED
    ** DISTINCT so it can be removed too. */
      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);
    sqlite3ExprListDelete(db, p->pOrderBy);
      testcase( pParse->earlyCleanup );
      p->pOrderBy = 0;
    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;
      }
    }
  }

  if( pDest->eDest==SRT_Output ){
    generateColumnNames(pParse, p);
  }

#ifndef SQLITE_OMIT_WINDOWFUNC
  rc = sqlite3WindowRewrite(pParse, p);
  if( sqlite3WindowRewrite(pParse, p) ){
  if( rc ){
    assert( db->mallocFailed || pParse->nErr>0 );
    goto select_end;
  }
#if SELECTTRACE_ENABLED
  if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
  if( sqlite3SelectTrace & 0x108 ){
    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
  /* Try to 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];
    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 );

    /* Convert LEFT JOIN into JOIN if there are terms of the right table
    ** of the LEFT JOIN used in the WHERE clause.
    */
    if( (pItem->fg.jointype & JT_LEFT)!=0
     && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
     && OptimizationEnabled(db, SQLITE_SimplifyJoin)
    ){
6249
6250
6251
6252
6253
6254
6255
6256

6257
6258
6259
6260
6261
6262
6263
6264
5802
5803
5804
5805
5806
5807
5808

5809

5810
5811
5812
5813
5814
5815
5816







-
+
-







#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];
    struct SrcList_item *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
6273
6274
6275
6276
6277
6278
6279
6280

6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294

6295
6296
6297
6298
6299
6300
6301
6302

6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340



6341
6342
6343

6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
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
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
5878
5879
5880



5881
5882
5883

5884

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
5916
5917
5918
5919
5920

5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939



5940
5941
5942
5943
5944
5945
5946
5947
5948
5949







5950
5951
5952
5953
5954
5955
5956







-
+













-
+
-
-
-
-
-
-
-
-
+














-










-









-
-
-
+
+
+
-

-
+





-



















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

-
-
-
+
+
+
+
+



+

-
+












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






-
-
-
-
-
-
-







    ** have a column named by the empty string, in which case there is no way to
    ** distinguish between an unreferenced table and an actual reference to the
    ** "" column. The original design was for the fake column name to be a NULL,
    ** which would be unambiguous.  But legacy authorization callbacks might
    ** assume the column name is non-NULL and segfault.  The use of an empty
    ** string for the fake column name seems safer.
    */
    if( pItem->colUsed==0 && pItem->zName!=0 ){
    if( pItem->colUsed==0 ){
      sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
    }

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
    /* Generate code for all sub-queries in the FROM clause
    */
    pSub = pItem->pSelect;
    if( pSub==0 ) continue;

    /* The code for a subquery should only be generated once, though it is
    ** technically harmless for it to be generated multiple times. The
    ** following assert() will detect if something changes to cause
    ** the same subquery to be coded multiple times, as a signal to the
    ** developers to try to optimize the situation.
    ** developers to try to optimize the situation. */
    **
    ** Update 2019-07-24:
    ** See ticket https://sqlite.org/src/tktview/c52b09c7f38903b1311cec40.
    ** The dbsqlfuzz fuzzer found a case where the same subquery gets
    ** coded twice.  So this assert() now becomes a testcase().  It should
    ** be very rare, though.
    */
    testcase( pItem->addrFillSub!=0 );
    assert( pItem->addrFillSub==0 );

    /* Increment Parse.nHeight by the height of the largest expression
    ** tree referred to by this, the parent select. The child select
    ** may contain expression trees of at most
    ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
    ** more conservative than necessary, but much easier than enforcing
    ** an exact limit.
    */
    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
    ** 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)
    **    (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
    ** 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) */
     && (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{
      /* Materalize the view.  If the view is not correlated, generate a
      ** subroutine to do the materialization so that subsequent uses of
      ** the same view can reuse the materialization. */
      /* 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 */
      assert( pItem->addrFillSub==0 );
      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);
        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 && pItem->fg.isCorrelated==0 ){
        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
  }

6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
5982
5983
5984
5985
5986
5987
5988



5989
5990
5991

5992
5993
5994
5995
5996
5997
5998







-
-
-



-







  ** The second form is preferred as a single index (or temp-table) may be 
  ** used for both the ORDER BY and DISTINCT processing. As originally 
  ** written the query must use a temp-table for at least one of the ORDER 
  ** BY and DISTINCT, and an index or separate temp-table for the other.
  */
  if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct 
   && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0
#ifndef SQLITE_OMIT_WINDOWFUNC
   && p->pWin==0
#endif
  ){
    p->selFlags &= ~SF_Distinct;
    pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0);
    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 ){
6536
6537
6538
6539
6540
6541
6542
6543

6544
6545

6546
6547
6548
6549
6550
6551
6552
6057
6058
6059
6060
6061
6062
6063

6064
6065

6066
6067
6068
6069
6070
6071
6072
6073







-
+

-
+







  }

  if( !isAgg && pGroupBy==0 ){
    /* No aggregate functions and no GROUP BY clause */
    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
                   | (p->selFlags & SF_FixedLimit);
#ifndef SQLITE_OMIT_WINDOWFUNC
    Window *pWin = p->pWin;      /* Main window object (or NULL) */
    Window *pWin = p->pWin;      /* Master window object (or NULL) */
    if( pWin ){
      sqlite3WindowCodeInit(pParse, p);
      sqlite3WindowCodeInit(pParse, pWin);
    }
#endif
    assert( WHERE_USE_LIMIT==SF_FixedLimit );


    /* Begin the database scan. */
    SELECTTRACE(1,pParse,p,("WhereBegin\n"));
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6083
6084
6085
6086
6087
6088
6089

6090
6091
6092
6093
6094
6095
6096







-







    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);
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6121
6122
6123
6124
6125
6126
6127

6128
6129
6130
6131
6132
6133
6134







-







      /* 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 */
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670












6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691

6692
6693
6694
6695



6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710



6711
6712
6713
6714

6715
6716

6717
6718

6719
6720
6721
6722
6723
6724
6725
6726
6727

6728
6729
6730
6731
6732

6733
6734
6735
6736
6737
6738

6739
6740
6741


6742
6743

6744
6745
6746


6747
6748
6749
6750
6751
6752
6753
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

6214






6215
6216

6217
6218
6219
6220
6221

6222
6223





6224
6225


6226
6227
6228

6229
6230


6231
6232
6233
6234
6235
6236
6237
6238
6239







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





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







-
-
-
-
-
-
-
-
-
-



-
+

-
-
-
+
+
+












-
-
-
+
+
+



-
+
-
-
+

-
+
-
-
-
-
-
-


-
+




-
+

-
-
-
-
-
+

-
-
+
+

-
+

-
-
+
+







        pItem->u.x.iAlias = 0;
      }
      for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
        pItem->u.x.iAlias = 0;
      }
      assert( 66==sqlite3LogEst(100) );
      if( p->nSelectRow>66 ) p->nSelectRow = 66;

      /* If there is both a GROUP BY and an ORDER BY clause and they are
      ** identical, then it may be possible to disable the ORDER BY clause 
      ** on the grounds that the GROUP BY will cause elements to come out 
      ** in the correct order. It also may not - the GROUP BY might use a
      ** database index that causes rows to be grouped together as required
      ** but not actually sorted. Either way, record the fact that the
      ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
      ** variable.  */
      if( sSort.pOrderBy && pGroupBy->nExpr==sSort.pOrderBy->nExpr ){
        int ii;
        /* The GROUP BY processing doesn't care whether rows are delivered in
        ** ASC or DESC order - only that each group is returned contiguously.
        ** So set the ASC/DESC flags in the GROUP BY to match those in the 
        ** ORDER BY to maximize the chances of rows being delivered in an 
        ** order that makes the ORDER BY redundant.  */
        for(ii=0; ii<pGroupBy->nExpr; ii++){
          u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC;
          pGroupBy->a[ii].sortFlags = sortFlags;
        }
        if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
          orderByGrp = 1;
        }
      }
    }else{
      assert( 0==sqlite3LogEst(1) );
      p->nSelectRow = 0;
    }

    /* If there is both a GROUP BY and an ORDER BY clause and they are
    ** identical, then it may be possible to disable the ORDER BY clause 
    ** on the grounds that the GROUP BY will cause elements to come out 
    ** in the correct order. It also may not - the GROUP BY might use a
    ** database index that causes rows to be grouped together as required
    ** but not actually sorted. Either way, record the fact that the
    ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
    ** variable.  */
    if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
      orderByGrp = 1;
    }
 
    /* Create a label to jump to when we want to abort the query */
    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;
    sNC.uNC.pAggInfo = &sAggInfo;
    VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
    pAggInfo->mnReg = pParse->nMem+1;
    pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
    pAggInfo->pGroupBy = pGroupBy;
    sAggInfo.mnReg = pParse->nMem+1;
    sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
    sAggInfo.pGroupBy = pGroupBy;
    sqlite3ExprAnalyzeAggList(&sNC, pEList);
    sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
    if( pHaving ){
      if( pGroupBy ){
        assert( pWhere==p->pWhere );
        assert( pHaving==p->pHaving );
        assert( pGroupBy==p->pGroupBy );
        havingToWhere(pParse, p);
        pWhere = p->pWhere;
      }
      sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
    }
    pAggInfo->nAccumulator = pAggInfo->nColumn;
    if( p->pGroupBy==0 && p->pHaving==0 && pAggInfo->nFunc==1 ){
      minMaxFlag = minMaxQuery(db, pAggInfo->aFunc[0].pFExpr, &pMinMaxOrderBy);
    sAggInfo.nAccumulator = sAggInfo.nColumn;
    if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){
      minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy);
    }else{
      minMaxFlag = WHERE_ORDERBY_NORMAL;
    }
    for(i=0; i<pAggInfo->nFunc; i++){
    for(i=0; i<sAggInfo.nFunc; i++){
      Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
      assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
      sNC.ncFlags |= NC_InAggFunc;
      sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
      sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
#ifndef SQLITE_OMIT_WINDOWFUNC
      assert( !IsWindowFunc(pExpr) );
      if( ExprHasProperty(pExpr, EP_WinFunc) ){
        sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter);
      }
#endif
      sNC.ncFlags &= ~NC_InAggFunc;
    }
    pAggInfo->mxReg = pParse->nMem;
    sAggInfo.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));
      SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n"));
      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++){
      for(ii=0; ii<sAggInfo.nColumn; ii++){
        sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
            ii, pAggInfo->aCol[ii].iMem);
        sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0);
            ii, sAggInfo.aCol[ii].iMem);
        sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0);
      }
      for(ii=0; ii<pAggInfo->nFunc; ii++){
      for(ii=0; ii<sAggInfo.nFunc; ii++){
        sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
            ii, pAggInfo->aFunc[ii].iMem);
        sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0);
            ii, sAggInfo.aFunc[ii].iMem);
        sqlite3TreeViewExpr(0, sAggInfo.aFunc[ii].pExpr, 0);
      }
    }
#endif


    /* Processing for aggregates with GROUP BY is very different and
    ** much more complex than aggregates without a GROUP BY.
6764
6765
6766
6767
6768
6769
6770
6771
6772


6773
6774
6775

6776
6777
6778
6779
6780
6781
6782
6250
6251
6252
6253
6254
6255
6256


6257
6258

6259

6260
6261
6262
6263
6264
6265
6266
6267







-
-
+
+
-

-
+







      int regReset;       /* Return address register for reset subroutine */

      /* If there is a GROUP BY clause we might need a sorting index to
      ** implement it.  Allocate that sorting index now.  If it turns out
      ** that we do not need it after all, the OP_SorterOpen instruction
      ** will be converted into a Noop.  
      */
      pAggInfo->sortingIdx = pParse->nTab++;
      pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pGroupBy,
      sAggInfo.sortingIdx = pParse->nTab++;
      pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn);
                                            0, pAggInfo->nColumn);
      addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, 
          pAggInfo->sortingIdx, pAggInfo->nSortingColumn, 
          sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
          0, (char*)pKeyInfo, P4_KEYINFO);

      /* Initialize memory locations used by GROUP BY aggregate processing
      */
      iUseFlag = ++pParse->nMem;
      iAbortFlag = ++pParse->nMem;
      regOutputRow = ++pParse->nMem;
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6283
6284
6285
6286
6287
6288
6289

6290
6291
6292
6293
6294
6295
6296







-







      */
      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{
6824
6825
6826
6827
6828
6829
6830
6831
6832


6833
6834
6835
6836
6837
6838
6839
6840
6841


6842
6843
6844
6845
6846
6847
6848
6849
6850
6851

6852
6853
6854
6855
6856

6857
6858
6859

6860
6861

6862
6863
6864
6865
6866
6867
6868
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







-
-
+
+







-
-
+
+









-
+


-

-
+


-
+

-
+







            (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
                    "DISTINCT" : "GROUP BY");

        groupBySort = 1;
        nGroupBy = pGroupBy->nExpr;
        nCol = nGroupBy;
        j = nGroupBy;
        for(i=0; i<pAggInfo->nColumn; i++){
          if( pAggInfo->aCol[i].iSorterColumn>=j ){
        for(i=0; i<sAggInfo.nColumn; i++){
          if( sAggInfo.aCol[i].iSorterColumn>=j ){
            nCol++;
            j++;
          }
        }
        regBase = sqlite3GetTempRange(pParse, nCol);
        sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
        j = nGroupBy;
        for(i=0; i<pAggInfo->nColumn; i++){
          struct AggInfo_col *pCol = &pAggInfo->aCol[i];
        for(i=0; i<sAggInfo.nColumn; i++){
          struct AggInfo_col *pCol = &sAggInfo.aCol[i];
          if( pCol->iSorterColumn>=j ){
            int r1 = j + regBase;
            sqlite3ExprCodeGetColumnOfTable(v,
                               pCol->pTab, pCol->iTable, pCol->iColumn, r1);
            j++;
          }
        }
        regRecord = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
        sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord);
        sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord);
        sqlite3ReleaseTempReg(pParse, regRecord);
        sqlite3ReleaseTempRange(pParse, regBase, nCol);
        SELECTTRACE(1,pParse,p,("WhereEnd\n"));
        sqlite3WhereEnd(pWInfo);
        pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++;
        sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++;
        sortOut = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
        sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd);
        sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
        pAggInfo->useSortingIdx = 1;
        sAggInfo.useSortingIdx = 1;
      }

      /* If the index or temporary table used by the GROUP BY sort
      ** will naturally deliver rows in the order required by the ORDER BY
      ** clause, cancel the ephemeral table open coded earlier.
      **
      ** This is an optimization - the correct answer should result regardless.
6878
6879
6880
6881
6882
6883
6884
6885

6886
6887
6888
6889
6890
6891
6892

6893
6894
6895
6896
6897
6898
6899
6361
6362
6363
6364
6365
6366
6367

6368
6369
6370
6371
6372
6373
6374

6375
6376
6377
6378
6379
6380
6381
6382







-
+






-
+







      /* Evaluate the current GROUP BY terms and store in b0, b1, b2...
      ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
      ** Then compare the current GROUP BY terms against the GROUP BY terms
      ** from the previous row currently stored in a0, a1, a2...
      */
      addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
      if( groupBySort ){
        sqlite3VdbeAddOp3(v, OP_SorterData, pAggInfo->sortingIdx,
        sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
                          sortOut, sortPTab);
      }
      for(j=0; j<pGroupBy->nExpr; j++){
        if( groupBySort ){
          sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
        }else{
          pAggInfo->directMode = 1;
          sAggInfo.directMode = 1;
          sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
        }
      }
      sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
                          (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
      addr1 = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v);
6915
6916
6917
6918
6919
6920
6921
6922

6923
6924
6925
6926
6927
6928
6929

6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6398
6399
6400
6401
6402
6403
6404

6405
6406
6407
6408
6409
6410
6411

6412
6413
6414

6415
6416
6417
6418
6419
6420
6421







-
+






-
+


-







      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
      VdbeComment((v, "reset accumulator"));

      /* Update the aggregate accumulators based on the content of
      ** the current row
      */
      sqlite3VdbeJumpHere(v, addr1);
      updateAccumulator(pParse, iUseFlag, pAggInfo);
      updateAccumulator(pParse, iUseFlag, &sAggInfo);
      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);
        sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.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);
6956
6957
6958
6959
6960
6961
6962
6963

6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974

6975
6976
6977
6978
6979
6980

6981
6982

6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001

7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023







7024
7025
7026
7027
7028
7029
7030
7031
7032
7033

7034
7035
7036
7037

7038
7039
7040



7041
7042
7043
7044
7045



7046
7047

7048
7049
7050
7051
7052
7053



7054
7055
7056
7057

7058
7059

7060
7061

7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072

7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089

7090
7091
7092




7093
7094
7095
7096

7097
7098
7099
7100
7101
7102
7103
6438
6439
6440
6441
6442
6443
6444

6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455

6456
6457
6458
6459
6460
6461
6462
6463
6464

6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483

6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498








6499
6500
6501
6502
6503
6504
6505

6506
6507
6508
6509
6510
6511
6512
6513

6514
6515
6516
6517

6518
6519
6520

6521
6522
6523
6524
6525



6526
6527
6528


6529






6530
6531
6532




6533


6534


6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545

6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561


6562
6563


6564
6565
6566
6567
6568

6569

6570
6571
6572
6573
6574
6575
6576
6577







-
+










-
+






+

-
+


















-
+














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








-
+



-
+


-
+
+
+


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










-
+















-
-
+

-
-
+
+
+
+

-

-
+







      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
      sqlite3VdbeResolveLabel(v, addrOutputRow);
      addrOutputRow = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
      VdbeCoverage(v);
      VdbeComment((v, "Groupby result generator entry point"));
      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
      finalizeAggFunctions(pParse, pAggInfo);
      finalizeAggFunctions(pParse, &sAggInfo);
      sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
      selectInnerLoop(pParse, p, -1, &sSort,
                      &sDistinct, pDest,
                      addrOutputRow+1, addrSetAbort);
      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
      VdbeComment((v, "end groupby result generator"));

      /* Generate a subroutine that will reset the group-by accumulator
      */
      sqlite3VdbeResolveLabel(v, addrReset);
      resetAccumulator(pParse, pAggInfo);
      resetAccumulator(pParse, &sAggInfo);
      sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
      VdbeComment((v, "indicate accumulator empty"));
      sqlite3VdbeAddOp1(v, OP_Return, regReset);
     
    } /* endif pGroupBy.  Begin aggregate queries without GROUP BY: */
    else {
#ifndef SQLITE_OMIT_BTREECOUNT
      Table *pTab;
      if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){
      if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
        /* If isSimpleCount() returns a pointer to a Table structure, then
        ** the SQL statement is of the form:
        **
        **   SELECT count(*) FROM <tbl>
        **
        ** where the Table structure returned represents table <tbl>.
        **
        ** This statement is so common that it is optimized specially. The
        ** OP_Count instruction is executed either on the intkey table that
        ** contains the data for table <tbl> or on one of its indexes. It
        ** is better to execute the op on an index, as indexes are almost
        ** always spread across less pages than their corresponding tables.
        */
        const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
        const int iCsr = pParse->nTab++;     /* Cursor to scan b-tree */
        Index *pIdx;                         /* Iterator variable */
        KeyInfo *pKeyInfo = 0;               /* Keyinfo for scanned index */
        Index *pBest = 0;                    /* Best index found so far */
        Pgno iRoot = pTab->tnum;             /* Root page of scanned b-tree */
        int iRoot = pTab->tnum;              /* Root page of scanned b-tree */

        sqlite3CodeVerifySchema(pParse, iDb);
        sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);

        /* Search for the index that has the lowest scan cost.
        **
        ** (2011-04-15) Do not do a full scan of an unordered index.
        **
        ** (2013-10-03) Do not count the entries in a partial index.
        **
        ** In practice the KeyInfo structure will not be used. It is only 
        ** passed to keep OP_OpenRead happy.
        */
        if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
        if( !p->pSrc->a[0].fg.notIndexed ){
          for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
            if( pIdx->bUnordered==0
             && pIdx->szIdxRow<pTab->szTabRow
             && pIdx->pPartIdxWhere==0
             && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
            ){
              pBest = pIdx;
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( pIdx->bUnordered==0
           && pIdx->szIdxRow<pTab->szTabRow
           && pIdx->pPartIdxWhere==0
           && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
          ){
            pBest = pIdx;
            }
          }
        }
        if( pBest ){
          iRoot = pBest->tnum;
          pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
        }

        /* Open a read-only cursor, execute the OP_Count, close the cursor. */
        sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, (int)iRoot, iDb, 1);
        sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1);
        if( pKeyInfo ){
          sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
        }
        sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem);
        sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
        sqlite3VdbeAddOp1(v, OP_Close, iCsr);
        explainSimpleCount(pParse, pTab, pBest);
      }else{
      }else
#endif /* SQLITE_OMIT_BTREECOUNT */
      {
        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.
        /* If there are accumulator registers but no min() or max() functions,
        ** allocate register regAcc. Register regAcc will contain 0 the first
        ** time the inner loop runs, and 1 thereafter. The code generated
        ** The code generated by updateAccumulator() uses this to ensure
        ** that the accumulator registers are (a) updated only once if
        ** by updateAccumulator() only updates the accumulator registers if
        ** there are no min() or max functions or (b) always updated for the
        ** first row visited by the aggregate, so that they are updated at
        ** least once even if the FILTER clause means the min() or max() 
        ** function visits zero rows.  */
        if( pAggInfo->nAccumulator ){
          for(i=0; i<pAggInfo->nFunc; i++){
        ** regAcc contains 0.  */
        if( sAggInfo.nAccumulator ){
          for(i=0; i<sAggInfo.nFunc; i++){
            if( ExprHasProperty(pAggInfo->aFunc[i].pFExpr, EP_WinFunc) ){
              continue;
            }
            if( pAggInfo->aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ){
            if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break;
              break;
            }
          }
          }
          if( i==pAggInfo->nFunc ){
          if( i==sAggInfo.nFunc ){
            regAcc = ++pParse->nMem;
            sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
          }
        }

        /* This case runs if the aggregate has no GROUP BY clause.  The
        ** processing is much simpler since there is only a single row
        ** of output.
        */
        assert( p->pGroupBy==0 );
        resetAccumulator(pParse, pAggInfo);
        resetAccumulator(pParse, &sAggInfo);

        /* If this query is a candidate for the min/max optimization, then
        ** minMaxFlag will have been previously set to either
        ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will
        ** be an appropriate ORDER BY expression for the optimization.
        */
        assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
        assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );

        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);
        updateAccumulator(pParse, regAcc, &sAggInfo);
        if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
        if( minMaxFlag ){
          sqlite3WhereMinMaxOptEarlyOut(v, pWInfo);
        if( sqlite3WhereIsOrdered(pWInfo)>0 ){
          sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
          VdbeComment((v, "%s() by index",
                (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max")));
        }
        SELECTTRACE(1,pParse,p,("WhereEnd\n"));
        sqlite3WhereEnd(pWInfo);
        finalizeAggFunctions(pParse, pAggInfo);
        finalizeAggFunctions(pParse, &sAggInfo);
      }

      sSort.pOrderBy = 0;
      sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
      selectInnerLoop(pParse, p, -1, 0, 0, 
                      pDest, addrEnd, addrEnd);
    }
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143

7144
7145
7146
7147
7148
7149
7150
7151

7152
7153
7154
7155
7156
7157
7158
7159
7160
6602
6603
6604
6605
6606
6607
6608









6609








6610
6611
6612
6613
6614
6615
6616
6617
6618
6619







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









  rc = (pParse->nErr>0);

  /* Control jumps to here if an error is encountered above, or upon
  ** successful coding of the SELECT.
  */
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++){
  sqlite3DbFree(db, sAggInfo.aCol);
      Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
      assert( pExpr!=0 );
      assert( pExpr->pAggInfo==pAggInfo );
      assert( pExpr->iAgg==i );
    }
  }
#endif

  sqlite3DbFree(db, sAggInfo.aFunc);
#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.

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








20
21
22
23
24
25
26







-
-
-
-
-
-
-
-







** utility for accessing SQLite databases.
*/
#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
/* This needs to come before any includes for MSVC compiler */
#define _CRT_SECURE_NO_WARNINGS
#endif

/*
** Determine if we are dealing with WinRT, which provides only a subset of
** the full Win32 API.
*/
#if !defined(SQLITE_OS_WINRT)
# define SQLITE_OS_WINRT 0
#endif

/*
** Warning pragmas copied from msvc.h in the core.
*/
#if defined(_MSC_VER)
#pragma warning(disable : 4054)
#pragma warning(disable : 4055)
#pragma warning(disable : 4100)
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
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







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







# define shell_stifle_history(X)

# define SHELL_USE_LOCAL_GETLINE 1
#endif


#if defined(_WIN32) || defined(WIN32)
# if SQLITE_OS_WINRT
#  define SQLITE_OMIT_POPEN 1
# else
#  include <io.h>
#  include <fcntl.h>
#  define isatty(h) _isatty(h)
#  ifndef access
#   define access(f,m) _access((f),(m))
#  endif
#  ifndef unlink
#   define unlink _unlink
#  endif
#  ifndef strdup
#   define strdup _strdup
#  endif
#  undef popen
#  define popen _popen
#  undef pclose
#  define pclose _pclose
# include <io.h>
# include <fcntl.h>
# define isatty(h) _isatty(h)
# ifndef access
#  define access(f,m) _access((f),(m))
# endif
# ifndef unlink
#  define unlink _unlink
# endif
# ifndef strdup
#  define strdup _strdup
# endif
# undef popen
# define popen _popen
# undef pclose
# define pclose _pclose
# endif
#else
 /* Make sure isatty() has a prototype. */
 extern int isatty(int);

# if !defined(__RTP__) && !defined(_WRS_KERNEL)
  /* popen and pclose are not C89 functions and so are
  ** sometimes omitted from the <stdio.h> header */
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
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







-
-
-















-
+








/* ctype macros that work with signed characters */
#define IsSpace(X)  isspace((unsigned char)X)
#define IsDigit(X)  isdigit((unsigned char)X)
#define ToLower(X)  (char)tolower((unsigned char)X)

#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
#include <intrin.h>
#endif
#include <windows.h>

/* string conversion routines only needed on Win32 */
extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
#endif

/* On Windows, we normally run with output mode of TEXT so that \n characters
** are automatically translated into \r\n.  However, this behavior needs
** to be disabled in some cases (ex: when generating CSV output and when
** rendering quoted strings that contain \n characters).  The following
** routines take care of that.
*/
#if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
#if defined(_WIN32) || defined(WIN32)
static void setBinaryMode(FILE *file, int isOutput){
  if( isOutput ) fflush(file);
  _setmode(_fileno(file), _O_BINARY);
}
static void setTextMode(FILE *file, int isOutput){
  if( isOutput ) fflush(file);
  _setmode(_fileno(file), _O_TEXT);
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
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







-
















-







** Check to see if we have timer support.  Return 1 if necessary
** support found (or found previously).
*/
static int hasTimer(void){
  if( getProcessTimesAddr ){
    return 1;
  } else {
#if !SQLITE_OS_WINRT
    /* GetProcessTimes() isn't supported in WIN95 and some other Windows
    ** versions. See if the version we are running on has it, and if it
    ** does, save off a pointer to it and the current process handle.
    */
    hProcess = GetCurrentProcess();
    if( hProcess ){
      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
      if( NULL != hinstLib ){
        getProcessTimesAddr =
            (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
        if( NULL != getProcessTimesAddr ){
          return 1;
        }
        FreeLibrary(hinstLib);
      }
    }
#endif
  }
  return 0;
}

/*
** Begin timing an operation
*/
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
393
394
395
396
397
398
399









400
401
402
403
404
405
406







-
-
-
-
-
-
-
-
-







static sqlite3 *globalDb = 0;

/*
** True if an interrupt (Control-C) has been received.
*/
static volatile int seenInterrupt = 0;

#ifdef SQLITE_DEBUG
/*
** Out-of-memory simulator variables
*/
static unsigned int oomCounter = 0;    /* Simulate OOM when equals 1 */
static unsigned int oomRepeat = 0;     /* Number of OOMs in a row */
static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */
#endif /* SQLITE_DEBUG */

/*
** This is the name of our program. It is set in main(), used
** in a number of other places, mostly for error messages.
*/
static char *Argv0;

/*
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
444
445
446
447
448
449
450











































451
452
453
454
455
456
457







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








/* Indicate out-of-memory and exit. */
static void shell_out_of_memory(void){
  raw_printf(stderr,"Error: out of memory\n");
  exit(1);
}

#ifdef SQLITE_DEBUG
/* This routine is called when a simulated OOM occurs.  It is broken
** out as a separate routine to make it easy to set a breakpoint on
** the OOM
*/
void shellOomFault(void){
  if( oomRepeat>0 ){
    oomRepeat--;
  }else{
    oomCounter--;
  }
}
#endif /* SQLITE_DEBUG */

#ifdef SQLITE_DEBUG
/* This routine is a replacement malloc() that is used to simulate
** Out-Of-Memory (OOM) errors for testing purposes.
*/
static void *oomMalloc(int nByte){
  if( oomCounter ){
    if( oomCounter==1 ){
      shellOomFault();
      return 0;
    }else{
      oomCounter--;
    }
  }
  return defaultMalloc(nByte);
}
#endif /* SQLITE_DEBUG */

#ifdef SQLITE_DEBUG
/* Register the OOM simulator.  This must occur before any memory
** allocations */
static void registerOomSimulator(void){
  sqlite3_mem_methods mem;
  sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem);
  defaultMalloc = mem.xMalloc;
  mem.xMalloc = oomMalloc;
  sqlite3_config(SQLITE_CONFIG_MALLOC, &mem);
}
#endif

/*
** Write I/O traces to the following stream.
*/
#ifdef SQLITE_ENABLE_IOTRACE
static FILE *iotrace = 0;
#endif

549
550
551
552
553
554
555


556
557
558
559
560
561
562
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495







+
+







** in bytes.  This is different from the %*.*s specification in printf
** since with %*.*s the width is measured in bytes, not characters.
*/
static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
  int i;
  int n;
  int aw = w<0 ? -w : w;
  char zBuf[1000];
  if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
  for(i=n=0; zUtf[i]; i++){
    if( (zUtf[i]&0xc0)!=0x80 ){
      n++;
      if( n==aw ){
        do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
        break;
      }
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
550
551
552
553
554
555
556















557
558
559
560
561
562
563







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







  int n = 0;
  while( *z ){
    if( (0xc0&*(z++))!=0x80 ) n++;
  }
  return n;
}

/*
** Return true if zFile does not exist or if it is not an ordinary file.
*/
#ifdef _WIN32
# define notNormalFile(X) 0
#else
static int notNormalFile(const char *zFile){
  struct stat x;
  int rc;
  memset(&x, 0, sizeof(x));
  rc = stat(zFile, &x);
  return rc || !S_ISREG(x.st_mode);
}
#endif

/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
** If zLine is not NULL then it is a malloced buffer returned from
944
945
946
947
948
949
950
951

952
953
954
955
956
957
958
862
863
864
865
866
867
868

869
870
871
872
873
874
875
876







-
+







**    CREATE INDEX
**    CREATE UNIQUE INDEX
**    CREATE VIEW
**    CREATE TRIGGER
**    CREATE VIRTUAL TABLE
**
** This UDF is used by the .schema command to insert the schema name of
** attached databases into the middle of the sqlite_schema.sql field.
** attached databases into the middle of the sqlite_master.sql field.
*/
static void shellAddSchemaName(
  sqlite3_context *pCtx,
  int nVal,
  sqlite3_value **apVal
){
  static const char *aPrefix[] = {
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
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







-
-
-
-







-
-
-
-












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







#define dirent DIRENT
#endif
INCLUDE ../ext/misc/shathree.c
INCLUDE ../ext/misc/fileio.c
INCLUDE ../ext/misc/completion.c
INCLUDE ../ext/misc/appendvfs.c
INCLUDE ../ext/misc/memtrace.c
INCLUDE ../ext/misc/uint.c
INCLUDE ../ext/misc/decimal.c
INCLUDE ../ext/misc/ieee754.c
INCLUDE ../ext/misc/series.c
#ifdef SQLITE_HAVE_ZLIB
INCLUDE ../ext/misc/zipfile.c
INCLUDE ../ext/misc/sqlar.c
#endif
INCLUDE ../ext/expert/sqlite3expert.h
INCLUDE ../ext/expert/sqlite3expert.c

#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
INCLUDE ../ext/misc/dbdata.c
#endif

#if defined(SQLITE_ENABLE_SESSION)
/*
** State information for a single open session
*/
typedef struct OpenSession OpenSession;
struct OpenSession {
  char *zName;             /* Symbolic name for this session */
  int nFilter;             /* Number of xFilter rejection GLOB patterns */
  char **azFilter;         /* Array of xFilter rejection GLOB patterns */
  sqlite3_session *p;      /* The open session */
};
#endif

/*
** Shell output mode information from before ".explain on",
** saved so that it can be restored by ".explain off"
*/
typedef struct SavedModeInfo SavedModeInfo;
struct SavedModeInfo {
  int valid;          /* Is there legit data in here? */
  int mode;           /* Mode prior to ".explain on" */
  int showHeader;     /* The ".header" setting prior to ".explain on" */
  int colWidth[100];  /* Column widths prior to ".explain on" */
};

typedef struct ExpertInfo ExpertInfo;
struct ExpertInfo {
  sqlite3expert *pExpert;
  int bVerbose;
};

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







+





-




-















-








-
-
+
+
-







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 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 */
  FILE *traceOut;        /* Output for sqlite3_trace() */
  int nErr;              /* Number of errors seen */
  int mode;              /* An output mode setting */
  int modePrior;         /* Saved mode */
  int cMode;             /* temporary output mode for the current query */
  int normalMode;        /* Output mode before ".explain on" */
  int writableSchema;    /* True if PRAGMA writable_schema=ON */
  int showHeader;        /* True to show column names in List or Column mode */
  int nCheck;            /* Number of ".check" commands run */
  unsigned nProgress;    /* Number of progress callbacks encountered */
  unsigned mxProgress;   /* Maximum progress callbacks before failing */
  unsigned flgProgress;  /* Flags for the progress callback */
  unsigned shellFlgs;    /* Various flags */
  unsigned priorShFlgs;  /* Saved copy of flags */
  sqlite3_int64 szMax;   /* --maxsize argument to .open */
  char *zDestTable;      /* Name of destination table when MODE_Insert */
  char *zTempFile;       /* Temporary file that might need deleting */
  char zTestcase[30];    /* Name of current test case */
  char colSeparator[20]; /* Column separator character for several modes */
  char rowSeparator[20]; /* Row separator character for MODE_Ascii */
  char colSepPrior[20];  /* Saved column separator */
  char rowSepPrior[20];  /* Saved row separator */
  int *colWidth;         /* Requested width of each column in columnar modes */
  int *actualWidth;      /* Actual width of each column */
  int colWidth[100];     /* Requested width of each column when in column mode*/
  int actualWidth[100];  /* Actual width of each column */
  int nWidth;            /* Number of slots in colWidth[] and actualWidth[] */
  char nullValue[20];    /* The text to print when a NULL comes back from
                         ** the database */
  char outfile[FILENAME_MAX]; /* Filename for *out */
  const char *zDbFilename;    /* name of the database file */
  char *zFreeOnClose;         /* Filename to free when closing */
  const char *zVfs;           /* Name of VFS to use */
  sqlite3_stmt *pStmt;   /* Current statement if any. */
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1098
1099
1100
1101
1102
1103
1104



1105
1106
1107
1108
1109
1110
1111







-
-
-







#define SHFLG_Pagecache      0x00000001 /* The --pagecache option is used */
#define SHFLG_Lookaside      0x00000002 /* Lookaside memory is used */
#define SHFLG_Backslash      0x00000004 /* The --backslash option is used */
#define SHFLG_PreserveRowid  0x00000008 /* .dump preserves rowid values */
#define SHFLG_Newlines       0x00000010 /* .dump --newline flag */
#define SHFLG_CountChanges   0x00000020 /* .changes setting */
#define SHFLG_Echo           0x00000040 /* .echo or --echo setting */
#define SHFLG_HeaderSet      0x00000080 /* .header has been used */
#define SHFLG_DumpDataOnly   0x00000100 /* .dump show data only */
#define SHFLG_DumpNoSys      0x00000200 /* .dump omits system tables */

/*
** Macros for testing and setting shellFlgs
*/
#define ShellHasFlag(P,X)    (((P)->shellFlgs & (X))!=0)
#define ShellSetFlag(P,X)    ((P)->shellFlgs|=(X))
#define ShellClearFlag(P,X)  ((P)->shellFlgs&=(~(X)))
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
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







-
-
-
-














-
+
-
-
-
-







#define MODE_Quote    6  /* Quote values as for SQL */
#define MODE_Tcl      7  /* Generate ANSI-C or TCL quoted elements */
#define MODE_Csv      8  /* Quote strings, numbers are plain */
#define MODE_Explain  9  /* Like MODE_Column, but do not truncate data */
#define MODE_Ascii   10  /* Use ASCII unit and record separators (0x1F/0x1E) */
#define MODE_Pretty  11  /* Pretty-print schemas */
#define MODE_EQP     12  /* Converts EXPLAIN QUERY PLAN output into a graph */
#define MODE_Json    13  /* Output JSON */
#define MODE_Markdown 14 /* Markdown formatting */
#define MODE_Table   15  /* MySQL-style table formatting */
#define MODE_Box     16  /* Unicode box-drawing characters */

static const char *modeDescr[] = {
  "line",
  "column",
  "list",
  "semi",
  "html",
  "insert",
  "quote",
  "tcl",
  "csv",
  "explain",
  "ascii",
  "prettyprint",
  "eqp",
  "eqp"
  "json",
  "markdown",
  "table",
  "box"
};

/*
** These are the column/row/line separators used by the various
** import/export modes.
*/
#define SEP_Column    "|"
1340
1341
1342
1343
1344
1345
1346
1347

1348
1349
1350
1351
1352

1353
1354
1355
1356
1357
1358
1359
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259

1260
1261
1262
1263
1264
1265
1266
1267







-
+




-
+







  f = fopen(zTempFile, bBin ? "wb" : "w");
  if( f==0 ){
    sqlite3_result_error(context, "edit() cannot open temp file", -1);
    goto edit_func_end;
  }
  sz = sqlite3_value_bytes(argv[0]);
  if( bBin ){
    x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f);
    x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f);
  }else{
    const char *z = (const char*)sqlite3_value_text(argv[0]);
    /* Remember whether or not the value originally contained \r\n */
    if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
    x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f);
    x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f);
  }
  fclose(f);
  f = 0;
  if( x!=sz ){
    sqlite3_result_error(context, "edit() could not write the whole file", -1);
    goto edit_func_end;
  }
1373
1374
1375
1376
1377
1378
1379
1380

1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391
1392
1281
1282
1283
1284
1285
1286
1287

1288
1289
1290
1291
1292

1293
1294
1295
1296
1297
1298
1299
1300







-
+




-
+







    sqlite3_result_error(context,
      "edit() cannot reopen temp file after edit", -1);
    goto edit_func_end;
  }
  fseek(f, 0, SEEK_END);
  sz = ftell(f);
  rewind(f);
  p = sqlite3_malloc64( sz+1 );
  p = sqlite3_malloc64( sz+(bBin==0) );
  if( p==0 ){
    sqlite3_result_error_nomem(context);
    goto edit_func_end;
  }
  x = fread(p, 1, (size_t)sz, f);
  x = fread(p, 1, sz, f);
  fclose(f);
  f = 0;
  if( x!=sz ){
    sqlite3_result_error(context, "could not read back the whole file", -1);
    goto edit_func_end;
  }
  if( bBin ){
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1328
1329
1330
1331
1332
1333
1334

1335
1336
1337
1338
1339

1340
1341
1342
1343
1344
1345
1346







-





-







#endif /* SQLITE_NOHAVE_SYSTEM */

/*
** Save or restore the current output mode
*/
static void outputModePush(ShellState *p){
  p->modePrior = p->mode;
  p->priorShFlgs = p->shellFlgs;
  memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
  memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
}
static void outputModePop(ShellState *p){
  p->mode = p->modePrior;
  p->shellFlgs = p->priorShFlgs;
  memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
  memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
}

/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1495
1496
1497
1498
1499
1500
1501


































1502
1503
1504
1505
1506
1507
1508







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







      fputc('\\', out);
      fputc('n', out);
    }else if( c=='\r' ){
      fputc('\\', out);
      fputc('r', out);
    }else if( !isprint(c&0xff) ){
      raw_printf(out, "\\%03o", c&0xff);
    }else{
      fputc(c, out);
    }
  }
  fputc('"', out);
}

/*
** Output the given string as a quoted according to JSON quoting rules.
*/
static void output_json_string(FILE *out, const char *z, int n){
  unsigned int c;
  if( n<0 ) n = (int)strlen(z);
  fputc('"', out);
  while( n-- ){
    c = *(z++);
    if( c=='\\' || c=='"' ){
      fputc('\\', out);
      fputc(c, out);
    }else if( c<=0x1f ){
      fputc('\\', out);
      if( c=='\b' ){
        fputc('b', out);
      }else if( c=='\f' ){
        fputc('f', out);
      }else if( c=='\n' ){
        fputc('n', out);
      }else if( c=='\r' ){
        fputc('r', out);
      }else if( c=='\t' ){
        fputc('t', out);
      }else{
         raw_printf(out, "u%04x",c);
      }
    }else{
      fputc(c, out);
    }
  }
  fputc('"', out);
}

1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1673
1674
1675
1676
1677
1678
1679


1680
1681
1682
1683
1684
1685
1686







-
-







/*
** Print a schema statement.  Part of MODE_Semi and MODE_Pretty output.
**
** This routine converts some CREATE TABLE statements for shadow tables
** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
*/
static void printSchemaLine(FILE *out, const char *z, const char *zTail){
  if( z==0 ) return;
  if( zTail==0 ) return;
  if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
    utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
  }else{
    utf8_printf(out, "%s%s", z, zTail);
  }
}
static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
1886
1887
1888
1889
1890
1891
1892
1893

1894
1895
1896
1897
1898
1899
1900
1901
1756
1757
1758
1759
1760
1761
1762

1763

1764
1765
1766
1767
1768
1769
1770







-
+
-







static void eqp_render_level(ShellState *p, int iEqpId){
  EQPGraphRow *pRow, *pNext;
  int n = strlen30(p->sGraph.zPrefix);
  char *z;
  for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
    pNext = eqp_next_row(p, iEqpId, pRow);
    z = pRow->zText;
    utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix,
    utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
                pNext ? "|--" : "`--", z);
    if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
      memcpy(&p->sGraph.zPrefix[n], pNext ? "|  " : "   ", 4);
      eqp_render_level(p, pRow->iEqpId);
      p->sGraph.zPrefix[n] = 0;
    }
  }
}
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
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







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









-
+




















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



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




+
+
-
-
-
+
+
+
+
+









-
+







  if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
    raw_printf(p->out, "Progress %u\n", p->nProgress);
  }
  return 0;
}
#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */

/*
** Print N dashes
*/
static void print_dashes(FILE *out, int N){
  const char zDash[] = "--------------------------------------------------";
  const int nDash = sizeof(zDash) - 1;
  while( N>nDash ){
    fputs(zDash, out);
    N -= nDash;
  }
  raw_printf(out, "%.*s", N, zDash);
}

/*
** Print a markdown or table-style row separator using ascii-art
*/
static void print_row_separator(
  ShellState *p,
  int nArg,
  const char *zSep
){
  int i;
  if( nArg>0 ){
    fputs(zSep, p->out);
    print_dashes(p->out, p->actualWidth[0]+2);
    for(i=1; i<nArg; i++){
      fputs(zSep, p->out);
      print_dashes(p->out, p->actualWidth[i]+2);
    }
    fputs(zSep, p->out);
  }
  fputs("\n", p->out);
}

/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(
  void *pArg,
  int nArg,        /* Number of result columns */
  char **azArg,    /* Text of each result column */
  char **azCol,    /* Column names */
  int *aiType      /* Column types.  Might be NULL */
  int *aiType      /* Column types */
){
  int i;
  ShellState *p = (ShellState*)pArg;

  if( azArg==0 ) return 0;
  switch( p->cMode ){
    case MODE_Line: {
      int w = 5;
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        int len = strlen30(azCol[i] ? azCol[i] : "");
        if( len>w ) w = len;
      }
      if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
      for(i=0; i<nArg; i++){
        utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
                azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
      }
      break;
    }
    case MODE_Explain: {
      static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
      if( nArg>ArraySize(aExplainWidth) ){
        nArg = ArraySize(aExplainWidth);
    case MODE_Explain:
    case MODE_Column: {
      static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
      const int *colWidth;
      int showHdr;
      char *rowSep;
      if( p->cMode==MODE_Column ){
        colWidth = p->colWidth;
        showHdr = p->showHeader;
        rowSep = p->rowSeparator;
      }else{
        colWidth = aExplainWidths;
        showHdr = 1;
        rowSep = SEP_Row;
      }
      if( p->cnt++==0 ){
        for(i=0; i<nArg; i++){
          int w, n;
          if( i<ArraySize(p->colWidth) ){
          int w = aExplainWidth[i];
          utf8_width_print(p->out, w, azCol[i]);
          fputs(i==nArg-1 ? "\n" : "  ", p->out);
        }
        for(i=0; i<nArg; i++){
          int w = aExplainWidth[i];
          print_dashes(p->out, w);
          fputs(i==nArg-1 ? "\n" : "  ", p->out);
            w = colWidth[i];
          }else{
            w = 0;
          }
          if( w==0 ){
            w = strlenChar(azCol[i] ? azCol[i] : "");
            if( w<10 ) w = 10;
            n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue);
            if( w<n ) w = n;
          }
          if( i<ArraySize(p->actualWidth) ){
            p->actualWidth[i] = w;
          }
          if( showHdr ){
            utf8_width_print(p->out, w, azCol[i]);
            utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : "  ");
          }
        }
        if( showHdr ){
          for(i=0; i<nArg; i++){
            int w;
            if( i<ArraySize(p->actualWidth) ){
               w = p->actualWidth[i];
               if( w<0 ) w = -w;
            }else{
               w = 10;
            }
            utf8_printf(p->out,"%-*.*s%s",w,w,
                   "----------------------------------------------------------"
                   "----------------------------------------------------------",
                    i==nArg-1 ? rowSep : "  ");
          }
        }
      }
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        int w;
        if( i<ArraySize(p->actualWidth) ){
        int w = aExplainWidth[i];
        if( i==nArg-1 ) w = 0;
        if( azArg[i] && strlenChar(azArg[i])>w ){
           w = p->actualWidth[i];
        }else{
           w = 10;
        }
        if( p->cMode==MODE_Explain && 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], "");
          }
          p->iIndent++;
        }
        utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
        fputs(i==nArg-1 ? "\n" : "  ", p->out);
        utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : "  ");
      }
      break;
    }
    case MODE_Semi: {   /* .schema and .fullschema output */
      printSchemaLine(p->out, azArg[0], ";\n");
      break;
    }
2072
2073
2074
2075
2076
2077
2078
2079

2080
2081
2082
2083
2084
2085
2086
1947
1948
1949
1950
1951
1952
1953

1954
1955
1956
1957
1958
1959
1960
1961







-
+







          j--;
        }
        z[j++] = c;
      }
      while( j>0 && IsSpace(z[j-1]) ){ j--; }
      z[j] = 0;
      if( strlen30(z)>=79 ){
        for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
        for(i=j=0; (c = z[i])!=0; i++){  /* Copy changes from z[i] back to z[j] */
          if( c==cEnd ){
            cEnd = 0;
          }else if( c=='"' || c=='\'' || c=='`' ){
            cEnd = c;
          }else if( c=='[' ){
            cEnd = ']';
          }else if( c=='-' && z[i+1]=='-' ){
2238
2239
2240
2241
2242
2243
2244
2245

2246
2247

2248
2249
2250
2251
2252
2253

2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264

2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294

2295
2296
2297
2298

2299
2300
2301
2302
2303
2304
2305
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







-
+

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


-
+



-
+







        }else{
          output_quoted_escaped_string(p->out, azArg[i]);
        }
      }
      raw_printf(p->out,");\n");
      break;
    }
    case MODE_Json: {
    case MODE_Quote: {
      if( azArg==0 ) break;
      if( p->cnt==0 ){
      if( p->cnt==0 && p->showHeader ){
        fputs("[{", p->out);
      }else{
        fputs(",\n{", p->out);
      }
      p->cnt++;
      for(i=0; i<nArg; i++){
        for(i=0; i<nArg; i++){
        output_json_string(p->out, azCol[i], -1);
        putc(':', p->out);
        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
          fputs("null",p->out);
        }else if( aiType && aiType[i]==SQLITE_FLOAT ){
          char z[50];
          double r = sqlite3_column_double(p->pStmt, i);
          sqlite3_uint64 ur;
          memcpy(&ur,&r,sizeof(r));
          if( ur==0x7ff0000000000000LL ){
            raw_printf(p->out, "1e999");
          if( i>0 ) raw_printf(p->out, ",");
          }else if( ur==0xfff0000000000000LL ){
            raw_printf(p->out, "-1e999");
          }else{
            sqlite3_snprintf(50,z,"%!.20g", r);
            raw_printf(p->out, "%s", z);
          }
        }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
          const void *pBlob = sqlite3_column_blob(p->pStmt, i);
          int nBlob = sqlite3_column_bytes(p->pStmt, i);
          output_json_string(p->out, pBlob, nBlob);
        }else if( aiType && aiType[i]==SQLITE_TEXT ){
          output_json_string(p->out, azArg[i], -1);
        }else{
          utf8_printf(p->out,"%s", azArg[i]);
        }
        if( i<nArg-1 ){
          putc(',', p->out);
        }
      }
      putc('}', p->out);
      break;
    }
    case MODE_Quote: {
      if( azArg==0 ) break;
      if( p->cnt==0 && p->showHeader ){
        for(i=0; i<nArg; i++){
          if( i>0 ) fputs(p->colSeparator, p->out);
          output_quoted_string(p->out, azCol[i]);
        }
        fputs(p->rowSeparator, p->out);
        raw_printf(p->out,"\n");
      }
      p->cnt++;
      for(i=0; i<nArg; i++){
        if( i>0 ) fputs(p->colSeparator, p->out);
        if( i>0 ) raw_printf(p->out, ",");
        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
          utf8_printf(p->out,"NULL");
        }else if( aiType && aiType[i]==SQLITE_TEXT ){
          output_quoted_string(p->out, azArg[i]);
        }else if( aiType && aiType[i]==SQLITE_INTEGER ){
          utf8_printf(p->out,"%s", azArg[i]);
        }else if( aiType && aiType[i]==SQLITE_FLOAT ){
2313
2314
2315
2316
2317
2318
2319
2320

2321
2322
2323
2324
2325
2326
2327
2146
2147
2148
2149
2150
2151
2152

2153
2154
2155
2156
2157
2158
2159
2160







-
+







          output_hex_blob(p->out, pBlob, nBlob);
        }else if( isNumber(azArg[i], 0) ){
          utf8_printf(p->out,"%s", azArg[i]);
        }else{
          output_quoted_string(p->out, azArg[i]);
        }
      }
      fputs(p->rowSeparator, p->out);
      raw_printf(p->out,"\n");
      break;
    }
    case MODE_Ascii: {
      if( p->cnt++==0 && p->showHeader ){
        for(i=0; i<nArg; i++){
          if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
          utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
2386
2387
2388
2389
2390
2391
2392
2393

2394
2395

2396
2397
2398
2399
2400
2401
2402

2403
2404
2405
2406
2407
2408
2409
2219
2220
2221
2222
2223
2224
2225

2226
2227

2228
2229
2230
2231
2232
2233
2234

2235
2236
2237
2238
2239
2240
2241
2242







-
+

-
+






-
+







    "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n"
    "INSERT INTO [_shell$self](rowid,op,cmd)\n"
    "  VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n"
    "         'memo','Tests generated by --init');\n"
    "INSERT INTO [_shell$self]\n"
    "  SELECT 'run',\n"
    "    'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql "
                                 "FROM sqlite_schema ORDER BY 2'',224))',\n"
                                 "FROM sqlite_master ORDER BY 2'',224))',\n"
    "    hex(sha3_query('SELECT type,name,tbl_name,sql "
                          "FROM sqlite_schema ORDER BY 2',224));\n"
                          "FROM sqlite_master ORDER BY 2',224));\n"
    "INSERT INTO [_shell$self]\n"
    "  SELECT 'run',"
    "    'SELECT hex(sha3_query(''SELECT * FROM \"' ||"
    "        printf('%w',name) || '\" NOT INDEXED'',224))',\n"
    "    hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n"
    "  FROM (\n"
    "    SELECT name FROM sqlite_schema\n"
    "    SELECT name FROM sqlite_master\n"
    "     WHERE type='table'\n"
    "       AND name<>'selftest'\n"
    "       AND coalesce(rootpage,0)>0\n"
    "  )\n"
    " ORDER BY name;\n"
    "INSERT INTO [_shell$self]\n"
    "  VALUES('run','PRAGMA integrity_check','ok');\n"
2458
2459
2460
2461
2462
2463
2464
2465


2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481




2482
2483
2484
2485
2486
2487
2488
2291
2292
2293
2294
2295
2296
2297

2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326







-
+
+
















+
+
+
+







** If the number of columns is 1 and that column contains text "--"
** then write the semicolon on a separate line.  That way, if a
** "--" comment occurs at the end of the statement, the comment
** won't consume the semicolon terminator.
*/
static int run_table_dump_query(
  ShellState *p,           /* Query context */
  const char *zSelect      /* SELECT statement to extract content */
  const char *zSelect,     /* SELECT statement to extract content */
  const char *zFirstRow    /* Print before first row, if not NULL */
){
  sqlite3_stmt *pSelect;
  int rc;
  int nResult;
  int i;
  const char *z;
  rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
  if( rc!=SQLITE_OK || !pSelect ){
    utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
                sqlite3_errmsg(p->db));
    if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
    return rc;
  }
  rc = sqlite3_step(pSelect);
  nResult = sqlite3_column_count(pSelect);
  while( rc==SQLITE_ROW ){
    if( zFirstRow ){
      utf8_printf(p->out, "%s", zFirstRow);
      zFirstRow = 0;
    }
    z = (const char*)sqlite3_column_text(pSelect, 0);
    utf8_printf(p->out, "%s", z);
    for(i=1; i<nResult; i++){
      utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
    }
    if( z==0 ) z = "";
    while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
2588
2589
2590
2591
2592
2593
2594
2595

2596
2597
2598
2599
2600
2601
2602
2426
2427
2428
2429
2430
2431
2432

2433
2434
2435
2436
2437
2438
2439
2440







-
+







){
  int iCur;
  int iHiwtr;
  FILE *out;
  if( pArg==0 || pArg->out==0 ) return 0;
  out = pArg->out;

  if( pArg->pStmt && pArg->statsOn==2 ){
  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);
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2450
2451
2452
2453
2454
2455
2456








2457
2458
2459
2460
2461
2462
2463







-
-
-
-
-
-
-
-







      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:",
       "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
2696
2697
2698
2699
2700
2701
2702
2703

2704
2705
2706
2707
2708
2709
2710
2526
2527
2528
2529
2530
2531
2532

2533
2534
2535
2536
2537
2538
2539
2540







-
+







    raw_printf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
    raw_printf(pArg->out, "Sort Operations:                     %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
    raw_printf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
    raw_printf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset);
    raw_printf(pArg->out, "Reprepare operations:                %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
    raw_printf(pArg->out, "Number of times run:                 %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
    raw_printf(pArg->out, "Memory used by prepared stmt:        %d\n", iCur);
  }

2886
2887
2888
2889
2890
2891
2892


2893
2894






2895
2896
2897
2898
2899
2900








2901
2902

2903
2904





2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935



2936
2937
2938
2939
2940
2941
2942
2716
2717
2718
2719
2720
2721
2722
2723
2724


2725
2726
2727
2728
2729
2730
2731





2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742


2743
2744
2745
2746
2747
2748
2749
2750
2751
2752



2753
2754
2755
2756
2757
2758
2759
2760
2761

2762
2763
2764
2765
2766
2767
2768
2769
2770
2771



2772
2773
2774
2775
2776
2777
2778
2779
2780
2781







+
+
-
-
+
+
+
+
+
+

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


+
-
-
+
+
+
+
+





-
-
-









-










-
-
-
+
+
+







  p->nIndent = 0;
  p->iIndent = 0;
}

/*
** Disable and restore .wheretrace and .selecttrace settings.
*/
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
extern int sqlite3SelectTrace;
static unsigned int savedSelectTrace;
static unsigned int savedWhereTrace;
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){
  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);
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
  savedSelectTrace = sqlite3SelectTrace;
  sqlite3SelectTrace = 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_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace);
  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace);
  sqlite3SelectTrace = 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);
  sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0);
  sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
  sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
  sqlite3_exec(p->db,
    "CREATE TABLE IF NOT EXISTS temp.sqlite_parameters(\n"
    "  key TEXT PRIMARY KEY,\n"
    "  value ANY\n"
    ") WITHOUT ROWID;",
    0, 0, 0);
  sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
  sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, defensiveMode, 0);
}

/*
** Bind parameters on a prepared statement.
**
** Parameter bindings are taken from a TEMP table of the form:
**
**    CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value)
**    WITHOUT ROWID;
**
** No bindings occur if this table does not exist.  The name of the table
** begins with "sqlite_" so that it will not collide with ordinary application
** tables.  The table must be in the TEMP schema.
** No bindings occur if this table does not exist.  The special character '$'
** is included in the table name to help prevent collisions with actual tables.
** The table must be in the TEMP schema.
*/
static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
  int nVar;
  int i;
  int rc;
  sqlite3_stmt *pQ = 0;

2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
2803
2804
2805
2806
2807
2808
2809




































































































































































































































2810
2811
2812
2813
2814
2815
2816
2817
2818









2819
2820
2821
2822
2823
2824
2825







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









-
-
-
-
-
-
-
-
-







      sqlite3_bind_null(pStmt, i);
    }
    sqlite3_reset(pQ);
  }
  sqlite3_finalize(pQ);
}

/*
** UTF8 box-drawing characters.  Imagine box lines like this:
**
**           1
**           |
**       4 --+-- 2
**           |
**           3
**
** Each box characters has between 2 and 4 of the lines leading from
** the center.  The characters are here identified by the numbers of
** their corresponding lines.
*/
#define BOX_24   "\342\224\200"  /* U+2500 --- */
#define BOX_13   "\342\224\202"  /* U+2502  |  */
#define BOX_23   "\342\224\214"  /* U+250c  ,- */
#define BOX_34   "\342\224\220"  /* U+2510 -,  */
#define BOX_12   "\342\224\224"  /* U+2514  '- */
#define BOX_14   "\342\224\230"  /* U+2518 -'  */
#define BOX_123  "\342\224\234"  /* U+251c  |- */
#define BOX_134  "\342\224\244"  /* U+2524 -|  */
#define BOX_234  "\342\224\254"  /* U+252c -,- */
#define BOX_124  "\342\224\264"  /* U+2534 -'- */
#define BOX_1234 "\342\224\274"  /* U+253c -|- */

/* Draw horizontal line N characters long using unicode box
** characters
*/
static void print_box_line(FILE *out, int N){
  const char zDash[] = 
      BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
      BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
  const int nDash = sizeof(zDash) - 1;
  N *= 3;
  while( N>nDash ){
    utf8_printf(out, zDash);
    N -= nDash;
  }
  utf8_printf(out, "%.*s", N, zDash);
}

/*
** Draw a horizontal separator for a MODE_Box table.
*/
static void print_box_row_separator(
  ShellState *p,
  int nArg,
  const char *zSep1,
  const char *zSep2,
  const char *zSep3
){
  int i;
  if( nArg>0 ){
    utf8_printf(p->out, "%s", zSep1);
    print_box_line(p->out, p->actualWidth[0]+2);
    for(i=1; i<nArg; i++){
      utf8_printf(p->out, "%s", zSep2);
      print_box_line(p->out, p->actualWidth[i]+2);
    }
    utf8_printf(p->out, "%s", zSep3);
  }
  fputs("\n", p->out);
}



/*
** Run a prepared statement and output the result in one of the
** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
** or MODE_Box.
**
** This is different from ordinary exec_prepared_stmt() in that
** it has to run the entire query and gather the results into memory
** first, in order to determine column widths, before providing
** any output.
*/
static void exec_prepared_stmt_columnar(
  ShellState *p,                        /* Pointer to ShellState */
  sqlite3_stmt *pStmt                   /* Statment to run */
){
  sqlite3_int64 nRow = 0;
  int nColumn = 0;
  char **azData = 0;
  sqlite3_int64 nAlloc = 0;
  const char *z;
  int rc;
  sqlite3_int64 i, nData;
  int j, nTotal, w, n;
  const char *colSep = 0;
  const char *rowSep = 0;

  rc = sqlite3_step(pStmt);
  if( rc!=SQLITE_ROW ) return;
  nColumn = sqlite3_column_count(pStmt);
  nAlloc = nColumn*4;
  if( nAlloc<=0 ) nAlloc = 1;
  azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
  if( azData==0 ) shell_out_of_memory();
  for(i=0; i<nColumn; i++){
    azData[i] = strdup(sqlite3_column_name(pStmt,i));
  }
  do{
    if( (nRow+2)*nColumn >= nAlloc ){
      nAlloc *= 2;
      azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
      if( azData==0 ) shell_out_of_memory();
    }
    nRow++;
    for(i=0; i<nColumn; i++){
      z = (const char*)sqlite3_column_text(pStmt,i);
      azData[nRow*nColumn + i] = z ? strdup(z) : 0;
    }
  }while( (rc = sqlite3_step(pStmt))==SQLITE_ROW );
  if( nColumn>p->nWidth ){
    p->colWidth = realloc(p->colWidth, nColumn*2*sizeof(int));
    if( p->colWidth==0 ) shell_out_of_memory();
    for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
    p->nWidth = nColumn;
    p->actualWidth = &p->colWidth[nColumn];
  }
  memset(p->actualWidth, 0, nColumn*sizeof(int));
  for(i=0; i<nColumn; i++){
    w = p->colWidth[i];
    if( w<0 ) w = -w;
    p->actualWidth[i] = w;
  }
  nTotal = nColumn*(nRow+1);
  for(i=0; i<nTotal; i++){
    z = azData[i];
    if( z==0 ) z = p->nullValue;
    n = strlenChar(z);
    j = i%nColumn;
    if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
  }
  if( seenInterrupt ) goto columnar_end;
  if( nColumn==0 ) goto columnar_end;
  switch( p->cMode ){
    case MODE_Column: {
      colSep = "  ";
      rowSep = "\n";
      if( p->showHeader ){
        for(i=0; i<nColumn; i++){
          w = p->actualWidth[i];
          if( p->colWidth[i]<0 ) w = -w;
          utf8_width_print(p->out, w, azData[i]);
          fputs(i==nColumn-1?"\n":"  ", p->out);
        }
        for(i=0; i<nColumn; i++){
          print_dashes(p->out, p->actualWidth[i]);
          fputs(i==nColumn-1?"\n":"  ", p->out);
        }
      }
      break;
    }
    case MODE_Table: {
      colSep = " | ";
      rowSep = " |\n";
      print_row_separator(p, nColumn, "+");
      fputs("| ", p->out);
      for(i=0; i<nColumn; i++){
        w = p->actualWidth[i];
        n = strlenChar(azData[i]);
        utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
        fputs(i==nColumn-1?" |\n":" | ", p->out);
      }
      print_row_separator(p, nColumn, "+");
      break;
    }
    case MODE_Markdown: {
      colSep = " | ";
      rowSep = " |\n";
      fputs("| ", p->out);
      for(i=0; i<nColumn; i++){
        w = p->actualWidth[i];
        n = strlenChar(azData[i]);
        utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
        fputs(i==nColumn-1?" |\n":" | ", p->out);
      }
      print_row_separator(p, nColumn, "|");
      break;
    }
    case MODE_Box: {
      colSep = " " BOX_13 " ";
      rowSep = " " BOX_13 "\n";
      print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34);
      utf8_printf(p->out, BOX_13 " ");
      for(i=0; i<nColumn; i++){
        w = p->actualWidth[i];
        n = strlenChar(azData[i]);
        utf8_printf(p->out, "%*s%s%*s%s",
            (w-n)/2, "", azData[i], (w-n+1)/2, "",
            i==nColumn-1?" "BOX_13"\n":" "BOX_13" ");
      }
      print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
      break;
    }
  }
  for(i=nColumn, j=0; i<nTotal; i++, j++){
    if( j==0 && p->cMode!=MODE_Column ){
      utf8_printf(p->out, "%s", p->cMode==MODE_Box?BOX_13" ":"| ");
    }
    z = azData[i];
    if( z==0 ) z = p->nullValue;
    w = p->actualWidth[j];
    if( p->colWidth[j]<0 ) w = -w;
    utf8_width_print(p->out, w, z);
    if( j==nColumn-1 ){
      utf8_printf(p->out, "%s", rowSep);
      j = -1;
      if( seenInterrupt ) goto columnar_end;
    }else{
      utf8_printf(p->out, "%s", colSep);
    }
  }
  if( p->cMode==MODE_Table ){
    print_row_separator(p, nColumn, "+");
  }else if( p->cMode==MODE_Box ){
    print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14);
  }
columnar_end:
  if( seenInterrupt ){
    utf8_printf(p->out, "Interrupt\n");
  }
  nData = (nRow+1)*nColumn;
  for(i=0; i<nData; i++) free(azData[i]);
  sqlite3_free(azData);
}

/*
** Run a prepared statement
*/
static void exec_prepared_stmt(
  ShellState *pArg,                                /* Pointer to ShellState */
  sqlite3_stmt *pStmt                              /* Statment to run */
){
  int rc;

  if( pArg->cMode==MODE_Column
   || pArg->cMode==MODE_Table
   || pArg->cMode==MODE_Box
   || pArg->cMode==MODE_Markdown
  ){
    exec_prepared_stmt_columnar(pArg, pStmt);
    return;
  }

  /* perform the first step.  this will tell us if we
  ** have a result set or not and how wide it is.
  */
  rc = sqlite3_step(pStmt);
  /* if we have a result set... */
  if( SQLITE_ROW == rc ){
    /* allocate space for col name ptr, value ptr, and type */
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
2859
2860
2861
2862
2863
2864
2865



2866
2867
2868
2869
2870
2871
2872







-
-
-







            rc = SQLITE_ABORT;
          }else{
            rc = sqlite3_step(pStmt);
          }
        }
      } while( SQLITE_ROW == rc );
      sqlite3_free(pData);
      if( pArg->cMode==MODE_Json ){
        fputs("]\n", pArg->out);
      }
    }
  }
}

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** This function is called to process SQL if the previous shell command
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3071
3072
3073
3074
3075
3076
3077

3078
3079
3080
3081
3082
3083
3084







-







        zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
        rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
        if( rc==SQLITE_OK ){
          while( sqlite3_step(pExplain)==SQLITE_ROW ){
            const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
            int iEqpId = sqlite3_column_int(pExplain, 0);
            int iParentId = sqlite3_column_int(pExplain, 1);
            if( zEQPLine==0 ) zEQPLine = "";
            if( zEQPLine[0]=='-' ) eqp_render(pArg);
            eqp_append(pArg, iEqpId, iParentId, zEQPLine);
          }
          eqp_render(pArg);
        }
        sqlite3_finalize(pExplain);
        sqlite3_free(zEQP);
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
3298
3299
3300
3301
3302
3303
3304


3305
3306
3307
3308
3309
3310


3311




3312
3313
3314
3315
3316
3317


3318
3319
3320
3321
3322
3323
3324

3325
3326
3327
3328
3329
3330
3331
3332







-
-






-
-

-
-
-
-
+
+
+
+


-
-







-
+







*/
static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
  int rc;
  const char *zTable;
  const char *zType;
  const char *zSql;
  ShellState *p = (ShellState *)pArg;
  int dataOnly;
  int noSys;

  UNUSED_PARAMETER(azNotUsed);
  if( nArg!=3 || azArg==0 ) return 0;
  zTable = azArg[0];
  zType = azArg[1];
  zSql = azArg[2];
  dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0;
  noSys    = (p->shellFlgs & SHFLG_DumpNoSys)!=0;

  if( strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
    if( !dataOnly ) raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
  }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
    if( !dataOnly ) raw_printf(p->out, "ANALYZE sqlite_schema;\n");
  if( strcmp(zTable, "sqlite_sequence")==0 ){
    raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
  }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
    raw_printf(p->out, "ANALYZE sqlite_master;\n");
  }else if( strncmp(zTable, "sqlite_", 7)==0 ){
    return 0;
  }else if( dataOnly ){
    /* no-op */
  }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
    char *zIns;
    if( !p->writableSchema ){
      raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
      p->writableSchema = 1;
    }
    zIns = sqlite3_mprintf(
       "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
       "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
       "VALUES('table','%q','%q',0,'%q');",
       zTable, zTable, zSql);
    utf8_printf(p->out, "%s\n", zIns);
    sqlite3_free(zIns);
    return 0;
  }else{
    printSchemaLine(p->out, zSql, ";\n");
3857
3858
3859
3860
3861
3862
3863
3864
3865


3866
3867
3868
3869
3870
3871
3872



3873
3874
3875
3876
3877



3878
3879
3880
3881
3882
3883
3884
3885
3886

3887
3888
3889
3890
3891
3892
3893
3894
3895
3896

3897
3898

3899
3900
3901
3902

3903
3904
3905
3906
3907
3908
3909

3910
3911
3912

3913
3914
3915
3916




3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955

3956
3957
3958
3959
3960




3961
3962
3963


3964
3965

3966
3967
3968


3969
3970

3971
3972
3973
3974



3975
3976
3977
3978
3979
3980
3981
3982
3983

3984
3985
3986
3987
3988
3989
3990
3991

3992
3993
3994
3995
3996
3997
3998
3999
4000
4001

4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027


4028
4029
4030
4031
4032
4033
4034
4035
3449
3450
3451
3452
3453
3454
3455


3456
3457
3458
3459
3460
3461



3462
3463
3464
3465
3466



3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477

3478
3479
3480
3481
3482
3483
3484
3485
3486
3487

3488
3489

3490
3491



3492

3493
3494
3495
3496
3497

3498
3499
3500

3501

3502


3503
3504
3505
3506



3507
3508
3509
3510












3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529

3530





3531
3532
3533
3534



3535
3536


3537



3538
3539
3540

3541
3542



3543
3544
3545



3546
3547
3548
3549
3550

3551
3552
3553
3554

3555
3556
3557

3558




3559
3560
3561
3562
3563

3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576








3577
3578
3579
3580


3581
3582

3583
3584
3585
3586
3587
3588
3589







-
-
+
+




-
-
-
+
+
+


-
-
-
+
+
+








-
+









-
+

-
+

-
-
-
+
-





-
+


-
+
-

-
-
+
+
+
+
-
-
-




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



















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

-
+

-
-
-
+
+
+
-
-
-





-
+



-



-
+
-
-
-
-





-
+












-
-
-
-
-
-
-
-




-
-
+
+
-







** start of the description of what that command does.
*/
static const char *(azHelp[]) = {
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
  ".archive ...             Manage SQL archives",
  "   Each command must have exactly one of the following options:",
  "     -c, --create               Create a new archive",
  "     -u, --update               Add or update files with changed mtime",
  "     -i, --insert               Like -u but always add even if unchanged",
  "     -u, --update               Add files or update files with changed mtime",
  "     -i, --insert               Like -u but always add even if mtime unchanged",
  "     -t, --list                 List contents of archive",
  "     -x, --extract              Extract files from archive",
  "   Optional arguments:",
  "     -v, --verbose              Print each filename as it is processed",
  "     -f FILE, --file FILE       Use archive FILE (default is current db)",
  "     -a FILE, --append FILE     Open FILE using the apndvfs VFS",
  "     -C DIR, --directory DIR    Read/extract files from directory DIR",
  "     -f FILE, --file FILE       Operate on archive FILE (default is current db)",
  "     -a FILE, --append FILE     Operate on FILE opened using the apndvfs VFS",
  "     -C DIR, --directory DIR    Change to directory DIR to read/extract files",
  "     -n, --dryrun               Show the SQL that would have occurred",
  "   Examples:",
  "     .ar -cf ARCHIVE foo bar  # Create ARCHIVE from files foo and bar",
  "     .ar -tf ARCHIVE          # List members of ARCHIVE",
  "     .ar -xvf ARCHIVE         # Verbosely extract files from ARCHIVE",
  "     .ar -cf archive.sar foo bar  # Create archive.sar from files foo and bar",
  "     .ar -tf archive.sar          # List members of archive.sar",
  "     .ar -xvf archive.sar         # Verbosely extract files from archive.sar",
  "   See also:",
  "      http://sqlite.org/cli.html#sqlar_archive_support",
#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
  ".auth ON|OFF             Show authorizer callbacks",
#endif
  ".backup ?DB? FILE        Backup DB (default \"main\") to FILE",
  "       --append            Use the appendvfs",
  "       --async             Write to FILE without journal and fsync()",
  "       --async             Write to FILE without a journal and without fsync()",
  ".bail on|off             Stop after hitting an error.  Default OFF",
  ".binary on|off           Turn binary output on or off.  Default OFF",
  ".cd DIRECTORY            Change the working directory to DIRECTORY",
  ".changes on|off          Show number of rows changed by SQL",
  ".check GLOB              Fail if output since .testcase does not match",
  ".clone NEWDB             Clone data into NEWDB from the existing database",
  ".databases               List names and files of attached databases",
  ".dbconfig ?op? ?val?     List or change sqlite3_db_config() options",
  ".dbinfo ?DB?             Show status information about the database",
  ".dump ?OBJECTS?          Render database content as SQL",
  ".dump ?TABLE? ...        Render all database content as SQL",
  "   Options:",
  "     --data-only            Output only INSERT statements",
  "     --preserve-rowids      Include ROWID values in the output",
  "     --newlines             Allow unescaped newline characters in output",
  "     --nosys                Omit system tables (ex: \"sqlite_stat1\")",
  "     --preserve-rowids      Include ROWID values in the output",
  "   OBJECTS is a LIKE pattern for tables, indexes, triggers or views to dump",
  "   TABLE is LIKE pattern for the tables to dump",
  "   Additional LIKE patterns can be given in subsequent arguments",
  ".echo on|off             Turn command echo on or off",
  ".eqp on|off|full|...     Enable or disable automatic EXPLAIN QUERY PLAN",
  "   Other Modes:",
#ifdef SQLITE_DEBUG
  "      test                  Show raw EXPLAIN QUERY PLAN output",
  "      trace                 Like \"full\" but enable \"PRAGMA vdbe_trace\"",
  "      trace                 Like \"full\" but also enable \"PRAGMA vdbe_trace\"",
#endif
  "      trigger               Like \"full\" but also show trigger bytecode",
  ".excel                   Display the output of next command in spreadsheet",
  ".excel                   Display the output of next command in a spreadsheet",
  "   --bom                   Put a UTF8 byte-order mark on intermediate file",
  ".exit ?CODE?             Exit this program with return-code CODE",
  ".expert                  EXPERIMENTAL. Suggest indexes for queries",
  ".explain ?on|off|auto?   Change the EXPLAIN formatting mode.  Default: auto",
  ".expert                  EXPERIMENTAL. Suggest indexes for specified queries",
/* Because explain mode comes on automatically now, the ".explain" mode
** is removed from the help screen.  It is still supported for legacy, however */
/*".explain ?on|off|auto?   Turn EXPLAIN output mode on or off or to automatic",*/
  ".filectrl CMD ...        Run various sqlite3_file_control() operations",
  "   --schema SCHEMA         Use SCHEMA instead of \"main\"",
  "   --help                  Show CMD details",
  ".fullschema ?--indent?   Show schema and the content of sqlite_stat tables",
  ".headers on|off          Turn display of headers on or off",
  ".help ?-all? ?PATTERN?   Show help text for PATTERN",
  ".import FILE TABLE       Import data from FILE into TABLE",
  "   Options:",
  "     --ascii               Use \\037 and \\036 as column and row separators",
  "     --csv                 Use , and \\n as column and row separators",
  "     --skip N              Skip the first N rows of input",
  "     -v                    \"Verbose\" - increase auxiliary output",
  "   Notes:",
  "     *  If TABLE does not exist, it is created.  The first row of input",
  "        determines the column names.",
  "     *  If neither --csv or --ascii are used, the input mode is derived",
  "        from the \".mode\" output mode",
  "     *  If FILE begins with \"|\" then it is a command that generates the",
  "        input text.",
#ifndef SQLITE_OMIT_TEST_CONTROL
  ".imposter INDEX TABLE    Create imposter table TABLE on index INDEX",
#endif
  ".indexes ?TABLE?         Show names of indexes",
  "                           If TABLE is specified, only show indexes for",
  "                           tables matching TABLE using the LIKE operator.",
#ifdef SQLITE_ENABLE_IOTRACE
  ".iotrace FILE            Enable I/O diagnostic logging to FILE",
#endif
  ".limit ?LIMIT? ?VAL?     Display or change the value of an SQLITE_LIMIT",
  ".lint OPTIONS            Report potential schema issues.",
  "     Options:",
  "        fkey-indexes     Find missing foreign key indexes",
#ifndef SQLITE_OMIT_LOAD_EXTENSION
  ".load FILE ?ENTRY?       Load an extension library",
#endif
  ".log FILE|off            Turn logging on or off.  FILE can be stderr/stdout",
  ".mode MODE ?TABLE?       Set output mode",
  "   MODE is one of:",
  "     ascii     Columns/rows delimited by 0x1F and 0x1E",
  "     ascii    Columns/rows delimited by 0x1F and 0x1E",
  "     box       Tables using unicode box-drawing characters",
  "     csv       Comma-separated values",
  "     column    Output in columns.  (See .width)",
  "     html      HTML <table> code",
  "     insert    SQL insert statements for TABLE",
  "     csv      Comma-separated values",
  "     column   Left-aligned columns.  (See .width)",
  "     html     HTML <table> code",
  "     insert   SQL insert statements for TABLE",
  "     json      Results in a JSON array",
  "     line      One value per line",
  "     list      Values delimited by \"|\"",
  "     line     One value per line",
  "     list     Values delimited by \"|\"",
  "     markdown  Markdown table format",
  "     quote     Escape answers as for SQL",
  "     quote    Escape answers as for SQL",
  "     table     ASCII-art table",
  "     tabs      Tab-separated values",
  "     tcl       TCL list elements",
  "     tabs     Tab-separated values",
  "     tcl      TCL list elements",
  ".nullvalue STRING        Use STRING in place of NULL values",
  ".once ?OPTIONS? ?FILE?   Output for the next SQL command only to FILE",
  ".once (-e|-x|FILE)       Output for the next SQL command only to FILE",
  "     If FILE begins with '|' then open as a pipe",
  "       --bom  Put a UTF8 byte-order mark at the beginning",
  "       -e     Send output to the system text editor",
  "       -x     Send output as CSV to a spreadsheet (same as \".excel\")",
  "     Other options:",
  "       -e    Invoke system text editor",
  "       -x    Open in a spreadsheet",
#ifdef SQLITE_DEBUG
  ".oom ?--repeat M? ?N?    Simulate an OOM error on the N-th allocation",
#endif 
  ".open ?OPTIONS? ?FILE?   Close existing database and reopen FILE",
  "     Options:",
  "        --append        Use appendvfs to append database to the end of FILE",
#ifdef SQLITE_ENABLE_DESERIALIZE
  "        --deserialize   Load into memory useing sqlite3_deserialize()",
  "        --hexdb         Load the output of \"dbtotxt\" as an in-memory db",
  "        --hexdb         Load the output of \"dbtotxt\" as an in-memory database",
  "        --maxsize N     Maximum size for --hexdb or --deserialized database",
#endif
  "        --new           Initialize FILE to an empty database",
  "        --nofollow      Do not follow symbolic links",
  "        --readonly      Open FILE readonly",
  "        --zip           FILE is a ZIP archive",
  ".output ?FILE?           Send output to FILE or stdout if FILE is omitted",
  "   If FILE begins with '|' then open it as a pipe.",
  "     If FILE begins with '|' then open it as a pipe.",
  "   Options:",
  "     --bom                 Prefix output with a UTF8 byte-order mark",
  "     -e                    Send output to the system text editor",
  "     -x                    Send output as CSV to a spreadsheet",
  ".parameter CMD ...       Manage SQL parameter bindings",
  "   clear                   Erase all bindings",
  "   init                    Initialize the TEMP table that holds bindings",
  "   list                    List the current parameter bindings",
  "   set PARAMETER VALUE     Given SQL parameter PARAMETER a value of VALUE",
  "                           PARAMETER should start with one of: $ : @ ?",
  "                           PARAMETER should start with '$', ':', '@', or '?'",
  "   unset PARAMETER         Remove PARAMETER from the binding table",
  ".print STRING...         Print literal STRING",
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  ".progress N              Invoke progress handler after every N opcodes",
  "   --limit N                 Interrupt after N progress callbacks",
  "   --once                    Do no more than one progress interrupt",
  "   --quiet|-q                No output except at interrupts",
  "   --reset                   Reset the count for each input and interrupt",
#endif
  ".prompt MAIN CONTINUE    Replace the standard prompts",
  ".quit                    Exit this program",
  ".read FILE               Read input from FILE",
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  ".recover                 Recover as much data as possible from corrupt db.",
  "   --freelist-corrupt       Assume the freelist is corrupt",
  "   --recovery-db NAME       Store recovery metadata in database file NAME",
  "   --lost-and-found TABLE   Alternative name for the lost-and-found table",
  "   --no-rowids              Do not attempt to recover rowid values",
  "                            that are not also INTEGER PRIMARY KEYs",
#endif
  ".restore ?DB? FILE       Restore content of DB (default \"main\") from FILE",
  ".save FILE               Write in-memory database into FILE",
  ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
  ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
  "   Options:",
  "      --indent             Try to pretty-print the schema",
  "     Options:",
  "         --indent            Try to pretty-print the schema",
  "      --nosys              Omit objects whose names start with \"sqlite_\"",
  ".selftest ?OPTIONS?      Run tests defined in the SELFTEST table",
  "    Options:",
  "       --init               Create a new SELFTEST table",
  "       -v                   Verbose output",
  ".separator COL ?ROW?     Change the column and row separators",
#if defined(SQLITE_ENABLE_SESSION)
  ".session ?NAME? CMD ...  Create or control sessions",
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
4103
4104
4105
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







-
+

-
+







-
+
-
-
-
-





-
-


















-
-
-
-



-
+







  "     list                     List currently open session names",
  "     open DB NAME             Open a new session on DB",
  "     patchset FILE            Write a patchset into FILE",
  "   If ?NAME? is omitted, the first defined session is used.",
#endif
  ".sha3sum ...             Compute a SHA3 hash of database content",
  "    Options:",
  "      --schema              Also hash the sqlite_schema table",
  "      --schema              Also hash the sqlite_master table",
  "      --sha3-224            Use the sha3-224 algorithm",
  "      --sha3-256            Use the sha3-256 algorithm (default)",
  "      --sha3-256            Use the sha3-256 algorithm.  This is the default.",
  "      --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",
  ".stats ?on|off?          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",
  ".timeout MS              Try opening locked tables for MS milliseconds",
  ".timer on|off            Turn SQL timer on or off",
#ifndef SQLITE_OMIT_TRACE
  ".trace ?OPTIONS?         Output each SQL statement as it is run",
  "    FILE                    Send output to FILE",
  "    stdout                  Send output to stdout",
  "    stderr                  Send output to stderr",
  "    off                     Disable tracing",
  "    --expanded              Expand query parameters",
#ifdef SQLITE_ENABLE_NORMALIZE
  "    --normalized            Normal the SQL statements",
#endif
  "    --plain                 Show SQL as it is input",
  "    --stmt                  Trace statement execution (SQLITE_TRACE_STMT)",
  "    --profile               Profile statements (SQLITE_TRACE_PROFILE)",
  "    --row                   Trace each row (SQLITE_TRACE_ROW)",
  "    --close                 Trace connection close (SQLITE_TRACE_CLOSE)",
#endif /* SQLITE_OMIT_TRACE */
#ifdef SQLITE_DEBUG
  ".unmodule NAME ...       Unregister virtual table modules",
  "    --allexcept             Unregister everything except those named",
#endif
  ".vfsinfo ?AUX?           Information about the top-level VFS",
  ".vfslist                 List all available VFSes",
  ".vfsname ?AUX?           Print the name of the VFS stack",
  ".width NUM1 NUM2 ...     Set minimum column widths for columnar output",
  ".width NUM1 NUM2 ...     Set column widths for \"column\" mode",
  "     Negative values right-justify",
};

/*
** Output help text.
**
** zPattern describes the set of commands for which help text is provided.
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
3657
3658
3659
3660
3661
3662
3663

3664
3665
3666
3667
3668
3669
3670







-







  int j = 0;
  int n = 0;
  char *zPat;
  if( zPattern==0
   || zPattern[0]=='0'
   || strcmp(zPattern,"-a")==0
   || strcmp(zPattern,"-all")==0
   || strcmp(zPattern,"--all")==0
  ){
    /* Show all commands, but only one line per command */
    if( zPattern==0 ) zPattern = "";
    for(i=0; i<ArraySize(azHelp); i++){
      if( azHelp[i][0]=='.' || zPattern[0] ){
        utf8_printf(out, "%s\n", azHelp[i]);
        n++;
4311
4312
4313
4314
4315
4316
4317
4318

4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337

4338
4339
4340

4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359


4360
4361
4362
4363
4364
4365

4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379

4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
3854
3855
3856
3857
3858
3859
3860

3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872

3873
3874
3875
3876
3877
3878

3879



3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898

3899
3900
3901
3902
3903
3904
3905

3906

3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918

3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
























































































































































3934
3935
3936
3937
3938
3939
3940







-
+











-






-
+
-
-
-
+


















-
+
+





-
+
-












-
+














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







  int nLine;
  int n = 0;
  int pgsz = 0;
  int iOffset = 0;
  int j, k;
  int rc;
  FILE *in;
  unsigned int x[16];
  unsigned char x[16];
  char zLine[1000];
  if( p->zDbFilename ){
    in = fopen(p->zDbFilename, "r");
    if( in==0 ){
      utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
      return 0;
    }
    nLine = 0;
  }else{
    in = p->in;
    nLine = p->lineno;
    if( in==0 ) in = stdin;
  }
  *pnData = 0;
  nLine++;
  if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
  rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
  if( rc!=2 ) goto readHexDb_error;
  if( n<0 ) goto readHexDb_error;
  if( n<=0 ) goto readHexDb_error;
  if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
  n = (n+pgsz-1)&~(pgsz-1);  /* Round n up to the next multiple of pgsz */
  a = sqlite3_malloc( n ? n : 1 );
  a = sqlite3_malloc( n );
  if( a==0 ){
    utf8_printf(stderr, "Out of memory!\n");
    goto readHexDb_error;
  }
  memset(a, 0, n);
  if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
    utf8_printf(stderr, "invalid pagesize\n");
    goto readHexDb_error;
  }
  for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){
    rc = sscanf(zLine, "| page %d offset %d", &j, &k);
    if( rc==2 ){
      iOffset = k;
      continue;
    }
    if( strncmp(zLine, "| end ", 6)==0 ){
      break;
    }
    rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
    rc = sscanf(zLine,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
                      "  %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
                &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
                &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
    if( rc==17 ){
      k = iOffset+j;
      if( k+16<=n ){
        int ii;
        memcpy(a+k, x, 16);
        for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
      }
    }
  }
  *pnData = n;
  if( in!=p->in ){
    fclose(in);
  }else{
    p->lineno = nLine;
  }
  return a;

readHexDb_error:
  if( in!=p->in ){
  if( in!=stdin ){
    fclose(in);
  }else{
    while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
      nLine++;
      if(strncmp(zLine, "| end ", 6)==0 ) break;
    }
    p->lineno = nLine;
  }
  sqlite3_free(a);
  utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
  return 0;
}
#endif /* SQLITE_ENABLE_DESERIALIZE */

/*
** Scalar function "shell_int32". The first argument to this function
** must be a blob. The second a non-negative integer. This function
** reads and returns a 32-bit big-endian integer from byte
** offset (4*<arg2>) of the blob.
*/
static void shellInt32(
  sqlite3_context *context, 
  int argc, 
  sqlite3_value **argv
){
  const unsigned char *pBlob;
  int nBlob;
  int iInt;

  UNUSED_PARAMETER(argc);
  nBlob = sqlite3_value_bytes(argv[0]);
  pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
  iInt = sqlite3_value_int(argv[1]);

  if( iInt>=0 && (iInt+1)*4<=nBlob ){
    const unsigned char *a = &pBlob[iInt*4];
    sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24)
                       + ((sqlite3_int64)a[1]<<16)
                       + ((sqlite3_int64)a[2]<< 8)
                       + ((sqlite3_int64)a[3]<< 0);
    sqlite3_result_int64(context, iVal);
  }
}

/*
** Scalar function "shell_idquote(X)" returns string X quoted as an identifier,
** using "..." with internal double-quote characters doubled.
*/
static void shellIdQuote(
  sqlite3_context *context, 
  int argc, 
  sqlite3_value **argv
){
  const char *zName = (const char*)sqlite3_value_text(argv[0]);
  UNUSED_PARAMETER(argc);
  if( zName ){
    char *z = sqlite3_mprintf("\"%w\"", zName);
    sqlite3_result_text(context, z, -1, sqlite3_free);
  }
}

/*
** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
*/
static void shellUSleepFunc(
  sqlite3_context *context, 
  int argcUnused, 
  sqlite3_value **argv
){
  int sleep = sqlite3_value_int(argv[0]);
  (void)argcUnused;
  sqlite3_sleep(sleep/1000);
  sqlite3_result_int(context, sleep);
}

/*
** Scalar function "shell_escape_crnl" used by the .recover command.
** The argument passed to this function is the output of built-in
** function quote(). If the first character of the input is "'", 
** indicating that the value passed to quote() was a text value,
** then this function searches the input for "\n" and "\r" characters
** and adds a wrapper similar to the following:
**
**   replace(replace(<input>, '\n', char(10), '\r', char(13));
**
** Or, if the first character of the input is not "'", then a copy
** of the input is returned.
*/
static void shellEscapeCrnl(
  sqlite3_context *context, 
  int argc, 
  sqlite3_value **argv
){
  const char *zText = (const char*)sqlite3_value_text(argv[0]);
  UNUSED_PARAMETER(argc);
  if( zText[0]=='\'' ){
    int nText = sqlite3_value_bytes(argv[0]);
    int i;
    char zBuf1[20];
    char zBuf2[20];
    const char *zNL = 0;
    const char *zCR = 0;
    int nCR = 0;
    int nNL = 0;

    for(i=0; zText[i]; i++){
      if( zNL==0 && zText[i]=='\n' ){
        zNL = unused_string(zText, "\\n", "\\012", zBuf1);
        nNL = (int)strlen(zNL);
      }
      if( zCR==0 && zText[i]=='\r' ){
        zCR = unused_string(zText, "\\r", "\\015", zBuf2);
        nCR = (int)strlen(zCR);
      }
    }

    if( zNL || zCR ){
      int iOut = 0;
      i64 nMax = (nNL > nCR) ? nNL : nCR;
      i64 nAlloc = nMax * nText + (nMax+64)*2;
      char *zOut = (char*)sqlite3_malloc64(nAlloc);
      if( zOut==0 ){
        sqlite3_result_error_nomem(context);
        return;
      }

      if( zNL && zCR ){
        memcpy(&zOut[iOut], "replace(replace(", 16);
        iOut += 16;
      }else{
        memcpy(&zOut[iOut], "replace(", 8);
        iOut += 8;
      }
      for(i=0; zText[i]; i++){
        if( zText[i]=='\n' ){
          memcpy(&zOut[iOut], zNL, nNL);
          iOut += nNL;
        }else if( zText[i]=='\r' ){
          memcpy(&zOut[iOut], zCR, nCR);
          iOut += nCR;
        }else{
          zOut[iOut] = zText[i];
          iOut++;
        }
      }

      if( zNL ){
        memcpy(&zOut[iOut], ",'", 2); iOut += 2;
        memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
        memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
      }
      if( zCR ){
        memcpy(&zOut[iOut], ",'", 2); iOut += 2;
        memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
        memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
      }

      sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
      sqlite3_free(zOut);
      return;
    }
  }

  sqlite3_result_value(context, argv[0]);
}

/* Flags for open_db().
**
** The default behavior of open_db() is to exit(1) if the database fails to
** open.  The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
** but still returns without calling exit.
**
** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a
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
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
3957
3958
3959
3960
3961
3962
3963

3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976

3977

3978
3979
3980
3981

3982

3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001







4002
4003
4004
4005
4006
4007
4008
4009
4010
4011








4012
4013
4014
4015
4016
4017
4018







-
+












-
+
-




-
+
-



















-
-
-
-
-
-
-










-
-
-
-
-
-
-
-







        p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 
                             (openFlags & OPEN_DB_ZIPFILE)!=0);
      }
    }
    switch( p->openMode ){
      case SHELL_OPEN_APPENDVFS: {
        sqlite3_open_v2(p->zDbFilename, &p->db, 
           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs");
           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
        break;
      }
      case SHELL_OPEN_HEXDB:
      case SHELL_OPEN_DESERIALIZE: {
        sqlite3_open(0, &p->db);
        break;
      }
      case SHELL_OPEN_ZIPFILE: {
        sqlite3_open(":memory:", &p->db);
        break;
      }
      case SHELL_OPEN_READONLY: {
        sqlite3_open_v2(p->zDbFilename, &p->db,
        sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0);
            SQLITE_OPEN_READONLY|p->openFlags, 0);
        break;
      }
      case SHELL_OPEN_UNSPEC:
      case SHELL_OPEN_NORMAL: {
        sqlite3_open_v2(p->zDbFilename, &p->db,
        sqlite3_open(p->zDbFilename, &p->db);
           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
        break;
      }
    }
    globalDb = p->db;
    if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
      utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
          p->zDbFilename, sqlite3_errmsg(p->db));
      if( openFlags & OPEN_DB_KEEPALIVE ){
        sqlite3_open(":memory:", &p->db);
        return;
      }
      exit(1);
    }
#ifndef SQLITE_OMIT_LOAD_EXTENSION
    sqlite3_enable_load_extension(p->db, 1);
#endif
    sqlite3_fileio_init(p->db, 0, 0);
    sqlite3_shathree_init(p->db, 0, 0);
    sqlite3_completion_init(p->db, 0, 0);
    sqlite3_uint_init(p->db, 0, 0);
    sqlite3_decimal_init(p->db, 0, 0);
    sqlite3_ieee_init(p->db, 0, 0);
    sqlite3_series_init(p->db, 0, 0);
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
    sqlite3_dbdata_init(p->db, 0, 0);
#endif
#ifdef SQLITE_HAVE_ZLIB
    sqlite3_zipfile_init(p->db, 0, 0);
    sqlite3_sqlar_init(p->db, 0, 0);
#endif
    sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
                            shellAddSchemaName, 0, 0);
    sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
                            shellModuleSchema, 0, 0);
    sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
                            shellPutsFunc, 0, 0);
    sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0,
                            shellEscapeCrnl, 0, 0);
    sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
                            shellInt32, 0, 0);
    sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
                            shellIdQuote, 0, 0);
    sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
                            shellUSleepFunc, 0, 0);
#ifndef SQLITE_NOHAVE_SYSTEM
    sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
                            editFunc, 0, 0);
    sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
                            editFunc, 0, 0);
#endif
    if( p->openMode==SHELL_OPEN_ZIPFILE ){
4657
4658
4659
4660
4661
4662
4663

4664
4665
4666
4667
4668
4669
4670
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042







+







      int nData = 0;
      unsigned char *aData;
      if( p->openMode==SHELL_OPEN_DESERIALIZE ){
        aData = (unsigned char*)readFile(p->zDbFilename, &nData);
      }else{
        aData = readHexDb(p, &nData);
        if( aData==0 ){
          utf8_printf(stderr, "Error in hexdb input\n");
          return;
        }
      }
      rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
                   SQLITE_DESERIALIZE_RESIZEABLE |
                   SQLITE_DESERIALIZE_FREEONCLOSE);
      if( rc ){
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
4319
4320
4321
4322
4323
4324
4325

4326
4327
4328
4329


4330
4331
4332
4333
4334
4335










4336
4337
4338
4339
4340
4341
4342







-




-
-






-
-
-
-
-
-
-
-
-
-







/*
** An object used to read a CSV and other files for import.
*/
typedef struct ImportCtx ImportCtx;
struct ImportCtx {
  const char *zFile;  /* Name of the input file */
  FILE *in;           /* Read the CSV text from this input stream */
  int (SQLITE_CDECL *xCloser)(FILE*);      /* Func to close in */
  char *z;            /* Accumulated text for a field */
  int n;              /* Number of bytes in z */
  int nAlloc;         /* Space allocated for z[] */
  int nLine;          /* Current line number */
  int nRow;           /* Number of rows imported */
  int nErr;           /* Number of errors encountered */
  int bNotFirst;      /* True if one or more bytes already read */
  int cTerm;          /* Character that terminated the most recent field */
  int cColSep;        /* The column separator character.  (Usually ",") */
  int cRowSep;        /* The row separator character.  (Usually "\n") */
};

/* Clean up resourced used by an ImportCtx */
static void import_cleanup(ImportCtx *p){
  if( p->in!=0 && p->xCloser!=0 ){
    p->xCloser(p->in);
    p->in = 0;
  }
  sqlite3_free(p->z);
  p->z = 0;
}

/* Append a single byte to z[] */
static void import_append_char(ImportCtx *p, int c){
  if( p->n+1>=p->nAlloc ){
    p->nAlloc += p->nAlloc + 100;
    p->z = sqlite3_realloc64(p->z, p->nAlloc);
    if( p->z==0 ) shell_out_of_memory();
  }
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
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







-
+














-
+







}


/*
** Try to transfer all rows of the schema that match zWhere.  For
** each row, invoke xForEach() on the object defined by that row.
** If an error is encountered while moving forward through the
** sqlite_schema table, try again moving backwards.
** sqlite_master table, try again moving backwards.
*/
static void tryToCloneSchema(
  ShellState *p,
  sqlite3 *newDb,
  const char *zWhere,
  void (*xForEach)(ShellState*,sqlite3*,const char*)
){
  sqlite3_stmt *pQuery = 0;
  char *zQuery = 0;
  int rc;
  const unsigned char *zName;
  const unsigned char *zSql;
  char *zErrMsg = 0;

  zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
  zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
                           " WHERE %s", zWhere);
  rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
  if( rc ){
    utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
                    sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
                    zQuery);
    goto end_schema_xfer;
5260
5261
5262
5263
5264
5265
5266
5267

5268
5269
5270
5271
5272
5273
5274
4619
4620
4621
4622
4623
4624
4625

4626
4627
4628
4629
4630
4631
4632
4633







-
+







      xForEach(p, newDb, (const char*)zName);
    }
    printf("done\n");
  }
  if( rc!=SQLITE_DONE ){
    sqlite3_finalize(pQuery);
    sqlite3_free(zQuery);
    zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
    zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
                             " WHERE %s ORDER BY rowid DESC", zWhere);
    rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
    if( rc ){
      utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
                      sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
                      zQuery);
      goto end_schema_xfer;
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
4704
4705
4706
4707
4708
4709
4710





4711
4712
4713
4714
4715
4716
4717







-
-
-
-
-







#else
      "xdg-open";
#endif
      char *zCmd;
      zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
      if( system(zCmd) ){
        utf8_printf(stderr, "Failed: [%s]\n", zCmd);
      }else{
        /* Give the start/open/xdg-open command some time to get
        ** going before we continue, and potential delete the
        ** p->zTempFile data file out from under it */
        sqlite3_sleep(2000);
      }
      sqlite3_free(zCmd);
      outputModePop(p);
      p->doXdgOpen = 0;
    }
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
  }
5386
5387
5388
5389
5390
5391
5392
5393

5394
5395
5396
5397
5398
5399
5400
4740
4741
4742
4743
4744
4745
4746

4747
4748
4749
4750
4751
4752
4753
4754







-
+







  return (a[0]<<8) + a[1];
}
static unsigned int get4byteInt(unsigned char *a){
  return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
}

/*
** Implementation of the ".dbinfo" command.
** Implementation of the ".info" command.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
  static const struct { const char *zName; int ofst; } aField[] = {
     { "file change counter:",  24  },
     { "database page count:",  28  },
5429
5430
5431
5432
5433
5434
5435




5436


5437
5438
5439
5440
5441
5442
5443
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793

4794
4795
4796
4797
4798
4799
4800
4801
4802







+
+
+
+
-
+
+







  unsigned char aHdr[100];
  open_db(p, 0);
  if( p->db==0 ) return 1;
  rc = sqlite3_prepare_v2(p->db,
             "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
             -1, &pStmt, 0);
  if( rc ){
    if( !sqlite3_compileoption_used("ENABLE_DBPAGE_VTAB") ){
      utf8_printf(stderr, "the \".dbinfo\" command requires the "
                          "-DSQLITE_ENABLE_DBPAGE_VTAB compile-time options\n");
    }else{
    utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
      utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
    }
    sqlite3_finalize(pStmt);
    return 1;
  }
  sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
  if( sqlite3_step(pStmt)==SQLITE_ROW
   && sqlite3_column_bytes(pStmt,0)>100
  ){
5464
5465
5466
5467
5468
5469
5470
5471

5472
5473

5474
5475

5476
5477
5478
5479
5480
5481
5482
4823
4824
4825
4826
4827
4828
4829

4830
4831

4832
4833

4834
4835
4836
4837
4838
4839
4840
4841







-
+

-
+

-
+







        if( val==2 ) raw_printf(p->out, " (utf16le)");
        if( val==3 ) raw_printf(p->out, " (utf16be)");
      }
    }
    raw_printf(p->out, "\n");
  }
  if( zDb==0 ){
    zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
    zSchemaTab = sqlite3_mprintf("main.sqlite_master");
  }else if( strcmp(zDb,"temp")==0 ){
    zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
    zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
  }else{
    zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
    zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
  }
  for(i=0; i<ArraySize(aQuery); i++){
    char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
    int val = db_int(p, zSql);
    sqlite3_free(zSql);
    utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
  }
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659

5660
5661
5662
5663
5664
5665
5666
4997
4998
4999
5000
5001
5002
5003



5004
5005










5006
5007
5008
5009
5010
5011
5012
5013







-
-
-


-
-
-
-
-
-
-
-
-
-
+







  clearTempFile(p);
  sqlite3_free(p->zTempFile);
  p->zTempFile = 0;
  if( p->db ){
    sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
  }
  if( p->zTempFile==0 ){
    /* If p->db is an in-memory database then the TEMPFILENAME file-control
    ** will not work and we will need to fallback to guessing */
    char *zTemp;
    sqlite3_uint64 r;
    sqlite3_randomness(sizeof(r), &r);
    zTemp = getenv("TEMP");
    if( zTemp==0 ) zTemp = getenv("TMP");
    if( zTemp==0 ){
#ifdef _WIN32
      zTemp = "\\tmp";
#else
      zTemp = "/tmp";
#endif
    }
    p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
    p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix);
  }else{
    p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
  }
  if( p->zTempFile==0 ){
    raw_printf(stderr, "out of memory\n");
    exit(1);
  }
5790
5791
5792
5793
5794
5795
5796
5797

5798
5799
5800
5801
5802
5803
5804
5137
5138
5139
5140
5141
5142
5143

5144
5145
5146
5147
5148
5149
5150
5151







-
+







    "  || ' ON ' || quote(s.name) || '('"
    "  || group_concat(quote(f.[from]) ||"
    "        fkey_collate_clause("
    "          f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')"
    "  || ');'"
    ", "
    "     f.[table] "
    "FROM sqlite_schema AS s, pragma_foreign_key_list(s.name) AS f "
    "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f "
    "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
    "GROUP BY s.name, f.id "
    "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
  ;
  const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";

  for(i=2; i<nArg; i++){
5912
5913
5914
5915
5916
5917
5918
5919




5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945

5946
5947
5948
5949
5950
5951
5952
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







-
+
+
+
+


















-
-
-
-
-
-
-
-
+







 usage:
  raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
  raw_printf(stderr, "Where sub-commands are:\n");
  raw_printf(stderr, "    fkey-indexes\n");
  return SQLITE_ERROR;
}

#if !defined SQLITE_OMIT_VIRTUALTABLE
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
/*********************************************************************************
** The ".archive" or ".ar" command.
*/
static void shellPrepare(
  sqlite3 *db, 
  int *pRc, 
  const char *zSql, 
  sqlite3_stmt **ppStmt
){
  *ppStmt = 0;
  if( *pRc==SQLITE_OK ){
    int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
    if( rc!=SQLITE_OK ){
      raw_printf(stderr, "sql error: %s (%d)\n", 
          sqlite3_errmsg(db), sqlite3_errcode(db)
      );
      *pRc = rc;
    }
  }
}

/*
** Create a prepared statement using printf-style arguments for the SQL.
**
** This routine is could be marked "static".  But it is not always used,
** depending on compile-time options.  By omitting the "static", we avoid
** nuisance compiler warnings about "defined but not used".
*/
void shellPreparePrintf(
static void shellPreparePrintf(
  sqlite3 *db, 
  int *pRc, 
  sqlite3_stmt **ppStmt,
  const char *zFmt, 
  ...
){
  *ppStmt = 0;
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974

5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996

5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
5304
5305
5306
5307
5308
5309
5310







5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326







5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339






5340
5341
5342
5343
5344
5345
5346







-
-
-
-
-
-
-
+















-
-
-
-
-
-
-
+












-
-
-
-
-
-







    }else{
      shellPrepare(db, pRc, z, ppStmt);
      sqlite3_free(z);
    }
  }
}

/* Finalize the prepared statement created using shellPreparePrintf().
**
** This routine is could be marked "static".  But it is not always used,
** depending on compile-time options.  By omitting the "static", we avoid
** nuisance compiler warnings about "defined but not used".
*/
void shellFinalize(
static void shellFinalize(
  int *pRc, 
  sqlite3_stmt *pStmt
){
  if( pStmt ){
    sqlite3 *db = sqlite3_db_handle(pStmt);
    int rc = sqlite3_finalize(pStmt);
    if( *pRc==SQLITE_OK ){
      if( rc!=SQLITE_OK ){
        raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
      }
      *pRc = rc;
    }
  }
}

/* Reset the prepared statement created using shellPreparePrintf().
**
** This routine is could be marked "static".  But it is not always used,
** depending on compile-time options.  By omitting the "static", we avoid
** nuisance compiler warnings about "defined but not used".
*/
void shellReset(
static void shellReset(
  int *pRc, 
  sqlite3_stmt *pStmt
){
  int rc = sqlite3_reset(pStmt);
  if( *pRc==SQLITE_OK ){
    if( rc!=SQLITE_OK ){
      sqlite3 *db = sqlite3_db_handle(pStmt);
      raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
    }
    *pRc = rc;
  }
}
#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */

#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
/******************************************************************************
** The ".archive" or ".ar" command.
*/
/*
** Structure representing a single ".ar" command.
*/
typedef struct ArCommand ArCommand;
struct ArCommand {
  u8 eCmd;                        /* An AR_CMD_* value */
  u8 bVerbose;                    /* True if --verbose */
6203
6204
6205
6206
6207
6208
6209
6210

6211
6212
6213
6214
6215
6216
6217
6218
5528
5529
5530
5531
5532
5533
5534

5535

5536
5537
5538
5539
5540
5541
5542







-
+
-







            }
            if( pOpt->bArg ){
              if( i<(n-1) ){
                zArg = &z[i+1];
                i = n;
              }else{
                if( iArg>=(nArg-1) ){
                  return arErrorMsg(pAr, "option requires an argument: %c",
                  return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
                                    z[i]);
                }
                zArg = azArg[++iArg];
              }
            }
            if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
          }
        }else if( z[2]=='\0' ){
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602




6603
6604
6605
6606
6607
6608
6609
5916
5917
5918
5919
5920
5921
5922




5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933







-
-
-
-
+
+
+
+







  return rc;
}

/*
** Implementation of ".ar" dot command.
*/
static int arDotCommand(
  ShellState *pState,          /* Current shell tool state */
  int fromCmdLine,             /* True if -A command-line option, not .ar cmd */
  char **azArg,                /* Array of arguments passed to dot command */
  int nArg                     /* Number of entries in azArg[] */
  ShellState *pState,             /* Current shell tool state */
  int fromCmdLine,                /* True if -A command-line option, not .ar cmd */
  char **azArg,                   /* Array of arguments passed to dot command */
  int nArg                        /* Number of entries in azArg[] */
){
  ArCommand cmd;
  int rc;
  memset(&cmd, 0, sizeof(cmd));
  cmd.fromCmdLine = fromCmdLine;
  rc = arParseCommand(azArg, nArg, &cmd);
  if( rc==SQLITE_OK ){
6695
6696
6697
6698
6699
6700
6701
6702

6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
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
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392

7393
7394
7395
7396
7397
7398
7399
7400
7401
7402

7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
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







-
+


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












-
+









-
+




















-







    close_db(cmd.db);
  }
  sqlite3_free(cmd.zSrcTable);

  return rc;
}
/* End of the ".archive" or ".ar" command logic
*******************************************************************************/
**********************************************************************************/
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */

#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
/*
** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op.
** Otherwise, the SQL statement or statements in zSql are executed using
** database connection db and the error code written to *pRc before
** this function returns.
*/
static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
  int rc = *pRc;
  if( rc==SQLITE_OK ){
    char *zErr = 0;
    rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
    if( rc!=SQLITE_OK ){
      raw_printf(stderr, "SQL error: %s\n", zErr);
    }
    *pRc = rc;
  }
}

/*
** Like shellExec(), except that zFmt is a printf() style format string.
*/
static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){
  char *z = 0;
  if( *pRc==SQLITE_OK ){
    va_list ap;
    va_start(ap, zFmt);
    z = sqlite3_vmprintf(zFmt, ap);
    va_end(ap);
    if( z==0 ){
      *pRc = SQLITE_NOMEM;
    }else{
      shellExec(db, pRc, z);
    }
    sqlite3_free(z);
  }
}

/*
** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
** Otherwise, an attempt is made to allocate, zero and return a pointer
** to a buffer nByte bytes in size. If an OOM error occurs, *pRc is set
** to SQLITE_NOMEM and NULL returned.
*/
static void *shellMalloc(int *pRc, sqlite3_int64 nByte){
  void *pRet = 0;
  if( *pRc==SQLITE_OK ){
    pRet = sqlite3_malloc64(nByte);
    if( pRet==0 ){
      *pRc = SQLITE_NOMEM;
    }else{
      memset(pRet, 0, nByte);
    }
  }
  return pRet;
}

/*
** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
** Otherwise, zFmt is treated as a printf() style string. The result of
** formatting it along with any trailing arguments is written into a 
** buffer obtained from sqlite3_malloc(), and pointer to which is returned.
** It is the responsibility of the caller to eventually free this buffer
** using a call to sqlite3_free().
** 
** If an OOM error occurs, (*pRc) is set to SQLITE_NOMEM and a NULL 
** pointer returned.
*/
static char *shellMPrintf(int *pRc, const char *zFmt, ...){
  char *z = 0;
  if( *pRc==SQLITE_OK ){
    va_list ap;
    va_start(ap, zFmt);
    z = sqlite3_vmprintf(zFmt, ap);
    va_end(ap);
    if( z==0 ){
      *pRc = SQLITE_NOMEM;
    }
  }
  return z;
}

/*
** When running the ".recover" command, each output table, and the special
** orphaned row table if it is required, is represented by an instance
** of the following struct.
*/
typedef struct RecoverTable RecoverTable;
struct RecoverTable {
  char *zQuoted;                  /* Quoted version of table name */
  int nCol;                       /* Number of columns in table */
  char **azlCol;                  /* Array of column lists */
  int iPk;                        /* Index of IPK column */
};

/*
** Free a RecoverTable object allocated by recoverFindTable() or
** recoverOrphanTable().
*/
static void recoverFreeTable(RecoverTable *pTab){
  if( pTab ){
    sqlite3_free(pTab->zQuoted);
    if( pTab->azlCol ){
      int i;
      for(i=0; i<=pTab->nCol; i++){
        sqlite3_free(pTab->azlCol[i]);
      }
      sqlite3_free(pTab->azlCol);
    }
    sqlite3_free(pTab);
  }
}

/*
** This function is a no-op if (*pRc) is not SQLITE_OK when it is called.
** Otherwise, it allocates and returns a RecoverTable object based on the
** final four arguments passed to this function. It is the responsibility
** of the caller to eventually free the returned object using
** recoverFreeTable().
*/
static RecoverTable *recoverNewTable(
  int *pRc,                       /* IN/OUT: Error code */
  const char *zName,              /* Name of table */
  const char *zSql,               /* CREATE TABLE statement */
  int bIntkey, 
  int nCol
){
  sqlite3 *dbtmp = 0;             /* sqlite3 handle for testing CREATE TABLE */
  int rc = *pRc;
  RecoverTable *pTab = 0;

  pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable));
  if( rc==SQLITE_OK ){
    int nSqlCol = 0;
    int bSqlIntkey = 0;
    sqlite3_stmt *pStmt = 0;
    
    rc = sqlite3_open("", &dbtmp);
    if( rc==SQLITE_OK ){
      sqlite3_create_function(dbtmp, "shell_idquote", 1, SQLITE_UTF8, 0,
                              shellIdQuote, 0, 0);
    }
    if( rc==SQLITE_OK ){
      rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
    }
    if( rc==SQLITE_OK ){
      rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0);
      if( rc==SQLITE_ERROR ){
        rc = SQLITE_OK;
        goto finished;
      }
    }
    shellPreparePrintf(dbtmp, &rc, &pStmt, 
        "SELECT count(*) FROM pragma_table_info(%Q)", zName
    );
    if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
      nSqlCol = sqlite3_column_int(pStmt, 0);
    }
    shellFinalize(&rc, pStmt);

    if( rc!=SQLITE_OK || nSqlCol<nCol ){
      goto finished;
    }

    shellPreparePrintf(dbtmp, &rc, &pStmt, 
      "SELECT ("
      "  SELECT substr(data,1,1)==X'0D' FROM sqlite_dbpage WHERE pgno=rootpage"
      ") FROM sqlite_schema WHERE name = %Q", zName
    );
    if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
      bSqlIntkey = sqlite3_column_int(pStmt, 0);
    }
    shellFinalize(&rc, pStmt);

    if( bIntkey==bSqlIntkey ){
      int i;
      const char *zPk = "_rowid_";
      sqlite3_stmt *pPkFinder = 0;

      /* If this is an intkey table and there is an INTEGER PRIMARY KEY,
      ** set zPk to the name of the PK column, and pTab->iPk to the index
      ** of the column, where columns are 0-numbered from left to right.
      ** Or, if this is a WITHOUT ROWID table or if there is no IPK column,
      ** leave zPk as "_rowid_" and pTab->iPk at -2.  */
      pTab->iPk = -2;
      if( bIntkey ){
        shellPreparePrintf(dbtmp, &rc, &pPkFinder, 
          "SELECT cid, name FROM pragma_table_info(%Q) "
          "  WHERE pk=1 AND type='integer' COLLATE nocase"
          "  AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)"
          , zName, zName
        );
        if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){
          pTab->iPk = sqlite3_column_int(pPkFinder, 0);
          zPk = (const char*)sqlite3_column_text(pPkFinder, 1);
        }
      }

      pTab->zQuoted = shellMPrintf(&rc, "\"%w\"", zName);
      pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
      pTab->nCol = nSqlCol;

      if( bIntkey ){
        pTab->azlCol[0] = shellMPrintf(&rc, "\"%w\"", zPk);
      }else{
        pTab->azlCol[0] = shellMPrintf(&rc, "");
      }
      i = 1;
      shellPreparePrintf(dbtmp, &rc, &pStmt, 
          "SELECT %Q || group_concat(shell_idquote(name), ', ') "
          "  FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
          "FROM pragma_table_info(%Q)", 
          bIntkey ? ", " : "", pTab->iPk, 
          bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ",
          zName
      );
      while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
        const char *zText = (const char*)sqlite3_column_text(pStmt, 0);
        pTab->azlCol[i] = shellMPrintf(&rc, "%s%s", pTab->azlCol[0], zText);
        i++;
      }
      shellFinalize(&rc, pStmt);

      shellFinalize(&rc, pPkFinder);
    }
  }

 finished:
  sqlite3_close(dbtmp);
  *pRc = rc;
  if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){
    recoverFreeTable(pTab);
    pTab = 0;
  }
  return pTab;
}

/*
** This function is called to search the schema recovered from the
** sqlite_schema table of the (possibly) corrupt database as part
** of a ".recover" command. Specifically, for a table with root page
** iRoot and at least nCol columns. Additionally, if bIntkey is 0, the
** table must be a WITHOUT ROWID table, or if non-zero, not one of
** those.
**
** If a table is found, a (RecoverTable*) object is returned. Or, if
** no such table is found, but bIntkey is false and iRoot is the 
** root page of an index in the recovered schema, then (*pbNoop) is
** set to true and NULL returned. Or, if there is no such table or
** index, NULL is returned and (*pbNoop) set to 0, indicating that
** the caller should write data to the orphans table.
*/
static RecoverTable *recoverFindTable(
  ShellState *pState,             /* Shell state object */
  int *pRc,                       /* IN/OUT: Error code */
  int iRoot,                      /* Root page of table */
  int bIntkey,                    /* True for an intkey table */
  int nCol,                       /* Number of columns in table */
  int *pbNoop                     /* OUT: True if iRoot is root of index */
){
  sqlite3_stmt *pStmt = 0;
  RecoverTable *pRet = 0;
  int bNoop = 0;
  const char *zSql = 0;
  const char *zName = 0;

  /* Search the recovered schema for an object with root page iRoot. */
  shellPreparePrintf(pState->db, pRc, &pStmt,
      "SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot
  );
  while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
    const char *zType = (const char*)sqlite3_column_text(pStmt, 0);
    if( bIntkey==0 && sqlite3_stricmp(zType, "index")==0 ){
      bNoop = 1;
      break;
    }
    if( sqlite3_stricmp(zType, "table")==0 ){
      zName = (const char*)sqlite3_column_text(pStmt, 1);
      zSql = (const char*)sqlite3_column_text(pStmt, 2);
      pRet = recoverNewTable(pRc, zName, zSql, bIntkey, nCol);
      break;
    }
  }

  shellFinalize(pRc, pStmt);
  *pbNoop = bNoop;
  return pRet;
}

/*
** Return a RecoverTable object representing the orphans table.
*/
static RecoverTable *recoverOrphanTable(
  ShellState *pState,             /* Shell state object */
  int *pRc,                       /* IN/OUT: Error code */
  const char *zLostAndFound,      /* Base name for orphans table */
  int nCol                        /* Number of user data columns */
){
  RecoverTable *pTab = 0;
  if( nCol>=0 && *pRc==SQLITE_OK ){
    int i;

    /* This block determines the name of the orphan table. The prefered
    ** name is zLostAndFound. But if that clashes with another name
    ** in the recovered schema, try zLostAndFound_0, zLostAndFound_1
    ** and so on until a non-clashing name is found.  */
    int iTab = 0;
    char *zTab = shellMPrintf(pRc, "%s", zLostAndFound);
    sqlite3_stmt *pTest = 0;
    shellPrepare(pState->db, pRc,
        "SELECT 1 FROM recovery.schema WHERE name=?", &pTest
    );
    if( pTest ) sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
    while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pTest) ){
      shellReset(pRc, pTest);
      sqlite3_free(zTab);
      zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++);
      sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
    }
    shellFinalize(pRc, pTest);

    pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
    if( pTab ){
      pTab->zQuoted = shellMPrintf(pRc, "\"%w\"", zTab);
      pTab->nCol = nCol;
      pTab->iPk = -2;
      if( nCol>0 ){
        pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1));
        if( pTab->azlCol ){
          pTab->azlCol[nCol] = shellMPrintf(pRc, "");
          for(i=nCol-1; i>=0; i--){
            pTab->azlCol[i] = shellMPrintf(pRc, "%s, NULL", pTab->azlCol[i+1]);
          }
        }
      }

      if( *pRc!=SQLITE_OK ){
        recoverFreeTable(pTab);
        pTab = 0;
      }else{
        raw_printf(pState->out, 
            "CREATE TABLE %s(rootpgno INTEGER, "
            "pgno INTEGER, nfield INTEGER, id INTEGER", pTab->zQuoted
        );
        for(i=0; i<nCol; i++){
          raw_printf(pState->out, ", c%d", i);
        }
        raw_printf(pState->out, ");\n");
      }
    }
    sqlite3_free(zTab);
  }
  return pTab;
}

/*
** This function is called to recover data from the database. A script
** to construct a new database containing all recovered data is output
** on stream pState->out.
*/
static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
  int rc = SQLITE_OK;
  sqlite3_stmt *pLoop = 0;        /* Loop through all root pages */
  sqlite3_stmt *pPages = 0;       /* Loop through all pages in a group */
  sqlite3_stmt *pCells = 0;       /* Loop through all cells in a page */
  const char *zRecoveryDb = "";   /* Name of "recovery" database */
  const char *zLostAndFound = "lost_and_found";
  int i;
  int nOrphan = -1;
  RecoverTable *pOrphan = 0;

  int bFreelist = 1;              /* 0 if --freelist-corrupt is specified */
  int bRowids = 1;                /* 0 if --no-rowids */
  for(i=1; i<nArg; i++){
    char *z = azArg[i];
    int n;
    if( z[0]=='-' && z[1]=='-' ) z++;
    n = strlen30(z);
    if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
      bFreelist = 0;
    }else
    if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
      i++;
      zRecoveryDb = azArg[i];
    }else
    if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
      i++;
      zLostAndFound = azArg[i];
    }else
    if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
      bRowids = 0;
    }
    else{
      utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); 
      showHelp(pState->out, azArg[0]);
      return 1;
    }
  }

  shellExecPrintf(pState->db, &rc,
    /* Attach an in-memory database named 'recovery'. Create an indexed 
    ** cache of the sqlite_dbptr virtual table. */
    "PRAGMA writable_schema = on;"
    "ATTACH %Q AS recovery;"
    "DROP TABLE IF EXISTS recovery.dbptr;"
    "DROP TABLE IF EXISTS recovery.freelist;"
    "DROP TABLE IF EXISTS recovery.map;"
    "DROP TABLE IF EXISTS recovery.schema;"
    "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb
  );

  if( bFreelist ){
    shellExec(pState->db, &rc,
      "WITH trunk(pgno) AS ("
      "  SELECT shell_int32("
      "      (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x "
      "      WHERE x>0"
      "    UNION"
      "  SELECT shell_int32("
      "      (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x "
      "      FROM trunk WHERE x>0"
      "),"
      "freelist(data, n, freepgno) AS ("
      "  SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno "
      "      FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno"
      "    UNION ALL"
      "  SELECT data, n-1, shell_int32(data, 2+n) "
      "      FROM freelist WHERE n>=0"
      ")"
      "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;"
    );
  }

  /* If this is an auto-vacuum database, add all pointer-map pages to
  ** the freelist table. Do this regardless of whether or not 
  ** --freelist-corrupt was specified.  */
  shellExec(pState->db, &rc, 
    "WITH ptrmap(pgno) AS ("
    "  SELECT 2 WHERE shell_int32("
    "    (SELECT data FROM sqlite_dbpage WHERE pgno=1), 13"
    "  )"
    "    UNION ALL "
    "  SELECT pgno+1+(SELECT page_size FROM pragma_page_size)/5 AS pp "
    "  FROM ptrmap WHERE pp<=(SELECT page_count FROM pragma_page_count)"
    ")"
    "REPLACE INTO recovery.freelist SELECT pgno FROM ptrmap"
  );

  shellExec(pState->db, &rc, 
    "CREATE TABLE recovery.dbptr("
    "      pgno, child, PRIMARY KEY(child, pgno)"
    ") WITHOUT ROWID;"
    "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) "
    "    SELECT * FROM sqlite_dbptr"
    "      WHERE pgno NOT IN freelist AND child NOT IN freelist;"

    /* Delete any pointer to page 1. This ensures that page 1 is considered
    ** a root page, regardless of how corrupt the db is. */
    "DELETE FROM recovery.dbptr WHERE child = 1;"

    /* Delete all pointers to any pages that have more than one pointer
    ** to them. Such pages will be treated as root pages when recovering
    ** data.  */
    "DELETE FROM recovery.dbptr WHERE child IN ("
    "  SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1"
    ");"

    /* Create the "map" table that will (eventually) contain instructions
    ** for dealing with each page in the db that contains one or more 
    ** records. */
    "CREATE TABLE recovery.map("
      "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT"
    ");"

    /* Populate table [map]. If there are circular loops of pages in the
    ** database, the following adds all pages in such a loop to the map
    ** as individual root pages. This could be handled better.  */
    "WITH pages(i, maxlen) AS ("
    "  SELECT page_count, ("
    "    SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count"
    "  ) FROM pragma_page_count WHERE page_count>0"
    "    UNION ALL"
    "  SELECT i-1, ("
    "    SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
    "  ) FROM pages WHERE i>=2"
    ")"
    "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
    "  SELECT i, maxlen, NULL, ("
    "    WITH p(orig, pgno, parent) AS ("
    "      SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
    "        UNION "
    "      SELECT i, p.parent, "
    "        (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
    "    )"
    "    SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
    ") "
    "FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;"
    "UPDATE recovery.map AS o SET intkey = ("
    "  SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
    ");"

    /* Extract data from page 1 and any linked pages into table
    ** recovery.schema. With the same schema as an sqlite_schema table.  */
    "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
    "INSERT INTO recovery.schema SELECT "
    "  max(CASE WHEN field=0 THEN value ELSE NULL END),"
    "  max(CASE WHEN field=1 THEN value ELSE NULL END),"
    "  max(CASE WHEN field=2 THEN value ELSE NULL END),"
    "  max(CASE WHEN field=3 THEN value ELSE NULL END),"
    "  max(CASE WHEN field=4 THEN value ELSE NULL END)"
    "FROM sqlite_dbdata WHERE pgno IN ("
    "  SELECT pgno FROM recovery.map WHERE root=1"
    ")"
    "GROUP BY pgno, cell;"
    "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);"
  );

  /* Open a transaction, then print out all non-virtual, non-"sqlite_%" 
  ** CREATE TABLE statements that extracted from the existing schema.  */
  if( rc==SQLITE_OK ){
    sqlite3_stmt *pStmt = 0;
    /* ".recover" might output content in an order which causes immediate
    ** foreign key constraints to be violated. So disable foreign-key
    ** constraint enforcement to prevent problems when running the output
    ** script. */
    raw_printf(pState->out, "PRAGMA foreign_keys=OFF;\n");
    raw_printf(pState->out, "BEGIN;\n");
    raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
    shellPrepare(pState->db, &rc,
        "SELECT sql FROM recovery.schema "
        "WHERE type='table' AND sql LIKE 'create table%'", &pStmt
    );
    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
      const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0);
      raw_printf(pState->out, "CREATE TABLE IF NOT EXISTS %s;\n", 
          &zCreateTable[12]
      );
    }
    shellFinalize(&rc, pStmt);
  }

  /* Figure out if an orphan table will be required. And if so, how many
  ** user columns it should contain */
  shellPrepare(pState->db, &rc, 
      "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"
      , &pLoop
  );
  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
    nOrphan = sqlite3_column_int(pLoop, 0);
  }
  shellFinalize(&rc, pLoop);
  pLoop = 0;

  shellPrepare(pState->db, &rc,
      "SELECT pgno FROM recovery.map WHERE root=?", &pPages
  );

  shellPrepare(pState->db, &rc,
      "SELECT max(field), group_concat(shell_escape_crnl(quote"
      "(case when (? AND field<0) then NULL else value end)"
      "), ', ')"
      ", min(field) "
      "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
      "GROUP BY cell", &pCells
  );

  /* Loop through each root page. */
  shellPrepare(pState->db, &rc, 
      "SELECT root, intkey, max(maxlen) FROM recovery.map" 
      " WHERE root>1 GROUP BY root, intkey ORDER BY root=("
      "  SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'"
      ")", &pLoop
  );
  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
    int iRoot = sqlite3_column_int(pLoop, 0);
    int bIntkey = sqlite3_column_int(pLoop, 1);
    int nCol = sqlite3_column_int(pLoop, 2);
    int bNoop = 0;
    RecoverTable *pTab;

    assert( bIntkey==0 || bIntkey==1 );
    pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
    if( bNoop || rc ) continue;
    if( pTab==0 ){
      if( pOrphan==0 ){
        pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
      }
      pTab = pOrphan;
      if( pTab==0 ) break;
    }

    if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
      raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
    }
    sqlite3_bind_int(pPages, 1, iRoot);
    if( bRowids==0 && pTab->iPk<0 ){
      sqlite3_bind_int(pCells, 1, 1);
    }else{
      sqlite3_bind_int(pCells, 1, 0);
    }
    sqlite3_bind_int(pCells, 3, pTab->iPk);

    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
      int iPgno = sqlite3_column_int(pPages, 0);
      sqlite3_bind_int(pCells, 2, iPgno);
      while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
        int nField = sqlite3_column_int(pCells, 0);
        int iMin = sqlite3_column_int(pCells, 2);
        const char *zVal = (const char*)sqlite3_column_text(pCells, 1);

        RecoverTable *pTab2 = pTab;
        if( pTab!=pOrphan && (iMin<0)!=bIntkey ){
          if( pOrphan==0 ){
            pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
          }
          pTab2 = pOrphan;
          if( pTab2==0 ) break;
        }

        nField = nField+1;
        if( pTab2==pOrphan ){
          raw_printf(pState->out, 
              "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
              pTab2->zQuoted, iRoot, iPgno, nField,
              iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField]
          );
        }else{
          raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", 
              pTab2->zQuoted, pTab2->azlCol[nField], zVal
          );
        }
      }
      shellReset(&rc, pCells);
    }
    shellReset(&rc, pPages);
    if( pTab!=pOrphan ) recoverFreeTable(pTab);
  }
  shellFinalize(&rc, pLoop);
  shellFinalize(&rc, pPages);
  shellFinalize(&rc, pCells);
  recoverFreeTable(pOrphan);

  /* The rest of the schema */
  if( rc==SQLITE_OK ){
    sqlite3_stmt *pStmt = 0;
    shellPrepare(pState->db, &rc, 
        "SELECT sql, name FROM recovery.schema "
        "WHERE sql NOT LIKE 'create table%'", &pStmt
    );
    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
      const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
      if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){
        const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
        char *zPrint = shellMPrintf(&rc, 
          "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
          zName, zName, zSql
        );
        raw_printf(pState->out, "%s;\n", zPrint);
        sqlite3_free(zPrint);
      }else{
        raw_printf(pState->out, "%s;\n", zSql);
      }
    }
    shellFinalize(&rc, pStmt);
  }

  if( rc==SQLITE_OK ){
    raw_printf(pState->out, "PRAGMA writable_schema = off;\n");
    raw_printf(pState->out, "COMMIT;\n");
  }
  sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
  return rc;
}
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */


/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
static int do_meta_command(char *zLine, ShellState *p){
  int h = 1;
  int nArg = 0;
  int n, c;
  int rc = 0;
  char *azArg[52];
  char *azArg[50];

#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( p->expert.pExpert ){
    expertFinish(p, 1, 0);
  }
#endif

  /* Parse the input line into tokens.
  */
  while( zLine[h] && nArg<ArraySize(azArg)-1 ){
  while( zLine[h] && nArg<ArraySize(azArg) ){
    while( IsSpace(zLine[h]) ){ h++; }
    if( zLine[h]==0 ) break;
    if( zLine[h]=='\'' || zLine[h]=='"' ){
      int delim = zLine[h++];
      azArg[nArg++] = &zLine[h];
      while( zLine[h] && zLine[h]!=delim ){
        if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
        h++;
      }
      if( zLine[h]==delim ){
        zLine[h++] = 0;
      }
      if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
    }else{
      azArg[nArg++] = &zLine[h];
      while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
      if( zLine[h] ) zLine[h++] = 0;
      resolve_backslashes(azArg[nArg-1]);
    }
  }
  azArg[nArg] = 0;

  /* Process the input line.
  */
  if( nArg==0 ) return 0; /* no tokens, no error */
  n = strlen30(azArg[0]);
  c = azArg[0][0];
  clearTempFile(p);
7608
7609
7610
7611
7612
7613
7614
7615
7616


7617
7618
7619





7620
7621
7622





7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633

7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660

7661
7662

7663
7664

7665
7666
7667
7668
7669
7670
7671
7672






7673
7674
7675
7676
7677
7678
7679
7680
7681
7682

7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703

7704
7705
7706
7707
7708
7709

7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743




7744
7745

7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756





7757
7758
7759
7760
7761

7762
7763
7764
7765
7766
7767
7768
7769



















7770
7771
7772
7773
7774


7775
7776
7777
7778
7779
7780




7781
7782

7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793

7794
7795
7796
7797
7798
7799
7800
7801
6256
6257
6258
6259
6260
6261
6262


6263
6264


6265
6266
6267
6268
6269
6270



6271
6272
6273
6274
6275
6276










6277
















6278
6279
6280
6281
6282
6283
6284




6285


6286


6287








6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302

6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315







6316

6317

6318
6319
6320


6321

6322
6323
6324
6325
6326
6327
6328
6329
6330

6331
6332
6333
6334
6335
6336
6337
6338






6339
6340
6341

6342
6343
6344


6345
6346
6347
6348
6349

6350
6351
6352

6353







6354
6355
6356
6357
6358

6359
6360
6361

6362
6363
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







-
-
+
+
-
-

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

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







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









-
+












-
-
-
-
-
-
-

-
+
-



-
-
+
-









-








-
-
-
-
-
-



-



-
-
+
+
+
+

-
+


-

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



-
+



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

-
-
-
-
+
+
+
+
-
-
+


-






-
-
+
-







    }else{
      raw_printf(stderr, "Usage: .clone FILENAME\n");
      rc = 1;
    }
  }else

  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
    char **azName = 0;
    int nName = 0;
    ShellState data;
    char *zErrMsg = 0;
    sqlite3_stmt *pStmt;
    int i;
    open_db(p, 0);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.cMode = data.mode = MODE_List;
    sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
    data.cnt = 0;
    rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
    if( rc ){
      utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
    sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
                 callback, &data, &zErrMsg);
    if( zErrMsg ){
      utf8_printf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }else{
      while( sqlite3_step(pStmt)==SQLITE_ROW ){
        const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
        const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
        azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*));
        if( azName==0 ){ shell_out_of_memory();  /* Does not return */ }
        azName[nName*2] = strdup(zSchema);
        azName[nName*2+1] = strdup(zFile);
        nName++;
      }
    }
    }
    sqlite3_finalize(pStmt);
    for(i=0; i<nName; i++){
      int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
      int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
      const char *z = azName[i*2+1];
      utf8_printf(p->out, "%s: %s %s%s\n",
         azName[i*2],
         z && z[0] ? z : "\"\"",
         bRdonly ? "r/o" : "r/w",
         eTxn==SQLITE_TXN_NONE ? "" :
            eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
      free(azName[i*2]);
      free(azName[i*2+1]);
    }
    sqlite3_free(azName);
  }else

  if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
    static const struct DbConfigChoices {
      const char *zName;
      int op;
    } aDbConfig[] = {
        { "defensive",          SQLITE_DBCONFIG_DEFENSIVE             },
        { "dqs_ddl",            SQLITE_DBCONFIG_DQS_DDL               },
        { "dqs_dml",            SQLITE_DBCONFIG_DQS_DML               },
        { "enable_fkey",        SQLITE_DBCONFIG_ENABLE_FKEY           },
        { "enable_fkey",      SQLITE_DBCONFIG_ENABLE_FKEY            },
        { "enable_qpsg",        SQLITE_DBCONFIG_ENABLE_QPSG           },
        { "enable_trigger",     SQLITE_DBCONFIG_ENABLE_TRIGGER        },
        { "enable_trigger",   SQLITE_DBCONFIG_ENABLE_TRIGGER         },
        { "enable_view",        SQLITE_DBCONFIG_ENABLE_VIEW           },
        { "fts3_tokenizer",     SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
        { "fts3_tokenizer",   SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER  },
        { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    },
        { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    },
        { "load_extension",     SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
        { "no_ckpt_on_close",   SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      },
        { "reset_database",     SQLITE_DBCONFIG_RESET_DATABASE        },
        { "trigger_eqp",        SQLITE_DBCONFIG_TRIGGER_EQP           },
        { "trusted_schema",     SQLITE_DBCONFIG_TRUSTED_SCHEMA        },
        { "writable_schema",    SQLITE_DBCONFIG_WRITABLE_SCHEMA       },
        { "load_extension",   SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION  },
        { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE       },
        { "enable_qpsg",      SQLITE_DBCONFIG_ENABLE_QPSG            },
        { "trigger_eqp",      SQLITE_DBCONFIG_TRIGGER_EQP            },
        { "reset_database",   SQLITE_DBCONFIG_RESET_DATABASE         },
        { "defensive",        SQLITE_DBCONFIG_DEFENSIVE              },
    };
    int ii, v;
    open_db(p, 0);
    for(ii=0; ii<ArraySize(aDbConfig); ii++){
      if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
      if( nArg>=3 ){
        sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
      }
      sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
      utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
      utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
      if( nArg>1 ) break;
    }
    if( nArg>1 && ii==ArraySize(aDbConfig) ){
      utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
      utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
    }   
  }else

  if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
    rc = shell_dbinfo_command(p, nArg, azArg);
  }else

#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
    open_db(p, 0);
    rc = recoverDatabaseCmd(p, nArg, azArg);
  }else
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */

  if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
    char *zLike = 0;
    const char *zLike = 0;
    char *zSql;
    int i;
    int savedShowHeader = p->showHeader;
    int savedShellFlags = p->shellFlgs;
    ShellClearFlag(p, 
       SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
    ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);
       |SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
    for(i=1; i<nArg; i++){
      if( azArg[i][0]=='-' ){
        const char *z = azArg[i]+1;
        if( z[0]=='-' ) z++;
        if( strcmp(z,"preserve-rowids")==0 ){
#ifdef SQLITE_OMIT_VIRTUALTABLE
          raw_printf(stderr, "The --preserve-rowids option is not compatible"
                             " with SQLITE_OMIT_VIRTUALTABLE\n");
          rc = 1;
          sqlite3_free(zLike);
          goto meta_command_exit;
#else
          ShellSetFlag(p, SHFLG_PreserveRowid);
#endif
        }else
        if( strcmp(z,"newlines")==0 ){
          ShellSetFlag(p, SHFLG_Newlines);
        }else
        if( strcmp(z,"data-only")==0 ){
          ShellSetFlag(p, SHFLG_DumpDataOnly);
        }else
        if( strcmp(z,"nosys")==0 ){
          ShellSetFlag(p, SHFLG_DumpNoSys);
        }else
        {
          raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
          rc = 1;
          sqlite3_free(zLike);
          goto meta_command_exit;
        }
      }else if( zLike ){
        zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
                zLike, azArg[i]);
        raw_printf(stderr, "Usage: .dump ?--preserve-rowids? "
                           "?--newlines? ?LIKE-PATTERN?\n");
        rc = 1;
        goto meta_command_exit;
      }else{
        zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
        zLike = azArg[i];
      }
    }

    open_db(p, 0);

    if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
      /* When playing back a "dump", the content might appear in an order
      ** which causes immediate foreign key constraints to be violated.
      ** So disable foreign-key constraint enforcement to prevent problems. */
      raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
      raw_printf(p->out, "BEGIN TRANSACTION;\n");
    /* When playing back a "dump", the content might appear in an order
    ** which causes immediate foreign key constraints to be violated.
    ** So disable foreign-key constraint enforcement to prevent problems. */
    raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
    raw_printf(p->out, "BEGIN TRANSACTION;\n");
    }
    p->writableSchema = 0;
    p->showHeader = 0;
    /* Set writable_schema=ON since doing so forces SQLite to initialize
    ** as much of the schema as it can even if the sqlite_schema table is
    ** as much of the schema as it can even if the sqlite_master table is
    ** corrupt. */
    sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
    p->nErr = 0;
    if( zLike==0 ) zLike = sqlite3_mprintf("true");
    zSql = sqlite3_mprintf(
      "SELECT name, type, sql FROM sqlite_schema "
      "WHERE (%s) AND type=='table'"
      "  AND sql NOT NULL"
    if( zLike==0 ){
      run_schema_dump_query(p,
        "SELECT name, type, sql FROM sqlite_master "
        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
      );
      run_schema_dump_query(p,
        "SELECT name, type, sql FROM sqlite_master "
        "WHERE name=='sqlite_sequence'"
      );
      run_table_dump_query(p,
        "SELECT sql FROM sqlite_master "
        "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
      );
    }else{
      char *zSql;
      zSql = sqlite3_mprintf(
        "SELECT name, type, sql FROM sqlite_master "
        "WHERE tbl_name LIKE %Q AND type=='table'"
        "  AND sql NOT NULL", zLike);
      " ORDER BY tbl_name='sqlite_sequence', rowid",
      zLike
    );
    run_schema_dump_query(p,zSql);
    sqlite3_free(zSql);
      run_schema_dump_query(p,zSql);
      sqlite3_free(zSql);
    if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
      zSql = sqlite3_mprintf(
        "SELECT sql FROM sqlite_schema "
        "WHERE (%s) AND sql NOT NULL"
        "  AND type IN ('index','trigger','view')",
        zLike
        "SELECT sql FROM sqlite_master "
        "WHERE sql NOT NULL"
        "  AND type IN ('index','trigger','view')"
        "  AND tbl_name LIKE %Q", zLike);
      );
      run_table_dump_query(p, zSql);
      run_table_dump_query(p, zSql, 0);
      sqlite3_free(zSql);
    }
    sqlite3_free(zLike);
    if( p->writableSchema ){
      raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
      p->writableSchema = 0;
    }
    sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
    sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
    if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
      raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
    raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
    }
    p->showHeader = savedShowHeader;
    p->shellFlgs = savedShellFlags;
  }else

  if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
    if( nArg==2 ){
      setOrClearFlag(p, SHFLG_Echo, azArg[1]);
7820
7821
7822
7823
7824
7825
7826
7827

7828
7829
7830
7831
7832
7833
7834
6427
6428
6429
6430
6431
6432
6433

6434
6435
6436
6437
6438
6439
6440
6441







-
+







      }else if( strcmp(azArg[1],"test")==0 ){
        p->autoEQP = AUTOEQP_on;
        p->autoEQPtest = 1;
      }else if( strcmp(azArg[1],"trace")==0 ){
        p->autoEQP = AUTOEQP_full;
        p->autoEQPtrace = 1;
        open_db(p, 0);
        sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
        sqlite3_exec(p->db, "SELECT name FROM sqlite_master LIMIT 1", 0, 0, 0);
        sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
#endif
      }else{
        p->autoEQP = (u8)booleanValue(azArg[1]);
      }
    }else{
      raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
7868
7869
7870
7871
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
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043


8044
8045
8046
8047
8048
8049
8050
8051

8052
8053
8054
8055
8056
8057
8058
8059
8060
8061


8062
8063
8064
8065


8066
8067
8068

8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095


8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108









8109
8110
8111
8112

8113
8114
8115
8116

8117
8118
8119

8120
8121
8122
8123
8124
8125
8126



8127
8128
8129


8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145


8146
8147
8148
8149
8150
8151
8152
8153
8154

8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177


8178
8179
8180


8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194













8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205

8206
8207
8208
8209
8210

8211
8212
8213
8214

8215





8216
8217
8218

8219
8220
8221
8222
8223
8224

8225
8226
8227
8228

8229
8230
8231
8232
8233
8234
8235

8236
8237

8238
8239
8240
8241
8242
8243
8244

8245
8246
8247
8248
8249
8250
8251
8252

8253

8254
8255

8256
8257
8258
8259
8260
8261
8262
8263
8264
8265

8266

8267
8268


8269
8270
8271
8272
8273
8274
8275
8276
8277
8278


8279
8280
8281
8282
8283
8284
8285
8286
8287

8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307


8308
8309
8310
8311
8312
8313
8314
8315
6475
6476
6477
6478
6479
6480
6481



















































































































































6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501


6502
6503
6504
6505
6506
6507
6508
6509
6510

6511
6512
6513
6514
6515
6516
6517
6518
6519


6520
6521
6522
6523
6524
6525
6526
6527
6528
6529

6530
6531
6532
6533
6534
6535
6536

6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554


6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565




6566
6567
6568
6569
6570
6571
6572
6573
6574
6575



6576




6577



6578







6579
6580
6581



6582
6583
















6584
6585









6586

6587





















6588
6589



6590
6591














6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604




6605
6606
6607
6608
6609
6610

6611

6612
6613
6614

6615
6616
6617
6618

6619
6620
6621
6622
6623
6624
6625
6626
6627

6628

6629




6630




6631







6632
6633

6634
6635
6636
6637
6638
6639
6640

6641
6642
6643
6644
6645
6646
6647
6648
6649
6650

6651
6652

6653

6654
6655



6656
6657
6658

6659
6660
6661


6662
6663

6664
6665
6666
6667
6668
6669
6670


6671
6672

6673
6674
6675
6676
6677
6678
6679

6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690



6691
6692
6693
6694
6695


6696
6697

6698
6699
6700
6701
6702
6703
6704







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




















-
-
+
+







-
+








-
-
+
+




+
+


-
+






-


















-
-
+
+









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

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

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






-
+
-



-
+



-
+

+
+
+
+
+


-
+
-

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

-
+






-
+








+
-
+

-
+
-


-
-
-



-
+

+
-
-
+
+
-







-
-
+
+
-







-
+










-
-
-





-
-
+
+
-







#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){
    open_db(p, 0);
    expertDotCommand(p, azArg, nArg);
  }else
#endif

  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;
    const char *zSchema = 0;

    open_db(p, 0);
    zCmd = nArg>=2 ? azArg[1] : "help";

    if( zCmd[0]=='-' 
     && (strcmp(zCmd,"--schema")==0 || strcmp(zCmd,"-schema")==0)
     && nArg>=4
    ){
      zSchema = azArg[2];
      for(i=3; i<nArg; i++) azArg[i-2] = azArg[i];
      nArg -= 2;
      zCmd = azArg[1];
    }

    /* The argument can optionally begin with "-" or "--" */
    if( zCmd[0]=='-' && zCmd[1] ){
      zCmd++;
      if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
    }

    /* --help lists all file-controls */
    if( strcmp(zCmd,"help")==0 ){
      utf8_printf(p->out, "Available file-controls:\n");
      for(i=0; i<ArraySize(aCtrl); i++){
        utf8_printf(p->out, "  .filectrl %s %s\n",
                    aCtrl[i].zCtrlName, aCtrl[i].zUsage);
      }
      rc = 1;
      goto meta_command_exit;
    }

    /* convert filectrl text option to value. allow any unique prefix
    ** of the option name, or a numerical value. */
    n2 = strlen30(zCmd);
    for(i=0; i<ArraySize(aCtrl); i++){
      if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
        if( filectrl<0 ){
          filectrl = aCtrl[i].ctrlCode;
          iCtrl = i;
        }else{
          utf8_printf(stderr, "Error: ambiguous file-control: \"%s\"\n"
                              "Use \".filectrl --help\" for help\n", zCmd);
          rc = 1;
          goto meta_command_exit;
        }
      }
    }
    if( filectrl<0 ){
      utf8_printf(stderr,"Error: unknown file-control: %s\n"
                         "Use \".filectrl --help\" for help\n", zCmd);
    }else{
      switch(filectrl){
        case SQLITE_FCNTL_SIZE_LIMIT: {
          if( nArg!=2 && nArg!=3 ) break;
          iRes = nArg==3 ? integerValue(azArg[2]) : -1;
          sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
          isOk = 1;
          break;
        }
        case SQLITE_FCNTL_LOCK_TIMEOUT:
        case SQLITE_FCNTL_CHUNK_SIZE: {
          int x;
          if( nArg!=3 ) break;
          x = (int)integerValue(azArg[2]);
          sqlite3_file_control(p->db, zSchema, filectrl, &x);
          isOk = 2;
          break;
        }
        case SQLITE_FCNTL_PERSIST_WAL:
        case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
          int x;
          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;
        }
        case SQLITE_FCNTL_TEMPFILENAME: {
          char *z = 0;
          if( nArg!=2 ) break;
          sqlite3_file_control(p->db, zSchema, filectrl, &z);
          if( z ){
            utf8_printf(p->out, "%s\n", z);
            sqlite3_free(z);
          }
          isOk = 2;
          break;
        }
        case SQLITE_FCNTL_RESERVE_BYTES: {
          int x;
          if( nArg>=3 ){
            x = atoi(azArg[2]);
            sqlite3_file_control(p->db, zSchema, filectrl, &x);
          }
          x = -1;
          sqlite3_file_control(p->db, zSchema, filectrl, &x);
          utf8_printf(p->out,"%d\n", x);
          isOk = 2;
          break;
        }
      }
    }
    if( isOk==0 && iCtrl>=0 ){
      utf8_printf(p->out, "Usage: .filectrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
      rc = 1;
    }else if( isOk==1 ){
      char zBuf[100];
      sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
      raw_printf(p->out, "%s\n", zBuf);
    }
  }else

  if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
    ShellState data;
    char *zErrMsg = 0;
    int doStats = 0;
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.cMode = data.mode = MODE_Semi;
    if( nArg==2 && optionMatch(azArg[1], "indent") ){
      data.cMode = data.mode = MODE_Pretty;
      nArg = 1;
    }
    if( nArg!=1 ){
      raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
      rc = 1;
      goto meta_command_exit;
    }
    open_db(p, 0);
    rc = sqlite3_exec(p->db,
       "SELECT sql FROM"
       "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
       "     FROM sqlite_schema UNION ALL"
       "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
       "     FROM sqlite_master UNION ALL"
       "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
       "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
       "ORDER BY rowid",
       callback, &data, &zErrMsg
    );
    if( rc==SQLITE_OK ){
      sqlite3_stmt *pStmt;
      rc = sqlite3_prepare_v2(p->db,
               "SELECT rowid FROM sqlite_schema"
               "SELECT rowid FROM sqlite_master"
               " WHERE name GLOB 'sqlite_stat[134]'",
               -1, &pStmt, 0);
      doStats = sqlite3_step(pStmt)==SQLITE_ROW;
      sqlite3_finalize(pStmt);
    }
    if( doStats==0 ){
      raw_printf(p->out, "/* No STAT tables available */\n");
    }else{
      raw_printf(p->out, "ANALYZE sqlite_schema;\n");
      sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_schema'",
      raw_printf(p->out, "ANALYZE sqlite_master;\n");
      sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
                   callback, &data, &zErrMsg);
      data.cMode = data.mode = MODE_Insert;
      data.zDestTable = "sqlite_stat1";
      shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
      data.zDestTable = "sqlite_stat3";
      shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg);
      data.zDestTable = "sqlite_stat4";
      shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
      raw_printf(p->out, "ANALYZE sqlite_schema;\n");
      raw_printf(p->out, "ANALYZE sqlite_master;\n");
    }
  }else

  if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
    if( nArg==2 ){
      p->showHeader = booleanValue(azArg[1]);
      p->shellFlgs |= SHFLG_HeaderSet;
    }else{
      raw_printf(stderr, "Usage: .headers on|off\n");
      rc = 1;
    }
  }else

  if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
    if( nArg>=2 ){
      n = showHelp(p->out, azArg[1]);
      if( n==0 ){
        utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
      }
    }else{
      showHelp(p->out, 0);
    }
  }else

  if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
    char *zTable = 0;           /* Insert data into this table */
    char *zFile = 0;            /* Name of file to extra content from */
    char *zTable;               /* Insert data into this table */
    char *zFile;                /* Name of file to extra content from */
    sqlite3_stmt *pStmt = NULL; /* A statement */
    int nCol;                   /* Number of columns in the table */
    int nByte;                  /* Number of bytes in an SQL string */
    int i, j;                   /* Loop counters */
    int needCommit;             /* True to COMMIT or ROLLBACK at end */
    int nSep;                   /* Number of bytes in p->colSeparator[] */
    char *zSql;                 /* An SQL statement */
    ImportCtx sCtx;             /* Reader context */
    char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
    int eVerbose = 0;           /* Larger for more console output */
    int nSkip = 0;              /* Initial lines to skip */
    int useOutputMode = 1;      /* Use output mode to determine separators */

    int (SQLITE_CDECL *xCloser)(FILE*);      /* Func to close file */

    if( nArg!=3 ){
      raw_printf(stderr, "Usage: .import FILE TABLE\n");
      goto meta_command_exit;
    }
    zFile = azArg[1];
    zTable = azArg[2];
    seenInterrupt = 0;
    memset(&sCtx, 0, sizeof(sCtx));
    if( p->mode==MODE_Ascii ){
      xRead = ascii_read_one_field;
    }else{
    open_db(p, 0);
      xRead = csv_read_one_field;
    }
    for(i=1; i<nArg; i++){
      char *z = azArg[i];
    nSep = strlen30(p->colSeparator);
      if( z[0]=='-' && z[1]=='-' ) z++;
      if( z[0]!='-' ){
        if( zFile==0 ){
    if( nSep==0 ){
          zFile = z;
        }else if( zTable==0 ){
          zTable = z;
        }else{
          utf8_printf(p->out, "ERROR: extra argument: \"%s\".  Usage:\n", z);
          showHelp(p->out, "import");
          rc = 1;
      raw_printf(stderr,
                 "Error: non-null column separator required for import\n");
      return 1;
          goto meta_command_exit;
        }
      }else if( strcmp(z,"-v")==0 ){
    }
    if( nSep>1 ){
        eVerbose++;
      }else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
        nSkip = integerValue(azArg[++i]);
      }else if( strcmp(z,"-ascii")==0 ){
        sCtx.cColSep = SEP_Unit[0];
        sCtx.cRowSep = SEP_Record[0];
        xRead = ascii_read_one_field;
        useOutputMode = 0;
      }else if( strcmp(z,"-csv")==0 ){
        sCtx.cColSep = ',';
        sCtx.cRowSep = '\n';
        xRead = csv_read_one_field;
        useOutputMode = 0;
      }else{
        utf8_printf(p->out, "ERROR: unknown option: \"%s\".  Usage:\n", z);
        showHelp(p->out, "import");
      raw_printf(stderr, "Error: multi-character column separators not allowed"
                      " for import\n");
        rc = 1;
        goto meta_command_exit;
      }
    }
    if( zTable==0 ){
      utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
                  zFile==0 ? "FILE" : "TABLE");
      showHelp(p->out, "import");
      rc = 1;
      return 1;
      goto meta_command_exit;
    }
    seenInterrupt = 0;
    open_db(p, 0);
    if( useOutputMode ){
      /* If neither the --csv or --ascii options are specified, then set
      ** the column and row separator characters from the output mode. */
      nSep = strlen30(p->colSeparator);
      if( nSep==0 ){
        raw_printf(stderr,
                   "Error: non-null column separator required for import\n");
        rc = 1;
        goto meta_command_exit;
      }
      if( nSep>1 ){
        raw_printf(stderr, 
              "Error: multi-character column separators not allowed"
              " for import\n");
        rc = 1;
        goto meta_command_exit;
      }
      nSep = strlen30(p->rowSeparator);
      if( nSep==0 ){
    nSep = strlen30(p->rowSeparator);
    if( nSep==0 ){
        raw_printf(stderr,
            "Error: non-null row separator required for import\n");
        rc = 1;
      raw_printf(stderr, "Error: non-null row separator required for import\n");
      return 1;
        goto meta_command_exit;
      }
      if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
        /* When importing CSV (only), if the row separator is set to the
        ** default output row separator, change it to the default input
        ** row separator.  This avoids having to maintain different input
        ** and output row separators. */
        sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
        nSep = strlen30(p->rowSeparator);
      }
      if( nSep>1 ){
        raw_printf(stderr, "Error: multi-character row separators not allowed"
                           " for import\n");
        rc = 1;
    }
    if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
      /* When importing CSV (only), if the row separator is set to the
      ** default output row separator, change it to the default input
      ** row separator.  This avoids having to maintain different input
      ** and output row separators. */
      sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
      nSep = strlen30(p->rowSeparator);
    }
    if( nSep>1 ){
      raw_printf(stderr, "Error: multi-character row separators not allowed"
                      " for import\n");
      return 1;
        goto meta_command_exit;
      }
      sCtx.cColSep = p->colSeparator[0];
      sCtx.cRowSep = p->rowSeparator[0];
    }
    sCtx.zFile = zFile;
    sCtx.nLine = 1;
    if( sCtx.zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
      rc = 1;
      return 1;
      goto meta_command_exit;
#else
      sCtx.in = popen(sCtx.zFile+1, "r");
      sCtx.zFile = "<pipe>";
      sCtx.xCloser = pclose;
      xCloser = pclose;
#endif
    }else{
      sCtx.in = fopen(sCtx.zFile, "rb");
      sCtx.xCloser = fclose;
      xCloser = fclose;
    }
    if( p->mode==MODE_Ascii ){
      xRead = ascii_read_one_field;
    }else{
      xRead = csv_read_one_field;
    }
    if( sCtx.in==0 ){
      utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
      rc = 1;
      return 1;
      goto meta_command_exit;
    }
    if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
      char zSep[2];
      zSep[1] = 0;
      zSep[0] = sCtx.cColSep;
    sCtx.cColSep = p->colSeparator[0];
      utf8_printf(p->out, "Column separator ");
      output_c_string(p->out, zSep);
      utf8_printf(p->out, ", row separator ");
      zSep[0] = sCtx.cRowSep;
    sCtx.cRowSep = p->rowSeparator[0];
      output_c_string(p->out, zSep);
      utf8_printf(p->out, "\n");
    }
    while( (nSkip--)>0 ){
      while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
    }
    zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
    zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
    if( zSql==0 ){
      import_cleanup(&sCtx);
      xCloser(sCtx.in);
      shell_out_of_memory();
    }
    nByte = strlen30(zSql);
    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    import_append_char(&sCtx, 0);    /* To ensure sCtx.z is allocated */
    if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
      char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\"", zTable);
      char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
      char cSep = '(';
      while( xRead(&sCtx) ){
        zCreate = sqlite3_mprintf("%z%c\n  \"%w\" TEXT", zCreate, cSep, sCtx.z);
        cSep = ',';
        if( sCtx.cTerm!=sCtx.cColSep ) break;
      }
      if( cSep=='(' ){
        sqlite3_free(zCreate);
        sqlite3_free(sCtx.z);
        import_cleanup(&sCtx);
        xCloser(sCtx.in);
        utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
        rc = 1;
        return 1;
        goto meta_command_exit;
      }
      zCreate = sqlite3_mprintf("%z\n)", zCreate);
      if( eVerbose>=1 ){
        utf8_printf(p->out, "%s\n", zCreate);
      }
      rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
      sqlite3_free(zCreate);
      if( rc ){
        utf8_printf(stderr, "CREATE TABLE \"%s\"(...) failed: %s\n", zTable,
        utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
                sqlite3_errmsg(p->db));
        sqlite3_free(sCtx.z);
        import_cleanup(&sCtx);
        rc = 1;
        xCloser(sCtx.in);
        return 1;
        goto meta_command_exit;
      }
      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    }
    sqlite3_free(zSql);
    if( rc ){
      if (pStmt) sqlite3_finalize(pStmt);
      utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
      import_cleanup(&sCtx);
      rc = 1;
      xCloser(sCtx.in);
      return 1;
      goto meta_command_exit;
    }
    nCol = sqlite3_column_count(pStmt);
    sqlite3_finalize(pStmt);
    pStmt = 0;
    if( nCol==0 ) return 0; /* no columns, no error */
    zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
    if( zSql==0 ){
      import_cleanup(&sCtx);
      xCloser(sCtx.in);
      shell_out_of_memory();
    }
    sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
    j = strlen30(zSql);
    for(i=1; i<nCol; i++){
      zSql[j++] = ',';
      zSql[j++] = '?';
    }
    zSql[j++] = ')';
    zSql[j] = 0;
    if( eVerbose>=2 ){
      utf8_printf(p->out, "Insert using: %s\n", zSql);
    }
    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    sqlite3_free(zSql);
    if( rc ){
      utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
      if (pStmt) sqlite3_finalize(pStmt);
      import_cleanup(&sCtx);
      rc = 1;
      xCloser(sCtx.in);
      return 1;
      goto meta_command_exit;
    }
    needCommit = sqlite3_get_autocommit(p->db);
    if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
    do{
      int startLine = sCtx.nLine;
      for(i=0; i<nCol; i++){
        char *z = xRead(&sCtx);
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358


8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395

8396
8397

8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410





8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446


8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457

8458
8459
8460
8461
8462
8463
8464
8465
6733
6734
6735
6736
6737
6738
6739



6740
6741
6742
6743

6744
6745
6746
6747





6748
6749
6750
6751
6752
6753
6754
6755


6756
6757
6758
6759







6760
6761
6762
6763
6764
6765
6766
6767

6768


6769






6770
6771
6772
6773

6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796



6797
6798
6799
6800
6801
6802
6803







6804


6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816

6817

6818
6819
6820
6821
6822
6823
6824







-
-
-




-
+
+


-
-
-
-
-








-
-




-
-
-
-
-
-
-








-
+
-
-
+
-
-
-
-
-
-




-


+
+
+
+
+
















-
-
-







-
-
-
-
-
-
-

-
-
+
+










-
+
-







      }
      if( i>=nCol ){
        sqlite3_step(pStmt);
        rc = sqlite3_reset(pStmt);
        if( rc!=SQLITE_OK ){
          utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
                      startLine, sqlite3_errmsg(p->db));
          sCtx.nErr++;
        }else{
          sCtx.nRow++;
        }
      }
    }while( sCtx.cTerm!=EOF );

    import_cleanup(&sCtx);
    xCloser(sCtx.in);
    sqlite3_free(sCtx.z);
    sqlite3_finalize(pStmt);
    if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
    if( eVerbose>0 ){
      utf8_printf(p->out,
          "Added %d rows with %d errors using %d lines of input\n",
          sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
    }
  }else

#ifndef SQLITE_UNTESTABLE
  if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
    char *zSql;
    char *zCollist = 0;
    sqlite3_stmt *pStmt;
    int tnum = 0;
    int isWO = 0;  /* True if making an imposter of a WITHOUT ROWID table */
    int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
    int i;
    if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
      utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
                          "       .imposter off\n");
      /* Also allowed, but not documented:
      **
      **    .imposter TABLE IMPOSTER
      **
      ** where TABLE is a WITHOUT ROWID table.  In that case, the
      ** imposter is another WITHOUT ROWID table with the columns in
      ** storage order. */
      rc = 1;
      goto meta_command_exit;
    }
    open_db(p, 0);
    if( nArg==2 ){
      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
      goto meta_command_exit;
    }
    zSql = sqlite3_mprintf(
    zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
      "SELECT rootpage, 0 FROM sqlite_schema"
      " WHERE name='%q' AND type='index'"
                           " WHERE name='%q' AND type='index'", azArg[1]);
      "UNION ALL "
      "SELECT rootpage, 1 FROM sqlite_schema"
      " WHERE name='%q' AND type='table'"
      "   AND sql LIKE '%%without%%rowid%%'",
      azArg[1], azArg[1]
    );
    sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    sqlite3_free(zSql);
    if( sqlite3_step(pStmt)==SQLITE_ROW ){
      tnum = sqlite3_column_int(pStmt, 0);
      isWO = sqlite3_column_int(pStmt, 1);
    }
    sqlite3_finalize(pStmt);
    if( tnum==0 ){
      utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
      rc = 1;
      goto meta_command_exit;
    }
    zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    sqlite3_free(zSql);
    i = 0;
    while( sqlite3_step(pStmt)==SQLITE_ROW ){
      char zLabel[20];
      const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
      i++;
      if( zCol==0 ){
        if( sqlite3_column_int(pStmt,1)==-1 ){
          zCol = "_ROWID_";
        }else{
          sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
          zCol = zLabel;
        }
      }
      if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){
        lenPK = (int)strlen(zCollist);
      }
      if( zCollist==0 ){
        zCollist = sqlite3_mprintf("\"%w\"", zCol);
      }else{
        zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
      }
    }
    sqlite3_finalize(pStmt);
    if( i==0 || tnum==0 ){
      utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
      rc = 1;
      sqlite3_free(zCollist);
      goto meta_command_exit;
    }
    if( lenPK==0 ) lenPK = 100000;
    zSql = sqlite3_mprintf(
          "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
          azArg[2], zCollist, lenPK, zCollist);
          "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
          azArg[2], zCollist, zCollist);
    sqlite3_free(zCollist);
    rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
    if( rc==SQLITE_OK ){
      rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
      if( rc ){
        utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
      }else{
        utf8_printf(stdout, "%s;\n", zSql);
        raw_printf(stdout,
          "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n",
           "WARNING: writing to an imposter table will corrupt the index!\n"
          azArg[1], isWO ? "table" : "index"
        );
      }
    }else{
      raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
      rc = 1;
    }
    sqlite3_free(zSql);
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
6949
6950
6951
6952
6953
6954
6955



6956
6957
6958
6959
6960
6961
6962







-
-
-







    int n2 = strlen30(zMode);
    int c2 = zMode[0];
    if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
      p->mode = MODE_Line;
      sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
    }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
      p->mode = MODE_Column;
      if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
        p->showHeader = 1;
      }
      sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
    }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
      p->mode = MODE_List;
      sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
      sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
    }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
      p->mode = MODE_Html;
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641

8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
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
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735

8736
8737
8738
8739
8740
8741
8742
6972
6973
6974
6975
6976
6977
6978


6979
6980
6981
6982








6983
6984
6985
6986

6987

6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002




























7003



7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014

7015
7016

7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028


7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040






7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051







-
-




-
-
-
-
-
-
-
-




-
+
-















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

-
-
-
+
+
+








-


-
+











-
-












-
-
-
-
-
-



+







      p->mode = MODE_List;
      sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
    }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
      p->mode = MODE_Insert;
      set_table_name(p, nArg>=3 ? azArg[2] : "table");
    }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
      p->mode = MODE_Quote;
      sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
      sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
    }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
      p->mode = MODE_Ascii;
      sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
      sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
    }else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
      p->mode = MODE_Markdown;
    }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
      p->mode = MODE_Table;
    }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
      p->mode = MODE_Box;
    }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
      p->mode = MODE_Json;
    }else if( nArg==1 ){
      raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
    }else{
      raw_printf(stderr, "Error: mode should be one of: "
         "ascii box column csv html insert json line list markdown "
         "ascii column csv html insert line list quote tabs tcl\n");
         "quote table tabs tcl\n");
      rc = 1;
    }
    p->cMode = p->mode;
  }else

  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
    if( nArg==2 ){
      sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
                       "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
    }else{
      raw_printf(stderr, "Usage: .nullvalue STRING\n");
      rc = 1;
    }
  }else

#ifdef SQLITE_DEBUG
  if( c=='o' && strcmp(azArg[0],"oom")==0 ){
    int i;
    for(i=1; i<nArg; i++){
      const char *z = azArg[i];
      if( z[0]=='-' && z[1]=='-' ) z++;
      if( strcmp(z,"-repeat")==0 ){
        if( i==nArg-1 ){
          raw_printf(p->out, "missing argument on \"%s\"\n", azArg[i]);
          rc = 1;
        }else{
          oomRepeat = (int)integerValue(azArg[++i]);
        }
      }else if( IsDigit(z[0]) ){
        oomCounter = (int)integerValue(azArg[i]);
      }else{
        raw_printf(p->out, "unknown argument: \"%s\"\n", azArg[i]);
        raw_printf(p->out, "Usage: .oom [--repeat N] [M]\n");
        rc = 1;
      }
    }
    if( rc==0 ){
      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 */
    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; iName++){
    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
      }else if( optionMatch(z, "append") ){
        p->openMode = SHELL_OPEN_APPENDVFS;
      }else if( optionMatch(z, "readonly") ){
        p->openMode = SHELL_OPEN_READONLY;
      }else if( optionMatch(z, "nofollow") ){
        p->openFlags |= SQLITE_OPEN_NOFOLLOW;
#ifdef SQLITE_ENABLE_DESERIALIZE
      }else if( optionMatch(z, "deserialize") ){
        p->openMode = SHELL_OPEN_DESERIALIZE;
      }else if( optionMatch(z, "hexdb") ){
        p->openMode = SHELL_OPEN_HEXDB;
      }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 */
    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);
8751
8752
8753
8754
8755
8756
8757
8758

8759
8760
8761
8762
8763
8764
8765

8766
8767
8768
8769





8770
8771
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

8797

8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809

8810
8811

8812
8813
8814

8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827

8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869



8870
8871

8872
8873
8874
8875
8876
8877
8878
7060
7061
7062
7063
7064
7065
7066

7067
7068






7069




7070
7071
7072
7073
7074
7075



7076














7077
7078
7079
7080



7081






7082

7083
7084

7085
7086



7087
7088
7089
7090
7091
7092
7093

7094
7095
7096

7097

7098

7099
7100
7101
7102

7103
7104
7105


7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
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
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158







-
+

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

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

-


-
-
-





+

-
+


-
+
-

-




-



-
-
+














-












-



-










+
+
+


+







    }
  }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;
    const char *zFile = nArg>=2 ? azArg[1] : "stdout";
    int bTxtMode = 0;
    int i;
    int eMode = 0;
    int bBOM = 0;
    int bOnce = 0;  /* 0: .output, 1: .once, 2: .excel */

    if( c=='e' ){
    if( azArg[0][0]=='e' ){
      eMode = 'x';
      bOnce = 2;
    }else if( strncmp(azArg[0],"once",n)==0 ){
      bOnce = 1;
      /* Transform the ".excel" command into ".once -x" */
      nArg = 2;
      azArg[0] = "once";
      zFile = azArg[1] = "-x";
      n = 4;
    }
    for(i=1; i<nArg; i++){
      char *z = azArg[i];
      if( z[0]=='-' ){
    if( nArg>2 ){
        if( z[1]=='-' ) z++;
        if( strcmp(z,"-bom")==0 ){
          bBOM = 1;
        }else if( c!='e' && strcmp(z,"-x")==0 ){
          eMode = 'x';  /* spreadsheet */
        }else if( c!='e' && strcmp(z,"-e")==0 ){
          eMode = 'e';  /* text editor */
        }else{
          utf8_printf(p->out, "ERROR: unknown option: \"%s\".  Usage:\n",
                      azArg[i]);
          showHelp(p->out, azArg[0]);
          rc = 1;
          goto meta_command_exit;
        }
      utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]);
      rc = 1;
      goto meta_command_exit;
    }
      }else if( zFile==0 && eMode!='e' && eMode!='x' ){
        zFile = sqlite3_mprintf("%s", z);
        if( zFile[0]=='|' ){
    if( n>1 && strncmp(azArg[0], "once", n)==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]);
      if( nArg<2 ){
        showHelp(p->out, azArg[0]);
        raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n");
        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);
    if( zFile[0]=='-' && zFile[1]=='-' ) zFile++;
#ifndef SQLITE_NOHAVE_SYSTEM
    if( eMode=='e' || eMode=='x' ){
    if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){
      p->doXdgOpen = 1;
      outputModePush(p);
      if( eMode=='x' ){
      if( zFile[1]=='x' ){
        /* spreadsheet mode.  Output as CSV. */
        newTempFile(p, "csv");
        ShellClearFlag(p, SHFLG_Echo);
        p->mode = MODE_Csv;
        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);
      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;
#else
      p->out = popen(zFile + 1, "w");
      if( p->out==0 ){
        utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
        p->out = stdout;
        rc = 1;
      }else{
        if( bBOM ) fprintf(p->out,"\357\273\277");
        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
      }
#endif
    }else{
      p->out = output_file_open(zFile, bTxtMode);
      if( p->out==0 ){
        if( strcmp(zFile,"off")!=0 ){
          utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
        }
        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
    ** Clear all bind parameters by dropping the TEMP table that holds them.
    */
    if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
      int wrSchema = 0;
      sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
      sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
      sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
                   0, 0, 0);
      sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
    }else

    /* .parameter list
    ** List all bind parameters.
    */
    if( nArg==2 && strcmp(azArg[1],"list")==0 ){
      sqlite3_stmt *pStmt = 0;
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049


9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
7315
7316
7317
7318
7319
7320
7321








7322
7323








7324
7325
7326
7327
7328
7329
7330







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







    FILE *inSaved = p->in;
    int savedLineno = p->lineno;
    if( nArg!=2 ){
      raw_printf(stderr, "Usage: .read FILE\n");
      rc = 1;
      goto meta_command_exit;
    }
    if( azArg[1][0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
      rc = 1;
      p->out = stdout;
#else
      p->in = popen(azArg[1]+1, "r");
      if( p->in==0 ){
    p->in = fopen(azArg[1], "rb");
    if( p->in==0 ){
        utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
        rc = 1;
      }else{
        rc = process_input(p);
        pclose(p->in);
      }
#endif
    }else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){
      utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
      rc = 1;
    }else{
      rc = process_input(p);
      fclose(p->in);
    }
    p->in = inSaved;
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161

9162
9163
9164
9165
9166
9167

9168
9169

9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180

9181
9182
9183
9184
9185
9186
9187
7398
7399
7400
7401
7402
7403
7404

7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416






7417
7418
7419

7420
7421
7422
7423
7424
7425

7426


7427


7428
7429
7430
7431
7432
7433
7434
7435

7436
7437
7438
7439
7440
7441
7442
7443







-












-
-
-
-
-
-



-
+





-
+
-
-
+
-
-








-
+







    ShellText sSelect;
    ShellState data;
    char *zErrMsg = 0;
    const char *zDiv = "(";
    const char *zName = 0;
    int iSchema = 0;
    int bDebug = 0;
    int bNoSystemTabs = 0;
    int ii;

    open_db(p, 0);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.cMode = data.mode = MODE_Semi;
    initText(&sSelect);
    for(ii=1; ii<nArg; ii++){
      if( optionMatch(azArg[ii],"indent") ){
        data.cMode = data.mode = MODE_Pretty;
      }else if( optionMatch(azArg[ii],"debug") ){
        bDebug = 1;
      }else if( optionMatch(azArg[ii],"nosys") ){
        bNoSystemTabs = 1;
      }else if( azArg[ii][0]=='-' ){
        utf8_printf(stderr, "Unknown option: \"%s\"\n", azArg[ii]);
        rc = 1;
        goto meta_command_exit;
      }else if( zName==0 ){
        zName = azArg[ii];
      }else{
        raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
        raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
        rc = 1;
        goto meta_command_exit;
      }
    }
    if( zName!=0 ){
      int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0
      int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0;
                  || sqlite3_strlike(zName, "sqlite_schema", '\\')==0
                  || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
      if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 ){
                  || sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
      if( isSchema ){
        char *new_argv[2], *new_colv[2];
        new_argv[0] = sqlite3_mprintf(
                      "CREATE TABLE %s (\n"
                      "  type text,\n"
                      "  name text,\n"
                      "  tbl_name text,\n"
                      "  rootpage integer,\n"
                      "  sql text\n"
                      ")", zName);
                      ")", isMaster ? "sqlite_master" : "sqlite_temp_master");
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
        sqlite3_free(new_argv[0]);
      }
    }
9201
9202
9203
9204
9205
9206
9207
9208

9209
9210
9211
9212
9213
9214
9215
9216
9217
9218


9219
9220
9221

9222
9223
9224
9225

9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250

9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270

9271
9272

9273
9274

9275
9276
9277
9278
9279
9280
9281
7457
7458
7459
7460
7461
7462
7463

7464
7465
7466
7467
7468
7469
7470
7471
7472


7473
7474
7475
7476

7477
7478
7479
7480

7481

7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501




7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524

7525

7526
7527
7528
7529
7530
7531
7532
7533
7534







-
+








-
-
+
+


-
+



-
+
-




















-
-
-
-
+




















+

-
+
-

+







        const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
        char zScNum[30];
        sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
        appendText(&sSelect, zDiv, 0);
        zDiv = " UNION ALL ";
        appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
        if( sqlite3_stricmp(zDb, "main")!=0 ){
          appendText(&sSelect, zDb, '\'');
          appendText(&sSelect, zDb, '"');
        }else{
          appendText(&sSelect, "NULL", 0);
        }
        appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
        appendText(&sSelect, zScNum, 0);
        appendText(&sSelect, " AS snum, ", 0);
        appendText(&sSelect, zDb, '\'');
        appendText(&sSelect, " AS sname FROM ", 0);
        appendText(&sSelect, zDb, quoteChar(zDb));
        appendText(&sSelect, ".sqlite_schema", 0);
        appendText(&sSelect, zDb, '"');
        appendText(&sSelect, ".sqlite_master", 0);
      }
      sqlite3_finalize(pStmt);
#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
#ifdef SQLITE_INTROSPECTION_PRAGMAS
      if( zName ){
        appendText(&sSelect,
           " UNION ALL SELECT shell_module_schema(name),"
           " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
           " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0);
        0);
      }
#endif
      appendText(&sSelect, ") WHERE ", 0);
      if( zName ){
        char *zQarg = sqlite3_mprintf("%Q", zName);
        int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
                    strchr(zName, '[') != 0;
        if( strchr(zName, '.') ){
          appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
        }else{
          appendText(&sSelect, "lower(tbl_name)", 0);
        }
        appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
        appendText(&sSelect, zQarg, 0);
        if( !bGlob ){
          appendText(&sSelect, " ESCAPE '\\' ", 0);
        }
        appendText(&sSelect, " AND ", 0);
        sqlite3_free(zQarg);
      }
      if( bNoSystemTabs ){
        appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND ", 0);
      }
      appendText(&sSelect, "sql IS NOT NULL"
      appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
                           " ORDER BY snum, rowid", 0);
      if( bDebug ){
        utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
      }else{
        rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
      }
      freeText(&sSelect);
    }
    if( zErrMsg ){
      utf8_printf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }else if( rc != SQLITE_OK ){
      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 ){
    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
    sqlite3SelectTrace = (int)integerValue(azArg[1]);
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
  }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;
9320
9321
9322
9323
9324
9325
9326
9327

9328
9329
9330
9331
9332
9333
9334
9335
7573
7574
7575
7576
7577
7578
7579

7580

7581
7582
7583
7584
7585
7586
7587







-
+
-







    */
    if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
      FILE *out = 0;
      if( nCmd!=2 ) goto session_syntax_error;
      if( pSession->p==0 ) goto session_not_open;
      out = fopen(azCmd[1], "wb");
      if( out==0 ){
        utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n",
        utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
                    azCmd[1]);
      }else{
        int szChng;
        void *pChng;
        if( azCmd[0][0]=='c' ){
          rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
        }else{
          rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
9642
9643
9644
9645
9646
9647
9648
9649


9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664

9665
9666

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
9700
9701
9702
7894
7895
7896
7897
7898
7899
7900

7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916

7917
7918

7919
7920
7921

7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938


7939
7940
7941
7942
7943
7944
7945
7946
7947

7948
7949
7950
7951
7952
7953
7954
7955
7956







-
+
+














-
+

-
+


-
+
















-
-
+
+







-
+
+







        }else
        if( strcmp(z,"debug")==0 ){
          bDebug = 1;
        }else
        {
          utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
                      azArg[i], azArg[0]);
          showHelp(p->out, azArg[0]);
          raw_printf(stderr, "Should be one of: --schema"
                             " --sha3-224 --sha3-256 --sha3-384 --sha3-512\n");
          rc = 1;
          goto meta_command_exit;
        }
      }else if( zLike ){
        raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
        rc = 1;
        goto meta_command_exit;
      }else{
        zLike = z;
        bSeparate = 1;
        if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1;
      }
    }
    if( bSchema ){
      zSql = "SELECT lower(name) FROM sqlite_schema"
      zSql = "SELECT lower(name) FROM sqlite_master"
             " WHERE type='table' AND coalesce(rootpage,0)>1"
             " UNION ALL SELECT 'sqlite_schema'"
             " UNION ALL SELECT 'sqlite_master'"
             " ORDER BY 1 collate nocase";
    }else{
      zSql = "SELECT lower(name) FROM sqlite_schema"
      zSql = "SELECT lower(name) FROM sqlite_master"
             " WHERE type='table' AND coalesce(rootpage,0)>1"
             " AND name NOT LIKE 'sqlite_%'"
             " ORDER BY 1 collate nocase";
    }
    sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    initText(&sQuery);
    initText(&sSql);
    appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0);
    zSep = "VALUES(";
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      const char *zTab = (const char*)sqlite3_column_text(pStmt,0);
      if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue;
      if( strncmp(zTab, "sqlite_",7)!=0 ){
        appendText(&sQuery,"SELECT * FROM ", 0);
        appendText(&sQuery,zTab,'"');
        appendText(&sQuery," NOT INDEXED;", 0);
      }else if( strcmp(zTab, "sqlite_schema")==0 ){
        appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_schema"
      }else if( strcmp(zTab, "sqlite_master")==0 ){
        appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_master"
                           " ORDER BY name;", 0);
      }else if( strcmp(zTab, "sqlite_sequence")==0 ){
        appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence"
                           " ORDER BY name;", 0);
      }else if( strcmp(zTab, "sqlite_stat1")==0 ){
        appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
                           " ORDER BY tbl,idx;", 0);
      }else if( strcmp(zTab, "sqlite_stat4")==0 ){
      }else if( strcmp(zTab, "sqlite_stat3")==0
             || strcmp(zTab, "sqlite_stat4")==0 ){
        appendText(&sQuery, "SELECT * FROM ", 0);
        appendText(&sQuery, zTab, 0);
        appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
      }
      appendText(&sSql, zSep, 0);
      appendText(&sSql, sQuery.z, '\'');
      sQuery.n = 0;
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
8002
8003
8004
8005
8006
8007
8008

8009
8010
8011
8012
8013
8014
8015







-







    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",
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
9808

9809
9810
9811
9812
9813
9814
9815
8026
8027
8028
8029
8030
8031
8032







8033
8034

8035
8036
8037
8038
8039
8040
8041
8042
8043
8044






8045

8046
8047
8048

8049
8050
8051
8052
8053
8054
8055
8056







-
-
-
-
-
-
-
+

-
+









-
-
-
-
-
-
+
-



-
+







            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: %s\n","stats", azBool[p->statsOn!=0]);
    utf8_printf(p->out, "%12.12s: ", "width");
    for (i=0;i<p->nWidth;i++) {
    for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;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]);
      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");
      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) )
9844
9845
9846
9847
9848
9849
9850
9851

9852
9853
9854
9855
9856
9857
9858
8085
8086
8087
8088
8089
8090
8091

8092
8093
8094
8095
8096
8097
8098
8099







-
+







        appendText(&s, "SELECT name FROM ", 0);
      }else{
        appendText(&s, "SELECT ", 0);
        appendText(&s, zDbName, '\'');
        appendText(&s, "||'.'||name FROM ", 0);
      }
      appendText(&s, zDbName, '"');
      appendText(&s, ".sqlite_schema ", 0);
      appendText(&s, ".sqlite_master ", 0);
      if( c=='t' ){
        appendText(&s," WHERE type IN ('table','view')"
                      "   AND name NOT LIKE 'sqlite_%'"
                      "   AND name LIKE ?1", 0);
      }else{
        appendText(&s," WHERE type='index'"
                      "   AND tbl_name LIKE ?1", 0);
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944





9945
9946
9947
9948
9949
9950
9951






9952
9953

9954
9955
9956
9957
9958





9959
9960
9961
9962
9963
9964
9965
9966
8174
8175
8176
8177
8178
8179
8180





8181
8182
8183
8184
8185







8186
8187
8188
8189
8190
8191
8192

8193
8194




8195
8196
8197
8198
8199

8200
8201
8202
8203
8204
8205
8206







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

-
+

-
-
-
-
+
+
+
+
+
-







#ifndef SQLITE_UNTESTABLE
  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", 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[] = {
      { "always",             SQLITE_TESTCTRL_ALWAYS,        "BOOLEAN"        },
      { "assert",             SQLITE_TESTCTRL_ASSERT,        "BOOLEAN"        },
    /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, ""       },*/
    /*{ "bitvec_test",        SQLITE_TESTCTRL_BITVEC_TEST,   ""             },*/
      { "byteorder",          SQLITE_TESTCTRL_BYTEORDER,     ""               },
      { "always",             SQLITE_TESTCTRL_ALWAYS,        "BOOLEAN"            },
      { "assert",             SQLITE_TESTCTRL_ASSERT,        "BOOLEAN"            },
    /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, ""          },*/
    /*{ "bitvec_test",        SQLITE_TESTCTRL_BITVEC_TEST,   ""                },*/
      { "byteorder",          SQLITE_TESTCTRL_BYTEORDER,     ""                   },
      { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN"   },
    /*{ "fault_install",      SQLITE_TESTCTRL_FAULT_INSTALL, ""             },*/
      { "imposter",         SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
      { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "" },
      { "localtime_fault",    SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN"       },
      { "never_corrupt",      SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN"        },
      { "optimizations",      SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK"   },
    /*{ "fault_install",      SQLITE_TESTCTRL_FAULT_INSTALL, ""                }, */
      { "imposter",           SQLITE_TESTCTRL_IMPOSTER,   "SCHEMA ON/OFF ROOTPAGE"},
      { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN"       },
      { "localtime_fault",    SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN"           },
      { "never_corrupt",      SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN"            },
      { "optimizations",      SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK"       },
#ifdef YYCOVERAGE
      { "parser_coverage",    SQLITE_TESTCTRL_PARSER_COVERAGE, ""             },
      { "parser_coverage",    SQLITE_TESTCTRL_PARSER_COVERAGE, ""                 },
#endif
      { "pending_byte",       SQLITE_TESTCTRL_PENDING_BYTE,  "OFFSET  "       },
      { "prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,  ""               },
      { "prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,     ""               },
      { "prng_seed",          SQLITE_TESTCTRL_PRNG_SEED,     "SEED ?db?"      },
      { "pending_byte",       SQLITE_TESTCTRL_PENDING_BYTE,  "OFFSET  "           },
      { "prng_reset",         SQLITE_TESTCTRL_PRNG_RESET,    ""                   },
      { "prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,  ""                   },
      { "prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,     ""                   },
      { "reserve",            SQLITE_TESTCTRL_RESERVE,       "BYTES-OF-RESERVE"   },
      { "seek_count",         SQLITE_TESTCTRL_SEEK_COUNT,    ""               },
    };
    int testctrl = -1;
    int iCtrl = -1;
    int rc2 = 0;    /* 0: usage.  1: %d  2: %x  3: no-output */
    int isOk = 0;
    int i, n2;
    const char *zCmd = 0;
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
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113

10114
10115
10116
10117
10118
10119
10120
8245
8246
8247
8248
8249
8250
8251
8252
8253

8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279





















8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300






8301
8302
8303
8304
8305
8306
8307
8308
8309
8310








8311
8312
8313
8314
8315
8316
8317
8318
8319
8320

8321
8322
8323
8324
8325
8326
8327
8328







+

-
+








+
















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



+

















-
-
-
-
-
-










-
-
-
-
-
-
-
-










-
+







      utf8_printf(stderr,"Error: unknown test-control: %s\n"
                         "Use \".testctrl --help\" for help\n", zCmd);
    }else{
      switch(testctrl){

        /* sqlite3_test_control(int, db, int) */
        case SQLITE_TESTCTRL_OPTIMIZATIONS:
        case SQLITE_TESTCTRL_RESERVE:
          if( nArg==3 ){
            unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0);
            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:
        case SQLITE_TESTCTRL_PRNG_RESTORE:
        case SQLITE_TESTCTRL_PRNG_RESET:
        case SQLITE_TESTCTRL_BYTEORDER:
          if( nArg==2 ){
            rc2 = sqlite3_test_control(testctrl);
            isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3;
          }
          break;

        /* sqlite3_test_control(int, uint) */
        case SQLITE_TESTCTRL_PENDING_BYTE:
          if( nArg==3 ){
            unsigned int opt = (unsigned int)integerValue(azArg[2]);
            rc2 = sqlite3_test_control(testctrl, opt);
            isOk = 3;
          }
          break;

        /* sqlite3_test_control(int, int, sqlite3*) */
        case SQLITE_TESTCTRL_PRNG_SEED:
          if( nArg==3 || nArg==4 ){
            int ii = (int)integerValue(azArg[2]);
            sqlite3 *db;
            if( ii==0 && strcmp(azArg[2],"random")==0 ){
              sqlite3_randomness(sizeof(ii),&ii);
              printf("-- random seed: %d\n", ii);
            }
            if( nArg==3 ){
              db = 0;
            }else{
              db = p->db;
              /* Make sure the schema has been loaded */
              sqlite3_table_column_metadata(db, 0, "x", 0, 0, 0, 0, 0, 0);
            }
            rc2 = sqlite3_test_control(testctrl, ii, db);
            isOk = 3;
          }
          break;

        /* sqlite3_test_control(int, int) */
        case SQLITE_TESTCTRL_ASSERT:
        case SQLITE_TESTCTRL_ALWAYS:
        case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
          if( nArg==3 ){
            int opt = booleanValue(azArg[2]);
            rc2 = sqlite3_test_control(testctrl, opt);
            isOk = 1;
          }
          break;

        /* sqlite3_test_control(int, int) */
        case SQLITE_TESTCTRL_LOCALTIME_FAULT:
        case SQLITE_TESTCTRL_NEVER_CORRUPT:
          if( nArg==3 ){
            int opt = booleanValue(azArg[2]);
            rc2 = sqlite3_test_control(testctrl, opt);
            isOk = 3;
          }
          break;

        /* sqlite3_test_control(sqlite3*) */
        case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
          rc2 = sqlite3_test_control(testctrl, p->db);
          isOk = 3;
          break;

        case SQLITE_TESTCTRL_IMPOSTER:
          if( nArg==5 ){
            rc2 = sqlite3_test_control(testctrl, p->db,
                          azArg[2],
                          integerValue(azArg[3]),
                          integerValue(azArg[4]));
            isOk = 3;
          }
          break;

        case SQLITE_TESTCTRL_SEEK_COUNT: {
          u64 x = 0;
          rc2 = sqlite3_test_control(testctrl, p->db, &x);
          utf8_printf(p->out, "%llu\n", x);
          isOk = 3;
          break;
        }

#ifdef YYCOVERAGE
        case SQLITE_TESTCTRL_PARSER_COVERAGE:
          if( nArg==2 ){
            sqlite3_test_control(testctrl, p->out);
            isOk = 3;
          }
#endif
      }
    }
    if( isOk==0 && iCtrl>=0 ){
      utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
      utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage);
      rc = 1;
    }else if( isOk==1 ){
      raw_printf(p->out, "%d\n", rc2);
    }else if( isOk==2 ){
      raw_printf(p->out, "0x%08x\n", rc2);
    }
  }else
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230

10231
10232
10233
10234
10235
10236
10237
10238
8392
8393
8394
8395
8396
8397
8398

























8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412

8413

8414
8415
8416
8417
8418
8419
8420







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














-
+
-







    }else{
      if( mType==0 ) mType = SQLITE_TRACE_STMT;
      sqlite3_trace_v2(p->db, mType, sql_trace_callback, p);
    }
  }else
#endif /* !defined(SQLITE_OMIT_TRACE) */

#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
  if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
    int ii;
    int lenOpt;
    char *zOpt;
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
      rc = 1;
      goto meta_command_exit;
    }
    open_db(p, 0);
    zOpt = azArg[1];
    if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
    lenOpt = (int)strlen(zOpt);
    if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
      assert( azArg[nArg]==0 );
      sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
    }else{
      for(ii=1; ii<nArg; ii++){
        sqlite3_create_module(p->db, azArg[ii], 0, 0);
      }
    }
  }else
#endif

#if SQLITE_USER_AUTHENTICATION
  if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
      rc = 1;
      goto meta_command_exit;
    }
    open_db(p, 0);
    if( strcmp(azArg[1],"login")==0 ){
      if( nArg!=4 ){
        raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
        rc = 1;
        goto meta_command_exit;
      }
      rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
      rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3]));
                                     strlen30(azArg[3]));
      if( rc ){
        utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
        rc = 1;
      }
    }else if( strcmp(azArg[1],"add")==0 ){
      if( nArg!=5 ){
        raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
10335
10336
10337
10338
10339
10340
10341

10342
10343

10344
10345

10346
10347
10348
10349
10350
10351
10352
10353
10354

10355
10356
10357
10358
10359
10360
10361
8517
8518
8519
8520
8521
8522
8523
8524
8525

8526

8527
8528
8529
8530
8531
8532





8533
8534
8535
8536
8537
8538
8539
8540







+

-
+
-

+




-
-
-
-
-
+







      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 ){
    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
    sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
  }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();
    if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
    for(j=1; j<nArg; j++){
    for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
      p->colWidth[j-1] = (int)integerValue(azArg[j]);
    }
  }else

  {
    utf8_printf(stderr, "Error: unknown command or invalid arguments: "
      " \"%s\". Enter \".help\" for help\n", azArg[0]);
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
8852
8853
8854
8855
8856
8857
8858

8859
8860



8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877

8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892

8893
8894
8895

8896
8897
8898
8899
8900
8901
8902
8903
8904

8905
8906
8907
8908
8909
8910
8911
8912
8913


8914
8915
8916
8917
8918
8919
8920







-
+

-
-
-

















-















-



-









-









-
-







    sqliterc = zBuf;
  }
  p->in = fopen(sqliterc,"rb");
  if( p->in ){
    if( stdin_is_interactive ){
      utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
    }
    if( process_input(p) && bail_on_error ) exit(1);
    process_input(p);
    fclose(p->in);
  }else if( sqliterc_override!=0 ){
    utf8_printf(stderr,"cannot open: \"%s\"\n", sqliterc);
    if( bail_on_error ) exit(1);
  }
  p->in = inSaved;
  p->lineno = savedLineno;
  sqlite3_free(zBuf);
}

/*
** Show available command line options
*/
static const char zOptions[] =
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
  "   -A ARGS...           run \".archive ARGS\" and exit\n"
#endif
  "   -append              append the database to the end of the file\n"
  "   -ascii               set output mode to 'ascii'\n"
  "   -bail                stop after hitting an error\n"
  "   -batch               force batch I/O\n"
  "   -box                 set output mode to 'box'\n"
  "   -column              set output mode to 'column'\n"
  "   -cmd COMMAND         run \"COMMAND\" before reading stdin\n"
  "   -csv                 set output mode to 'csv'\n"
#if defined(SQLITE_ENABLE_DESERIALIZE)
  "   -deserialize         open the database using sqlite3_deserialize()\n"
#endif
  "   -echo                print commands before execution\n"
  "   -init FILENAME       read/process named file\n"
  "   -[no]header          turn headers on or off\n"
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
  "   -heap SIZE           Size of heap for memsys3 or memsys5\n"
#endif
  "   -help                show this message\n"
  "   -html                set output mode to HTML\n"
  "   -interactive         force interactive I/O\n"
  "   -json                set output mode to 'json'\n"
  "   -line                set output mode to 'line'\n"
  "   -list                set output mode to 'list'\n"
  "   -lookaside SIZE N    use N entries of SZ bytes for lookaside memory\n"
  "   -markdown            set output mode to 'markdown'\n"
#if defined(SQLITE_ENABLE_DESERIALIZE)
  "   -maxsize N           maximum size for a --deserialize database\n"
#endif
  "   -memtrace            trace all memory allocations and deallocations\n"
  "   -mmap N              default mmap size set to N\n"
#ifdef SQLITE_ENABLE_MULTIPLEX
  "   -multiplex           enable the multiplexor VFS\n"
#endif
  "   -newline SEP         set output row separator. Default: '\\n'\n"
  "   -nofollow            refuse to open symbolic links to database files\n"
  "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
  "   -pagecache SIZE N    use N slots of SZ bytes each for page cache memory\n"
  "   -quote               set output mode to 'quote'\n"
  "   -readonly            open the database read-only\n"
  "   -separator SEP       set output column separator. Default: '|'\n"
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
  "   -sorterref SIZE      sorter references threshold size\n"
#endif
  "   -stats               print memory stats before each finalize\n"
  "   -table               set output mode to 'table'\n"
  "   -tabs                set output mode to 'tabs'\n"
  "   -version             show SQLite version\n"
  "   -vfs NAME            use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
  "   -vfstrace            enable tracing of all VFS calls\n"
#endif
#ifdef SQLITE_HAVE_ZLIB
  "   -zip                 open the file as a ZIP Archive\n"
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
8964
8965
8966
8967
8968
8969
8970

8971
8972
8973
8974
8975
8976

8977

8978

8979
8980
8981
8982
8983
8984
8985







-






-

-

-







}

/*
** Output text to the console in a font that attracts extra attention.
*/
#ifdef _WIN32
static void printBold(const char *zText){
#if !SQLITE_OS_WINRT
  HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
  CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
  GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
  SetConsoleTextAttribute(out,
         FOREGROUND_RED|FOREGROUND_INTENSITY
  );
#endif
  printf("%s", zText);
#if !SQLITE_OS_WINRT
  SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
#endif
}
#else
static void printBold(const char *zText){
  printf("\033[1m%s\033[0m", zText);
}
#endif

10827
10828
10829
10830
10831
10832
10833
10834

10835
10836
10837
10838
10839
10840
10841
10842
8993
8994
8995
8996
8997
8998
8999

9000

9001
9002
9003
9004
9005
9006
9007







-
+
-







            argv[0], argv[argc-1]);
    exit(1);
  }
  return argv[i];
}

#ifndef SQLITE_SHELL_IS_UTF8
#  if (defined(_WIN32) || defined(WIN32)) \
#  if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
   && (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
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
9026
9027
9028
9029
9030
9031
9032




9033
9034
9035
9036
9037
9038
9039
9040
9041



9042

9043
9044
9045
9046
9047
9048
9049







-
-
-
-









-
-
-

-







#endif

  setBinaryMode(stdin, 0);
  setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
  stdin_is_interactive = isatty(0);
  stdout_is_console = isatty(1);

#ifdef SQLITE_DEBUG
  registerOomSimulator();
#endif

#if !defined(_WIN32_WCE)
  if( getenv("SQLITE_DEBUG_BREAK") ){
    if( isatty(0) && isatty(2) ){
      fprintf(stderr,
          "attach debugger to process %d and press any key to continue.\n",
          GETPID());
      fgetc(stdin);
    }else{
#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
      __debugbreak();
#else
      DebugBreak();
#endif
#elif defined(SIGTRAP)
      raise(SIGTRAP);
#endif
    }
  }
#endif

10995
10996
10997
10998
10999
11000
11001
11002
11003


11004
11005
11006

11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
9152
9153
9154
9155
9156
9157
9158


9159
9160
9161
9162

9163



9164
9165
9166
9167
9168
9169
9170







-
-
+
+


-
+
-
-
-







      szHeap = integerValue(zSize);
      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
      sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
#else
      (void)cmdline_option_value(argc, argv, ++i);
#endif
    }else if( strcmp(z,"-pagecache")==0 ){
      sqlite3_int64 n, sz;
      sz = integerValue(cmdline_option_value(argc,argv,++i));
      int n, sz;
      sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
      if( sz>70000 ) sz = 70000;
      if( sz<0 ) sz = 0;
      n = integerValue(cmdline_option_value(argc,argv,++i));
      n = (int)integerValue(cmdline_option_value(argc,argv,++i));
      if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
        n = 0xffffffffffffLL/sz;
      }
      sqlite3_config(SQLITE_CONFIG_PAGECACHE,
                    (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
      data.shellFlgs |= SHFLG_Pagecache;
    }else if( strcmp(z,"-lookaside")==0 ){
      int n, sz;
      sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
      if( sz<0 ) sz = 0;
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
9208
9209
9210
9211
9212
9213
9214


9215
9216
9217
9218
9219
9220
9221
9222


9223
9224
9225
9226
9227
9228
9229







-
-








-
-







    }else if( strcmp(z,"-deserialize")==0 ){
      data.openMode = SHELL_OPEN_DESERIALIZE;
    }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
      data.szMax = integerValue(argv[++i]);
#endif
    }else if( strcmp(z,"-readonly")==0 ){
      data.openMode = SHELL_OPEN_READONLY;
    }else if( strcmp(z,"-nofollow")==0 ){
      data.openFlags = SQLITE_OPEN_NOFOLLOW;
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
    }else if( strncmp(z, "-A",2)==0 ){
      /* All remaining command-line arguments are passed to the ".archive"
      ** command, so ignore them */
      break;
#endif
    }else if( strcmp(z, "-memtrace")==0 ){
      sqlite3MemTraceActivate(stderr);
    }else if( strcmp(z,"-bail")==0 ){
      bail_on_error = 1;
    }
  }
  verify_uninitialized();


#ifdef SQLITE_SHELL_INIT_PROC
  {
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
9290
9291
9292
9293
9294
9295
9296


9297
9298
9299
9300








9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317


9318
9319


9320
9321
9322




9323
9324
9325
9326
9327
9328
9329
9330







-
-




-
-
-
-
-
-
-
-

















-
-


-
-
+
+
+
-
-
-
-
+







      i++;
    }else if( strcmp(z,"-html")==0 ){
      data.mode = MODE_Html;
    }else if( strcmp(z,"-list")==0 ){
      data.mode = MODE_List;
    }else if( strcmp(z,"-quote")==0 ){
      data.mode = MODE_Quote;
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma);
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
    }else if( strcmp(z,"-line")==0 ){
      data.mode = MODE_Line;
    }else if( strcmp(z,"-column")==0 ){
      data.mode = MODE_Column;
    }else if( strcmp(z,"-json")==0 ){
      data.mode = MODE_Json;
    }else if( strcmp(z,"-markdown")==0 ){
      data.mode = MODE_Markdown;
    }else if( strcmp(z,"-table")==0 ){
      data.mode = MODE_Table;
    }else if( strcmp(z,"-box")==0 ){
      data.mode = MODE_Box;
    }else if( strcmp(z,"-csv")==0 ){
      data.mode = MODE_Csv;
      memcpy(data.colSeparator,",",2);
#ifdef SQLITE_HAVE_ZLIB
    }else if( strcmp(z,"-zip")==0 ){
      data.openMode = SHELL_OPEN_ZIPFILE;
#endif
    }else if( strcmp(z,"-append")==0 ){
      data.openMode = SHELL_OPEN_APPENDVFS;
#ifdef SQLITE_ENABLE_DESERIALIZE
    }else if( strcmp(z,"-deserialize")==0 ){
      data.openMode = SHELL_OPEN_DESERIALIZE;
    }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
      data.szMax = integerValue(argv[++i]);
#endif
    }else if( strcmp(z,"-readonly")==0 ){
      data.openMode = SHELL_OPEN_READONLY;
    }else if( strcmp(z,"-nofollow")==0 ){
      data.openFlags |= SQLITE_OPEN_NOFOLLOW;
    }else if( strcmp(z,"-ascii")==0 ){
      data.mode = MODE_Ascii;
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit);
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record);
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
                       SEP_Unit);
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
    }else if( strcmp(z,"-tabs")==0 ){
      data.mode = MODE_List;
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Tab);
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
                       SEP_Record);
    }else if( strcmp(z,"-separator")==0 ){
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
                       "%s",cmdline_option_value(argc,argv,++i));
    }else if( strcmp(z,"-newline")==0 ){
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
                       "%s",cmdline_option_value(argc,argv,++i));
    }else if( strcmp(z,"-nullvalue")==0 ){
11212
11213
11214
11215
11216
11217
11218
11219

11220
11221
11222
11223
11224
11225
11226
9348
9349
9350
9351
9352
9353
9354

9355
9356
9357
9358
9359
9360
9361
9362







-
+







      /* Undocumented command-line option: -backslash
      ** Causes C-style backslash escapes to be evaluated in SQL statements
      ** prior to sending the SQL into SQLite.  Useful for injecting
      ** crazy bytes in the middle of SQL statements for testing and debugging.
      */
      ShellSetFlag(&data, SHFLG_Backslash);
    }else if( strcmp(z,"-bail")==0 ){
      /* No-op.  The bail_on_error flag should already be set. */
      bail_on_error = 1;
    }else if( strcmp(z,"-version")==0 ){
      printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
      return 0;
    }else if( strcmp(z,"-interactive")==0 ){
      stdin_is_interactive = 1;
    }else if( strcmp(z,"-batch")==0 ){
      stdin_is_interactive = 0;
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
9436
9437
9438
9439
9440
9441
9442



9443

9444
9445
9446





9447
9448
9449
9450
9451




9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463







-
-
-
+
-



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



+







    /* Run all arguments that do not begin with '-' as if they were separate
    ** command-line inputs, except for the argToSkip argument which contains
    ** the database filename.
    */
    for(i=0; i<nCmd; i++){
      if( azCmd[i][0]=='.' ){
        rc = do_meta_command(azCmd[i], &data);
        if( rc ){
          free(azCmd);
          return rc==2 ? 0 : rc;
        if( rc ) return rc==2 ? 0 : rc;
        }
      }else{
        open_db(&data, 0);
        rc = shell_exec(&data, azCmd[i], &zErrMsg);
        if( zErrMsg || rc ){
          if( zErrMsg!=0 ){
            utf8_printf(stderr,"Error: %s\n", zErrMsg);
          }else{
            utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
        if( zErrMsg!=0 ){
          utf8_printf(stderr,"Error: %s\n", zErrMsg);
          return rc!=0 ? rc : 1;
        }else if( rc!=0 ){
          utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
          }
          sqlite3_free(zErrMsg);
          free(azCmd);
          return rc!=0 ? rc : 1;
          return rc;
        }
      }
    }
    free(azCmd);
  }else{
    /* Run commands received from standard input
    */
    if( stdin_is_interactive ){
      char *zHome;
      char *zHistory;
      int nHistory;
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
9495
9496
9497
9498
9499
9500
9501

9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515

9516
9517
9518
9519
9520







-














-





        free(zHistory);
      }
    }else{
      data.in = stdin;
      rc = process_input(&data);
    }
  }
  free(azCmd);
  set_table_name(&data, 0);
  if( data.db ){
    session_close_all(&data);
    close_db(data.db);
  }
  sqlite3_free(data.zFreeOnClose);
  find_home_dir(1);
  output_reset(&data);
  data.doXdgOpen = 0;
  clearTempFile(&data);
#if !SQLITE_SHELL_IS_UTF8
  for(i=0; i<argcToFree; i++) free(argvToFree[i]);
  free(argvToFree);
#endif
  free(data.colWidth);
  /* Clear the global data structure so that valgrind will detect memory
  ** leaks */
  memset(&data, 0, sizeof(data));
  return rc;
}

Changes to src/sqlite.h.in.

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







-
-
-
-

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







**
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
** for the [sqlite3] object.
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
** Ideally, applications should [sqlite3_finalize | finalize] all
** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and 
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
** with the [sqlite3] object prior to attempting to close the object.
** ^If the database connection is associated with unfinalized prepared
** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
** sqlite3_close() will leave the database connection open and return
** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
** statements or unfinished sqlite3_backup objects then sqlite3_close()
** will leave the database connection open and return [SQLITE_BUSY].
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
** and/or unfinished sqlite3_backups, then the database connection becomes
** it returns [SQLITE_OK] regardless, but instead of deallocating the database
** connection immediately, it marks the database connection as an unusable
** an unusable "zombie" which will automatically be deallocated when the
** "zombie" and makes arrangements to automatically deallocate the database
** connection after all prepared statements are finalized, all BLOB handles
** are closed, and all backups have finished. The sqlite3_close_v2() interface
** is intended for use with host languages that are garbage collected, and
** where the order in which destructors are called is arbitrary.
** last prepared statement is finalized or the last sqlite3_backup is
** finished.  The sqlite3_close_v2() interface is intended for use with
** host languages that are garbage collected, and where the order in which
** destructors are called is arbitrary.
**
** Applications should [sqlite3_finalize | finalize] all [prepared statements],
** [sqlite3_blob_close | close] all [BLOB handles], and 
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
** with the [sqlite3] object prior to attempting to close the object.  ^If
** sqlite3_close_v2() is called on a [database connection] that still has
** outstanding [prepared statements], [BLOB handles], and/or
** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
** of resources is deferred until all [prepared statements], [BLOB handles],
** and [sqlite3_backup] objects are also destroyed.
**
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
**
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
** must be either a NULL
** pointer or an [sqlite3] object pointer obtained
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
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







-
-




-





-


-

















-





-







#define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
#define SQLITE_IOERR_VNODE             (SQLITE_IOERR | (27<<8))
#define SQLITE_IOERR_AUTH              (SQLITE_IOERR | (28<<8))
#define SQLITE_IOERR_BEGIN_ATOMIC      (SQLITE_IOERR | (29<<8))
#define SQLITE_IOERR_COMMIT_ATOMIC     (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC   (SQLITE_IOERR | (31<<8))
#define SQLITE_IOERR_DATA              (SQLITE_IOERR | (32<<8))
#define SQLITE_IOERR_CORRUPTFS         (SQLITE_IOERR | (33<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_LOCKED_VTAB             (SQLITE_LOCKED |  (2<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
#define SQLITE_BUSY_TIMEOUT            (SQLITE_BUSY   |  (3<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CANTOPEN_DIRTYWAL       (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
#define SQLITE_CANTOPEN_SYMLINK        (SQLITE_CANTOPEN | (6<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_CORRUPT_SEQUENCE        (SQLITE_CORRUPT | (2<<8))
#define SQLITE_CORRUPT_INDEX           (SQLITE_CORRUPT | (3<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED        (SQLITE_READONLY | (4<<8))
#define SQLITE_READONLY_CANTINIT       (SQLITE_READONLY | (5<<8))
#define SQLITE_READONLY_DIRECTORY      (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))
#define SQLITE_CONSTRAINT_FOREIGNKEY   (SQLITE_CONSTRAINT | (3<<8))
#define SQLITE_CONSTRAINT_FUNCTION     (SQLITE_CONSTRAINT | (4<<8))
#define SQLITE_CONSTRAINT_NOTNULL      (SQLITE_CONSTRAINT | (5<<8))
#define SQLITE_CONSTRAINT_PRIMARYKEY   (SQLITE_CONSTRAINT | (6<<8))
#define SQLITE_CONSTRAINT_TRIGGER      (SQLITE_CONSTRAINT | (7<<8))
#define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
#define SQLITE_CONSTRAINT_PINNED       (SQLITE_CONSTRAINT |(11<<8))
#define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8))

/*
** CAPI3REF: Flags For File Open Operations
**
** These bit values are intended for use in the
** 3rd parameter to the [sqlite3_open_v2()] interface and
** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
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
558
559
560
561
562
563
564

565
566
567
568
569
570

571
572



573
574
575
576
577
578
579







-
+





-


-
-
-







#define SQLITE_OPEN_MEMORY           0x00000080  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_MAIN_DB          0x00000100  /* VFS only */
#define SQLITE_OPEN_TEMP_DB          0x00000200  /* VFS only */
#define SQLITE_OPEN_TRANSIENT_DB     0x00000400  /* VFS only */
#define SQLITE_OPEN_MAIN_JOURNAL     0x00000800  /* VFS only */
#define SQLITE_OPEN_TEMP_JOURNAL     0x00001000  /* VFS only */
#define SQLITE_OPEN_SUBJOURNAL       0x00002000  /* VFS only */
#define SQLITE_OPEN_SUPER_JOURNAL    0x00004000  /* VFS only */
#define SQLITE_OPEN_MASTER_JOURNAL   0x00004000  /* VFS only */
#define SQLITE_OPEN_NOMUTEX          0x00008000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_FULLMUTEX        0x00010000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_SHAREDCACHE      0x00020000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_WAL              0x00080000  /* VFS only */
#define SQLITE_OPEN_NOFOLLOW         0x01000000  /* Ok for sqlite3_open_v2() */

/* Reserved:                         0x00F00000 */
/* Legacy compatibility: */
#define SQLITE_OPEN_MASTER_JOURNAL   0x00004000  /* VFS only */


/*
** CAPI3REF: Device Characteristics
**
** The xDeviceCharacteristics method of the [sqlite3_io_methods]
** object returns an integer which is a vector of these
** bit values expressing I/O characteristics of the mass storage
870
871
872
873
874
875
876
877

878
879
880
881
882
883
884
863
864
865
866
867
868
869

870
871
872
873
874
875
876
877







-
+







** sent to the VFS immediately before the xSync method is invoked on a
** database file descriptor. Or, if the xSync method is not invoked 
** because the user has configured SQLite with 
** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place 
** of the xSync method. In most cases, the pointer argument passed with
** this file-control is NULL. However, if the database file is being synced
** as part of a multi-database commit, the argument points to a nul-terminated
** string containing the transactions super-journal file name. VFSes that 
** string containing the transactions master-journal file name. VFSes that 
** do not need this signal should silently ignore this opcode. Applications 
** should not call [sqlite3_file_control()] with this opcode as doing so may 
** disrupt the operation of the specialized VFSes that do require it.  
**
** <li>[[SQLITE_FCNTL_COMMIT_PHASETWO]]
** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite
** and sent to the VFS after a transaction has been committed immediately
982
983
984
985
986
987
988
989

990
991

992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
975
976
977
978
979
980
981

982
983

984
985
986
987
988
989
990

991
992
993
994
995
996
997
998







-
+

-
+






-
+







** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements.
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^The [SQLITE_FCNTL_BUSYHANDLER]
** file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
** to the connection's busy-handler callback. The argument is of type (void**)
** to the connections busy-handler callback. The argument is of type (void **)
** - an array of two (void *) values. The first (void *) actually points
** to a function of type (int (*)(void *)). In order to invoke the connection's
** to a function of type (int (*)(void *)). In order to invoke the connections
** busy-handler, this function should be invoked with the second (void *) in
** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the
** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
** ^Applications can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control
** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control
** to have SQLite generate a
** temporary filename using the same algorithm that is followed to generate
** temporary filenames for TEMP tables and other internal uses.  The
** argument should be a char** which will be filled with the filename
** written into memory obtained from [sqlite3_malloc()].  The caller should
** invoke [sqlite3_free()] on the result to avoid a memory leak.
**
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
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







-
+
-
-
-
+
+
+
-
-














-
+





-
-
-
-
-
-
-
-
-
-
-







** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
** ^This file control takes the file descriptor out of batch write mode
** so that all subsequent write operations are independent.
** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
**
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
** to block for up to M milliseconds before failing when attempting to 
** obtain a file lock using the xLock or xShmLock methods of the VFS. 
** The parameter is a pointer to a 32-bit signed integer that contains
** a file lock using the xLock or xShmLock methods of the VFS to wait
** for up to M milliseconds before failing, where M is the single 
** unsigned integer parameter.
** the value that M is to be set to. Before returning, the 32-bit signed
** integer is overwritten with the previous value of M.
**
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
** a database file.  The argument is a pointer to a 32-bit unsigned integer.
** The "data version" for the pager is written into the pointer.  The
** "data version" changes whenever any change occurs to the corresponding
** database file, either through SQL statements on the same database
** connection or through transactions committed by separate database
** connections possibly in other processes. The [sqlite3_total_changes()]
** interface can be used to find if any database on the connection has changed,
** but that interface responds to changes on TEMP as well as MAIN and does
** not provide a mechanism to detect changes to MAIN only.  Also, the
** [sqlite3_total_changes()] interface responds to internal changes only and
** omits changes made by other database connections.  The
** [PRAGMA data_version] command provides a mechanism to detect changes to
** [PRAGMA data_version] command provide a mechanism to detect changes to
** a single attached database that occur due to other database connections,
** but omits changes implemented by the database connection on which it is
** called.  This file control is the only mechanism to detect changes that
** happen either internally or externally and that are associated with
** a particular attached database.
**
** <li>[[SQLITE_FCNTL_CKPT_START]]
** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
** in wal mode before the client starts to copy pages from the wal
** file to the database file.
**
** <li>[[SQLITE_FCNTL_CKPT_DONE]]
** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
** in wal mode after the client has finished copying pages from the wal
** file to the database file, but before the *-shm file is updated to
** record the fact that the pages have been checkpointed.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
#define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
#define SQLITE_FCNTL_LAST_ERRNO              4
#define SQLITE_FCNTL_SIZE_HINT               5
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1140
1141
1142
1143
1144
1145
1146



1147
1148
1149
1150
1151
1152
1153







-
-
-







#define SQLITE_FCNTL_PDB                    30
#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE     31
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE    32
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
#define SQLITE_FCNTL_LOCK_TIMEOUT           34
#define SQLITE_FCNTL_DATA_VERSION           35
#define SQLITE_FCNTL_SIZE_LIMIT             36
#define SQLITE_FCNTL_CKPT_DONE              37
#define SQLITE_FCNTL_RESERVE_BYTES          38
#define SQLITE_FCNTL_CKPT_START             39

/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
#define SQLITE_SET_LOCKPROXYFILE      SQLITE_FCNTL_SET_LOCKPROXYFILE
#define SQLITE_LAST_ERRNO             SQLITE_FCNTL_LAST_ERRNO


1208
1209
1210
1211
1212
1213
1214
1215
1216


1217
1218

1219
1220
1221
1222
1223
1224
1225
1185
1186
1187
1188
1189
1190
1191


1192
1193
1194

1195
1196
1197
1198
1199
1200
1201
1202







-
-
+
+

-
+







** the end.  Each time such an extension occurs, the iVersion field
** is incremented.  The iVersion value started out as 1 in
** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6].  Additional fields
** may be appended to the sqlite3_vfs object and the iVersion value
** may increase again in future versions of SQLite.
** Note that due to an oversight, the structure
** of the sqlite3_vfs object changed in the transition from
** Note that the structure
** of the sqlite3_vfs object changes in the transition from
** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
** and yet the iVersion field was not increased.
** and yet the iVersion field was not modified.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
** structure used by this VFS.  mxPathname is the maximum length of
** a pathname in this VFS.
**
** Registered sqlite3_vfs objects are kept on a linked list formed by
** the pNext pointer.  The [sqlite3_vfs_register()]
1267
1268
1269
1270
1271
1272
1273
1274

1275
1276
1277
1278
1279
1280
1281
1244
1245
1246
1247
1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1258







-
+







** <ul>
** <li>  [SQLITE_OPEN_MAIN_DB]
** <li>  [SQLITE_OPEN_MAIN_JOURNAL]
** <li>  [SQLITE_OPEN_TEMP_DB]
** <li>  [SQLITE_OPEN_TEMP_JOURNAL]
** <li>  [SQLITE_OPEN_TRANSIENT_DB]
** <li>  [SQLITE_OPEN_SUBJOURNAL]
** <li>  [SQLITE_OPEN_SUPER_JOURNAL]
** <li>  [SQLITE_OPEN_MASTER_JOURNAL]
** <li>  [SQLITE_OPEN_WAL]
** </ul>)^
**
** The file I/O implementation can use the object type flags to
** change the way it deals with files.  For example, an application
** that does not care about crash recovery or rollback might make
** the open of a journal file a no-op.  Writes to this journal would
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
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







-
+












-
+
-
-
-
+
-
-
-
-







** API.  The SQLITE_OPEN_EXCLUSIVE flag, when paired with the 
** SQLITE_OPEN_CREATE, is used to indicate that file should always
** be created, and that it is an error if it already exists.
** It is <i>not</i> used to indicate the file should be opened 
** for exclusive access.
**
** ^At least szOsFile bytes of memory are allocated by SQLite
** to hold the [sqlite3_file] structure passed as the third
** to hold the  [sqlite3_file] structure passed as the third
** argument to xOpen.  The xOpen method does not have to
** allocate the structure; it should just fill it in.  Note that
** the xOpen method must set the sqlite3_file.pMethods to either
** a valid [sqlite3_io_methods] object or to NULL.  xOpen must do
** this even if the open fails.  SQLite expects that the sqlite3_file.pMethods
** element will be valid after xOpen returns regardless of the success
** or failure of the xOpen call.
**
** [[sqlite3_vfs.xAccess]]
** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
** to test whether a file is at least readable.  The SQLITE_ACCESS_READ
** to test whether a file is at least readable.   The file can be a
** flag is never actually used and is not implemented in the built-in
** VFSes of SQLite.  The file is named by the second argument and can be a
** directory. The xAccess method returns [SQLITE_OK] on success or some
** directory.
** non-zero error code if there is an I/O error or if the name of
** the file given in the second argument is illegal.  If SQLITE_OK
** is returned, then non-zero or zero is written into *pResOut to indicate
** whether or not the file is accessible.  
**
** ^SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname.  The exact size of the output buffer
** is also passed as a parameter to both  methods. If the output buffer
** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
** handled as a fatal error by SQLite, vfs implementations should endeavor
** to prevent this by setting mxPathname to a sufficiently large value.
1639
1640
1641
1642
1643
1644
1645
1646

1647
1648
1649
1650
1651
1652

1653
1654
1655
1656
1657
1658
1659
1610
1611
1612
1613
1614
1615
1616

1617
1618
1619
1620
1621
1622

1623
1624
1625
1626
1627
1628
1629
1630







-
+





-
+







** allocators round up memory allocations at least to the next multiple
** of 8.  Some allocators round up to a larger multiple or to a power of 2.
** Every memory allocation request coming in through [sqlite3_malloc()]
** or [sqlite3_realloc()] first calls xRoundup.  If xRoundup returns 0, 
** that causes the corresponding memory allocation to fail.
**
** The xInit method initializes the memory allocator.  For example,
** it might allocate any required mutexes or initialize internal data
** it might allocate any require mutexes or initialize internal data
** structures.  The xShutdown method is invoked (indirectly) by
** [sqlite3_shutdown()] and should deallocate any resources acquired
** by xInit.  The pAppData pointer is used as the only parameter to
** xInit and xShutdown.
**
** SQLite holds the [SQLITE_MUTEX_STATIC_MAIN] mutex when it invokes
** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
** the xInit method, so the xInit method need not be threadsafe.  The
** xShutdown method is only called from [sqlite3_shutdown()] so it does
** not need to be threadsafe either.  For all other methods, SQLite
** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
** it is by default) and so the methods are automatically serialized.
** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
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
1732
1733
1734
1735
1736
1737
1738

1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
1764







-


















-
+







**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
** memory allocation statistics. ^(When memory allocation statistics are
** disabled, the following SQLite interfaces become non-operational:
**   <ul>
**   <li> [sqlite3_hard_heap_limit64()]
**   <li> [sqlite3_memory_used()]
**   <li> [sqlite3_memory_highwater()]
**   <li> [sqlite3_soft_heap_limit64()]
**   <li> [sqlite3_status64()]
**   </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
** allocation statistics are disabled by default.
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
** that SQLite can use for the database page cache with the default page
** cache implementation.  
** This configuration option is a no-op if an application-defined page
** This configuration option is a no-op if an application-define page
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
** 8-byte aligned memory (pMem), the size of each page cache line (sz),
** and the number of cache lines (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 65536) plus some extra bytes for each
** page header.  ^The number of extra bytes needed by the page header
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
2081
2082
2083
2084
2085
2086
2087

2088























2089
2090
2091
2092
2093
2094
2095







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







** <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.
** which case the trigger setting is not reported back. </dd>
**
** <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.
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360

2361
2362
2363
2364
2365
2366
2367
2194
2195
2196
2197
2198
2199
2200

2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215






































































2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229







2230
2231
2232
2233
2234
2235
2236
2237







-















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














-
-
-
-
-
-
-
+







** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
** "defensive" flag for a database connection.  When the defensive
** flag is enabled, language features that allow ordinary SQL to 
** deliberately corrupt the database file are disabled.  The disabled
** features include but are not limited to the following:
** <ul>
** <li> The [PRAGMA writable_schema=ON] statement.
** <li> The [PRAGMA journal_mode=OFF] statement.
** <li> Writes to the [sqlite_dbpage] virtual table.
** <li> Direct writes to [shadow tables].
** </ul>
** </dd>
**
** [[SQLITE_DBCONFIG_WRITABLE_SCHEMA]] <dt>SQLITE_DBCONFIG_WRITABLE_SCHEMA</dt>
** <dd>The SQLITE_DBCONFIG_WRITABLE_SCHEMA option activates or deactivates the
** "writable_schema" flag. This has the same effect and is logically equivalent
** to setting [PRAGMA writable_schema=ON] or [PRAGMA writable_schema=OFF].
** The first argument to this setting is an integer which is 0 to disable 
** the writable_schema, positive to enable writable_schema, 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 the writable_schema
** is enabled or disabled following this call.
** </dd>
**
** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]]
** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt>
** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates
** the legacy behavior of the [ALTER TABLE RENAME] command such it
** behaves as it did prior to [version 3.24.0] (2018-06-04).  See the
** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for
** additional information. This feature can also be turned on and off
** using the [PRAGMA legacy_alter_table] statement.
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DML]]
** <dt>SQLITE_DBCONFIG_DQS_DML</td>
** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DML statements
** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
** default value of this setting is determined by the [-DSQLITE_DQS]
** compile-time option.
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DDL]]
** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DDL statements,
** such as CREATE TABLE and CREATE INDEX. The
** default value of this setting is determined by the [-DSQLITE_DQS]
** compile-time option.
** </dd>
**
** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
** assume that database schemas are untainted by malicious content.
** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
** takes additional defensive steps to protect the application from harm
** including:
** <ul>
** <li> Prohibit the use of SQL functions inside triggers, views,
** CHECK constraints, DEFAULT clauses, expression indexes, 
** partial indexes, or generated columns
** unless those functions are tagged with [SQLITE_INNOCUOUS].
** <li> Prohibit the use of virtual tables inside of triggers or views
** unless those virtual tables are tagged with [SQLITE_VTAB_INNOCUOUS].
** </ul>
** This setting defaults to "on" for legacy compatibility, however
** all applications are advised to turn it off if possible. This setting
** can also be controlled using the [PRAGMA trusted_schema] statement.
** </dd>
**
** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]]
** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</td>
** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates
** the legacy file format flag.  When activated, this flag causes all newly
** created database file to have a schema format version number (the 4-byte
** integer found at offset 44 into the database header) of 1.  This in turn
** means that the resulting database file will be readable and writable by
** any SQLite version back to 3.0.0 ([dateof:3.0.0]).  Without this setting,
** newly created databases are generally not understandable by SQLite versions
** prior to 3.3.0 ([dateof:3.3.0]).  As these words are written, there
** is now scarcely any need to generated database files that are compatible 
** all the way back to version 3.0.0, and so this setting is of little
** practical use, but is provided so that SQLite can continue to claim the
** ability to generate new database files that are compatible with  version
** 3.0.0.
** <p>Note that when the SQLITE_DBCONFIG_LEGACY_FILE_FORMAT setting is on,
** the [VACUUM] command will fail with an obscure error when attempting to
** process a table with generated columns and a descending index.  This is
** not considered a bug since SQLite versions 3.3.0 and earlier do not support
** either generated columns or decending indexes.
** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
#define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
#define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
#define SQLITE_DBCONFIG_WRITABLE_SCHEMA       1011 /* int int* */
#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    1012 /* int int* */
#define SQLITE_DBCONFIG_DQS_DML               1013 /* int int* */
#define SQLITE_DBCONFIG_DQS_DDL               1014 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */
#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    1016 /* int int* */
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA        1017 /* int int* */
#define SQLITE_DBCONFIG_MAX                   1017 /* Largest DBCONFIG */
#define SQLITE_DBCONFIG_MAX                   1011 /* Largest DBCONFIG */

/*
** CAPI3REF: Enable Or Disable Extended Result Codes
** METHOD: sqlite3
**
** ^The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. ^The extended result
2559
2560
2561
2562
2563
2564
2565
2566

2567
2568
2569
2570
2571
2572
2573
2429
2430
2431
2432
2433
2434
2435

2436
2437
2438
2439
2440
2441
2442
2443







-
+







** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
** that is inside an explicit transaction, then the entire transaction
** will be rolled back automatically.
**
** ^The sqlite3_interrupt(D) call is in effect until all currently running
** SQL statements on [database connection] D complete.  ^Any new SQL statements
** that are started after the sqlite3_interrupt() call and before the 
** running statement count reaches zero are interrupted as if they had been
** running statements reaches zero are interrupted as if they had been
** running prior to the sqlite3_interrupt() call.  ^New SQL statements
** that are started after the running statement count reaches zero are
** not effected by the sqlite3_interrupt().
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
*/
2727
2728
2729
2730
2731
2732
2733
2734

2735
2736

2737
2738
2739
2740
2741
2742
2743
2597
2598
2599
2600
2601
2602
2603

2604
2605

2606
2607
2608
2609
2610
2611
2612
2613







-
+

-
+







**        Name        | Age
**        -----------------------
**        Alice       | 43
**        Bob         | 28
**        Cindy       | 21
** </pre></blockquote>
**
** There are two columns (M==2) and three rows (N==3).  Thus the
** There are two column (M==2) and three rows (N==3).  Thus the
** result table has 8 entries.  Suppose the result table is stored
** in an array named azResult.  Then azResult holds this content:
** in an array names azResult.  Then azResult holds this content:
**
** <blockquote><pre>
**        azResult&#91;0] = "Name";
**        azResult&#91;1] = "Age";
**        azResult&#91;2] = "Alice";
**        azResult&#91;3] = "43";
**        azResult&#91;4] = "Bob";
2822
2823
2824
2825
2826
2827
2828
2829

2830
2831
2832
2833
2834
2835
2836
2692
2693
2694
2695
2696
2697
2698

2699
2700
2701
2702
2703
2704
2705
2706







-
+







char *sqlite3_vsnprintf(int,char*,const char*, va_list);

/*
** CAPI3REF: Memory Allocation Subsystem
**
** The SQLite core uses these three routines for all of its own
** internal memory allocation needs. "Core" in the previous sentence
** does not include operating-system specific [VFS] implementation.  The
** does not include operating-system specific VFS implementation.  The
** Windows VFS uses native malloc() and free() for some operations.
**
** ^The sqlite3_malloc() routine returns a pointer to a block
** of memory at least N bytes in length, where N is the parameter.
** ^If sqlite3_malloc() is unable to obtain sufficient free
** memory, it returns a NULL pointer.  ^If the parameter N to
** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
2882
2883
2884
2885
2886
2887
2888













2889
2890
2891
2892
2893
2894
2895
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778







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







** of sqlite3_msize(X) is undefined and possibly harmful.
**
** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(),
** sqlite3_malloc64(), and sqlite3_realloc64()
** is always aligned to at least an 8 byte boundary, or to a
** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
** option is used.
**
** In SQLite version 3.5.0 and 3.5.1, it was possible to define
** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
** implementation of these routines to be omitted.  That capability
** is no longer provided.  Only built-in memory allocators can be used.
**
** Prior to SQLite version 3.7.10, the Windows OS interface layer called
** the system malloc() and free() directly when converting
** filenames between the UTF-8 encoding used by SQLite
** and whatever filename encoding is used by the particular Windows
** installation.  Memory allocation errors were detected, but
** they were reported back as [SQLITE_CANTOPEN] or
** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
**
** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
** must be either NULL or else pointers obtained from a prior
** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
** not yet been released.
**
** The application must not read or write any part of
2931
2932
2933
2934
2935
2936
2937
2938

2939
2940
2941
2942
2943
2944
2945
2814
2815
2816
2817
2818
2819
2820

2821
2822
2823
2824
2825
2826
2827
2828







-
+








/*
** CAPI3REF: Pseudo-Random Number Generator
**
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random [ROWID | ROWIDs] when inserting new records into a table that
** already uses the largest possible [ROWID].  The PRNG is also used for
** the built-in random() and randomblob() SQL functions.  This interface allows
** the build-in random() and randomblob() SQL functions.  This interface allows
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
** ^The P parameter can be a NULL pointer.
**
** ^If this routine has not been previously called or if the previous
** call had N less than one or a NULL pointer for P, then the PRNG is
3305
3306
3307
3308
3309
3310
3311
3312
3313




3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332


3333
3334
3335

3336
3337
3338
3339
3340
3341
3342

3343
3344

3345
3346

3347
3348
3349
3350


3351
3352

3353
3354
3355
3356
3357


3358
3359
3360


3361
3362

3363
3364

3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3188
3189
3190
3191
3192
3193
3194


3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215


3216
3217



3218







3219
3220

3221


3222




3223
3224


3225





3226
3227



3228
3229


3230


3231










3232
3233
3234
3235
3236
3237
3238







-
-
+
+
+
+

















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

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







** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
** passing it to [sqlite3_close()] when it is no longer required.
**
** The sqlite3_open_v2() interface works like sqlite3_open()
** except that it accepts two additional parameters for additional control
** over the new database connection.  ^(The flags parameter to
** sqlite3_open_v2() must include, at a minimum, one of the following
** three flag combinations:)^
** sqlite3_open_v2() can take one of
** the following three values, optionally combined with the 
** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^
**
** <dl>
** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
** <dd>The database is opened in read-only mode.  If the database does not
** already exist, an error is returned.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
** <dd>The database is opened for reading and writing if possible, or reading
** only if the file is write protected by the operating system.  In either
** case the database must already exist, otherwise an error is returned.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
** <dd>The database is opened for reading and writing, and is created if
** it does not already exist. This is the behavior that is always used for
** sqlite3_open() and sqlite3_open16().</dd>)^
** </dl>
**
** In addition to the required flags, the following optional flags are
** also supported:
** If the 3rd parameter to sqlite3_open_v2() is not one of the
** combinations shown above optionally combined with other
**
** <dl>
** ^(<dt>[SQLITE_OPEN_URI]</dt>
** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
** <dd>The filename can be interpreted as a URI if this flag is set.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_MEMORY]</dt>
** <dd>The database will be opened as an in-memory database.  The database
** is named by the "filename" argument for the purposes of cache-sharing,
** if shared cache mode is enabled, but the "filename" is otherwise ignored.
** </dd>)^
** then the behavior is undefined.
**
** ^(<dt>[SQLITE_OPEN_NOMUTEX]</dt>
** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
** <dd>The new database connection will use the "multi-thread"
** [threading mode].)^  This means that separate threads are allowed
** opens in the multi-thread [threading mode] as long as the single-thread
** to use SQLite at the same time, as long as each thread is using
** a different [database connection].
**
** ^(<dt>[SQLITE_OPEN_FULLMUTEX]</dt>
** mode has not been set at compile-time or start-time.  ^If the
** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
** <dd>The new database connection will use the "serialized"
** [threading mode].)^  This means the multiple threads can safely
** in the serialized [threading mode] unless single-thread was
** attempt to use the same database connection at the same time.
** (Mutexes will block any actual concurrency, but in this mode
** there is no harm in trying.)
**
** ^(<dt>[SQLITE_OPEN_SHAREDCACHE]</dt>
** previously selected at compile-time or start-time.
** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
** <dd>The database is opened [shared cache] enabled, overriding
** the default shared cache setting provided by
** [sqlite3_enable_shared_cache()].)^
** eligible to use [shared cache mode], regardless of whether or not shared
** cache is enabled using [sqlite3_enable_shared_cache()].  ^The
**
** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
** <dd>The database is opened [shared cache] disabled, overriding
** the default shared cache setting provided by
** participate in [shared cache mode] even if it is enabled.
** [sqlite3_enable_shared_cache()].)^
**
** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
** <dd>The database filename is not allowed to be a symbolic link</dd>
** </dl>)^
**
** If the 3rd parameter to sqlite3_open_v2() is not one of the
** required combinations shown above optionally combined with other
** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
** then the behavior is undefined.
**
** ^The fourth parameter to sqlite3_open_v2() is the name of the
** [sqlite3_vfs] object that defines the operating system interface that
** the new database connection should use.  ^If the fourth parameter is
** a NULL pointer then the default [sqlite3_vfs] object is used.
**
** ^If the filename is ":memory:", then a private, temporary in-memory database
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3364
3365
3366
3367
3368
3369
3370

3371
3372
3373
3374
3375
3376
3377







-







**          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 
3549
3550
3551
3552
3553
3554
3555
3556
3557


3558
3559
3560
3561
3562
3563
3564


3565
3566
3567
3568

3569
3570
3571
3572
3573

3574
3575
3576

3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588

3589
3590
3591
3592
3593
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
3405
3406
3407
3408
3409
3410
3411


3412
3413
3414
3415





3416
3417




3418





3419
3420
3421

3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433

3434
3435
3436
3437
3438
3439
3440







3441
3442
3443



3444
3445
3446
3447








3448
3449
3450
3451
3452

3453







































































































3454
3455
3456
3457
3458
3459
3460







-
-
+
+


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


-
+











-
+






-
-
-
-
-
-
-



-
-
-
+
+
+

-
-
-
-
-
-
-
-





-

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







  int flags,              /* Flags */
  const char *zVfs        /* Name of VFS module to use */
);

/*
** CAPI3REF: Obtain Values For URI Parameters
**
** These are utility routines, useful to [VFS|custom VFS implementations],
** that check if a database file was a URI that contained a specific query 
** These are utility routines, useful to VFS implementations, that check
** to see if a database file was a URI that contained a specific query 
** parameter, and if so obtains the value of that query parameter.
**
** The first parameter to these interfaces (hereafter referred to
** as F) must be one of:
** <ul>
** <li> A database filename pointer created by the SQLite core and
** passed into the xOpen() method of a VFS implemention, or
** If F is the database filename pointer passed into the xOpen() method of 
** a VFS implementation when the flags parameter to xOpen() has one or 
** <li> A filename obtained from [sqlite3_db_filename()], or
** <li> A new filename constructed using [sqlite3_create_filename()].
** </ul>
** If the F parameter is not one of the above, then the behavior is
** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and
** undefined and probably undesirable.  Older versions of SQLite were
** more tolerant of invalid F parameters than newer versions.
**
** If F is a suitable filename (as described in the previous paragraph)
** and if P is the name of the query parameter, then
** P is the name of the query parameter, then
** sqlite3_uri_parameter(F,P) returns the value of the P
** parameter if it exists or a NULL pointer if P does not appear as a 
** query parameter on F.  If P is a query parameter of F and it
** query parameter on F.  If P is a query parameter of F
** has no explicit value, then sqlite3_uri_parameter(F,P) returns
** a pointer to an empty string.
**
** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
** parameter and returns true (1) or false (0) according to the value
** of P.  The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the
** value of query parameter P is one of "yes", "true", or "on" in any
** case or if the value begins with a non-zero number.  The 
** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
** query parameter P is one of "no", "false", or "off" in any case or
** if the value begins with a numeric zero.  If P is not a query
** parameter on F or if the value of P does not match any of the
** parameter on F or if the value of P is does not match any of the
** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
**
** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
** 64-bit signed integer and returns that integer, or D if P does not
** exist.  If the value of P is something other than an integer, then
** zero is returned.
**
** The sqlite3_uri_key(F,N) returns a pointer to the name (not
** the value) of the N-th query parameter for filename F, or a NULL
** pointer if N is less than zero or greater than the number of query
** parameters minus 1.  The N value is zero-based so N should be 0 to obtain
** the name of the first query parameter, 1 for the second parameter, and
** so forth.
** 
** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
** sqlite3_uri_boolean(F,P,B) returns B.  If F is not a NULL pointer and
** is not a database file pathname pointer that the SQLite core passed
** into the xOpen VFS method, then the behavior of this routine is undefined
** and probably undesirable.
** is not a database file pathname pointer that SQLite passed into the xOpen
** VFS method, then the behavior of this routine is undefined and probably
** undesirable.
**
** Beginning with SQLite [version 3.31.0] ([dateof:3.31.0]) the input F
** parameter can also be the name of a rollback journal file or WAL file
** in addition to the main database file.  Prior to version 3.31.0, these
** routines would only work if F was the name of the main database file.
** When the F parameter is the name of the rollback journal or WAL file,
** it has access to all the same query parameters as were found on the
** main database file.
**
** See the [URI filename] documentation for additional information.
*/
const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
const char *sqlite3_uri_key(const char *zFilename, int N);

/*
** CAPI3REF:  Translate filenames
**
** These routines are available to [VFS|custom VFS implementations] for
** translating filenames between the main database file, the journal file,
** and the WAL file.
**
** If F is the name of an sqlite database file, journal file, or WAL file
** passed by the SQLite core into the VFS, then sqlite3_filename_database(F)
** returns the name of the corresponding database file.
**
** If F is the name of an sqlite database file, journal file, or WAL file
** passed by the SQLite core into the VFS, or if F is a database filename
** obtained from [sqlite3_db_filename()], then sqlite3_filename_journal(F)
** returns the name of the corresponding rollback journal file.
**
** If F is the name of an sqlite database file, journal file, or WAL file
** that was passed by the SQLite core into the VFS, or if F is a database
** filename obtained from [sqlite3_db_filename()], then
** sqlite3_filename_wal(F) returns the name of the corresponding
** WAL file.
**
** In all of the above, if F is not the name of a database, journal or WAL
** filename passed into the VFS from the SQLite core and F is not the
** return value from [sqlite3_db_filename()], then the result is
** undefined and is likely a memory access violation.
*/
const char *sqlite3_filename_database(const char*);
const char *sqlite3_filename_journal(const char*);
const char *sqlite3_filename_wal(const char*);

/*
** CAPI3REF:  Database File Corresponding To A Journal
**
** ^If X is the name of a rollback or WAL-mode journal file that is
** passed into the xOpen method of [sqlite3_vfs], then 
** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
** object that represents the main database file.
**
** This routine is intended for use in custom [VFS] implementations
** only.  It is not a general-purpose interface.
** The argument sqlite3_file_object(X) must be a filename pointer that
** has been passed into [sqlite3_vfs].xOpen method where the 
** flags parameter to xOpen contains one of the bits
** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL].  Any other use
** of this routine results in undefined and probably undesirable
** behavior.
*/
sqlite3_file *sqlite3_database_file_object(const char*);

/*
** CAPI3REF: Create and Destroy VFS Filenames
**
** These interfces are provided for use by [VFS shim] implementations and
** are not useful outside of that context.
**
** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
** database filename D with corresponding journal file J and WAL file W and
** with N URI parameters key/values pairs in the array P.  The result from
** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
** is safe to pass to routines like:
** <ul>
** <li> [sqlite3_uri_parameter()],
** <li> [sqlite3_uri_boolean()],
** <li> [sqlite3_uri_int64()],
** <li> [sqlite3_uri_key()], 
** <li> [sqlite3_filename_database()],
** <li> [sqlite3_filename_journal()], or
** <li> [sqlite3_filename_wal()].
** </ul>
** If a memory allocation error occurs, sqlite3_create_filename() might
** return a NULL pointer.  The memory obtained from sqlite3_create_filename(X)
** must be released by a corresponding call to sqlite3_free_filename(Y).
**
** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array
** of 2*N pointers to strings.  Each pair of pointers in this array corresponds
** to a key and value for a query parameter.  The P parameter may be a NULL
** pointer if N is zero.  None of the 2*N pointers in the P array may be
** NULL pointers and key pointers should not be empty strings.
** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
** be NULL pointers, though they can be empty strings.
**
** 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,
  const char *zJournal,
  const char *zWal,
  int nParam,
  const char **azParam
);
void sqlite3_free_filename(char*);

/*
** CAPI3REF: Error Codes And Messages
** METHOD: sqlite3
**
** ^If the most recent sqlite3_* API call associated with 
** [database connection] D failed, then the sqlite3_errcode(D) interface
4037
4038
4039
4040
4041
4042
4043
4044

4045
4046
4047

4048
4049

4050
4051
4052

4053
4054
4055
4056
4057
4058
4059
3764
3765
3766
3767
3768
3769
3770

3771
3772
3773

3774
3775

3776
3777
3778

3779
3780
3781
3782
3783
3784
3785
3786







-
+


-
+

-
+


-
+







** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
** and the application would have to make a second call to [sqlite3_reset()]
** in order to find the underlying cause of the problem. With the "v2" prepare
** interfaces, the underlying reason for the error is returned immediately.
** </li>
**
** <li>
** ^If the specific value bound to a [parameter | host parameter] in the 
** ^If the specific value bound to [parameter | host parameter] in the 
** WHERE clause might influence the choice of query plan for a statement,
** then the statement will be automatically recompiled, as if there had been 
** a schema change, on the first [sqlite3_step()] call following any change
** a schema change, on the first  [sqlite3_step()] call following any change
** to the [sqlite3_bind_text | bindings] of that [parameter]. 
** ^The specific value of a WHERE-clause [parameter] might influence the 
** ^The specific value of WHERE-clause [parameter] might influence the 
** choice of query plan if the parameter is the left-hand side of a [LIKE]
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
** </li>
** </ol>
**
** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
** the extra prepFlags parameter, which is a bit array consisting of zero or
** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
** sqlite3_prepare_v2() interface works exactly the same as
4302
4303
4304
4305
4306
4307
4308
4309

4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346

4347
4348
4349
4350
4351
4352
4353
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







-
+





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













-
+







** ^The leftmost SQL parameter has an index of 1.  ^When the same named
** SQL parameter is used more than once, second and subsequent
** occurrences have the same index as the first occurrence.
** ^The index for named parameters can be looked up using the
** [sqlite3_bind_parameter_index()] API if desired.  ^The index
** for "?NNN" parameters is the value of NNN.
** ^The NNN value must be between 1 and the [sqlite3_limit()]
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766).
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
**
** ^The third argument is the value to bind to the parameter.
** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
** is ignored and the end result is the same as sqlite3_bind_null().
** ^If the third parameter to sqlite3_bind_text() is not NULL, then
** it should be a pointer to well-formed UTF8 text.
** ^If the third parameter to sqlite3_bind_text16() is not NULL, then
** it should be a pointer to well-formed UTF16 text.
** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
** it should be a pointer to a well-formed unicode string that is
** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
** otherwise.
**
** [[byte-order determination rules]] ^The byte-order of
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
** found in first character, which is removed, or in the absence of a BOM
** the byte order is the native byte order of the host
** machine for sqlite3_bind_text16() or the byte order specified in
** the 6th parameter for sqlite3_bind_text64().)^ 
** ^If UTF16 input text contains invalid unicode
** characters, then SQLite might change those invalid characters
** into the unicode replacement character: U+FFFD.
**
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter.  To be clear: the value is the
** number of <u>bytes</u> in the value, not the number of characters.)^
** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
** is negative, then the length of the string is
** the number of bytes up to the first zero terminator.
** If the fourth parameter to sqlite3_bind_blob() is negative, then
** the behavior is undefined.
** If a non-negative fourth parameter is provided to sqlite3_bind_text()
** or sqlite3_bind_text16() or sqlite3_bind_text64() then
** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated.  If any NUL characters occurs at byte offsets less than 
** terminated.  If any NUL characters occur at byte offsets less than 
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs.  The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to the BLOB and string binding interfaces
** is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it.  ^The destructor is called
4569
4570
4571
4572
4573
4574
4575
4576

4577
4578
4579
4580
4581
4582
4583
4584




4585
4586
4587
4588
4589
4590
4591
4278
4279
4280
4281
4282
4283
4284

4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304







-
+








+
+
+
+







** ^The first argument to these interfaces is a [prepared statement].
** ^These functions return information about the Nth result column returned by
** the statement, where N is the second function argument.
** ^The left-most column is column 0 for these routines.
**
** ^If the Nth column returned by the statement is an expression or
** subquery and is not a column value, then all of these functions return
** NULL.  ^These routines might also return NULL if a memory allocation error
** NULL.  ^These routine might also return NULL if a memory allocation error
** occurs.  ^Otherwise, they return the name of the attached database, table,
** or column that query result column was extracted from.
**
** ^As with all other SQLite APIs, those whose names end with "16" return
** UTF-16 encoded strings and the other functions return UTF-8.
**
** ^These APIs are only available if the library was compiled with the
** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol.
**
** If two or more threads call one or more of these routines against the same
** prepared statement and column at the same time then the results are
** undefined.
**
** If two or more threads call one or more
** [sqlite3_column_database_name | column metadata interfaces]
** for the same [prepared statement] and result column
** at the same time then the results are undefined.
*/
const char *sqlite3_column_database_name(sqlite3_stmt*,int);
4715
4716
4717
4718
4719
4720
4721
4722

4723
4724
4725
4726
4727
4728
4729
4428
4429
4430
4431
4432
4433
4434

4435
4436
4437
4438
4439
4440
4441
4442







-
+







/*
** CAPI3REF: Number of columns in a result set
** METHOD: sqlite3_stmt
**
** ^The sqlite3_data_count(P) interface returns the number of columns in the
** current row of the result set of [prepared statement] P.
** ^If prepared statement P does not have results ready to return
** (via calls to the [sqlite3_column_int | sqlite3_column()] family of
** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
** interfaces) then sqlite3_data_count(P) returns 0.
** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
** [sqlite3_step](P) returned [SQLITE_DONE].  ^The sqlite3_data_count(P)
** will return non-zero if previous call to [sqlite3_step](P) returned
** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
** where it always returns zero since each step of that multi-step
5039
5040
5041
5042
5043
5044
5045


5046
5047
5048
5049
5050
5051
5052
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767







+
+







** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
int sqlite3_reset(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Create Or Redefine SQL Functions
** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
** METHOD: sqlite3
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
** of existing SQL functions or aggregates. The only differences between
** the three "sqlite3_create_function*" routines are the text encoding 
** expected for the second parameter (the name of the function being 
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
4807
4808
4809
4810
4811
4812
4813

















4814
4815
4816
4817
4818
4819
4820







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







** to signal that the function will always return the same result given
** the same inputs within a single SQL statement.  Most SQL functions are
** deterministic.  The built-in [random()] SQL function is an example of a
** function that is not deterministic.  The SQLite query planner is able to
** perform additional optimizations on deterministic functions, so use
** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
**
** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
** flag, which if present prevents the function from being invoked from
** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions,
** index expressions, or the WHERE clause of partial indexes.
**
** <span style="background-color:#ffff90;">
** For best security, the [SQLITE_DIRECTONLY] flag is recommended for
** all application-defined SQL functions that do not need to be
** used inside of triggers, view, CHECK constraints, or other elements of
** the database schema.  This flags is especially recommended for SQL 
** functions that have side effects or reveal internal application state.
** Without this flag, an attacker might be able to modify the schema of
** a database file to include invocations of the function with parameters
** chosen by the attacker, which the application will then execute when
** the database file is opened and read.
** </span>
**
** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
**
** ^The sixth, seventh and eighth parameters passed to the three
** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
** pointers to C-language functions that implement the SQL function or
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
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
4923
4924
4925
4926
4927
4928
4929

























































4930

4931



4932
4933
4934
4935
4936
4937
4938







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

-
+
-
-
-







/*
** CAPI3REF: Function Flags
**
** These constants may be ORed together with the 
** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
** to [sqlite3_create_function()], [sqlite3_create_function16()], or
** [sqlite3_create_function_v2()].
**
** <dl>
** [[SQLITE_DETERMINISTIC]] <dt>SQLITE_DETERMINISTIC</dt><dd>
** The SQLITE_DETERMINISTIC flag means that the new function always gives
** the same output when the input parameters are the same.
** The [abs|abs() function] is deterministic, for example, but
** [randomblob|randomblob()] is not.  Functions must
** be deterministic in order to be used in certain contexts such as
** with the WHERE clause of [partial indexes] or in [generated columns].
** SQLite might also optimize deterministic functions by factoring them
** out of inner loops.
** </dd>
** 
** [[SQLITE_DIRECTONLY]] <dt>SQLITE_DIRECTONLY</dt><dd>
** The SQLITE_DIRECTONLY flag means that the function may only be invoked
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in 
** schema structures such as [CHECK constraints], [DEFAULT clauses],
** [expression indexes], [partial indexes], or [generated columns].
** The SQLITE_DIRECTONLY flags is a security feature which is recommended
** for all [application-defined SQL functions], and especially for functions
** that have side-effects or that could potentially leak sensitive
** information.
** </dd>
**
** [[SQLITE_INNOCUOUS]] <dt>SQLITE_INNOCUOUS</dt><dd>
** The SQLITE_INNOCUOUS flag means that the function is unlikely
** to cause problems even if misused.  An innocuous function should have
** no side effects and should not depend on any values other than its
** input parameters. The [abs|abs() function] is an example of an
** innocuous function.
** The [load_extension() SQL function] is not innocuous because of its
** side effects.
** <p> SQLITE_INNOCUOUS is similar to SQLITE_DETERMINISTIC, but is not
** exactly the same.  The [random|random() function] is an example of a
** function that is innocuous but not deterministic.
** <p>Some heightened security settings
** ([SQLITE_DBCONFIG_TRUSTED_SCHEMA] and [PRAGMA trusted_schema=OFF])
** disable the use of SQL functions inside views and triggers and in
** schema structures such as [CHECK constraints], [DEFAULT clauses],
** [expression indexes], [partial indexes], and [generated columns] unless
** the function is tagged with SQLITE_INNOCUOUS.  Most built-in functions
** are innocuous.  Developers are advised to avoid using the
** SQLITE_INNOCUOUS flag for application-defined functions unless the
** function has been carefully audited and found to be free of potentially
** security-adverse side-effects and information-leaks.
** </dd>
**
** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd>
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
** Specifying this flag makes no difference for scalar or aggregate user
** functions. However, if it is not specified for a user-defined window
** function, then any sub-types belonging to arguments passed to the window
** function may be discarded before the window function is called (i.e.
** sqlite3_value_subtype() will always return 0).
** </dd>
** </dl>
*/
#define SQLITE_DETERMINISTIC    0x000000800
#define SQLITE_DETERMINISTIC    0x800
#define SQLITE_DIRECTONLY       0x000080000
#define SQLITE_SUBTYPE          0x000100000
#define SQLITE_INNOCUOUS        0x000200000

/*
** CAPI3REF: Deprecated Functions
** DEPRECATED
**
** These functions are [deprecated].  In order to maintain
** backwards compatibility with older code, these functions continue 
5345
5346
5347
5348
5349
5350
5351
5352
5353


5354
5355
5356
5357
5358
5359
5360
4983
4984
4985
4986
4987
4988
4989


4990
4991
4992
4993
4994
4995
4996
4997
4998







-
-
+
+







** <td>&rarr;&nbsp;&nbsp;<td>True if value originated from a [bound parameter]
** </table></blockquote>
**
** <b>Details:</b>
**
** These routines extract type, size, and content information from
** [protected sqlite3_value] objects.  Protected sqlite3_value objects
** are used to pass parameter information into the functions that
** implement [application-defined SQL functions] and [virtual tables].
** are used to pass parameter information into implementation of
** [application-defined SQL functions] and [virtual tables].
**
** These routines work only with [protected sqlite3_value] objects.
** Any attempt to use these routines on an [unprotected sqlite3_value]
** is not threadsafe.
**
** ^These routines work just like the corresponding [column access functions]
** except that these routines take a single [protected sqlite3_value] object
5403
5404
5405
5406
5407
5408
5409
5410

5411
5412
5413
5414
5415
5416
5417
5041
5042
5043
5044
5045
5046
5047

5048
5049
5050
5051
5052
5053
5054
5055







-
+







** to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
** than within an [xUpdate] method call for an UPDATE statement, then
** the return value is arbitrary and meaningless.
**
** ^The sqlite3_value_frombind(X) interface returns non-zero if the
** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
** interfaces.  ^If X comes from an SQL literal value, or a table column,
** or an expression, then sqlite3_value_frombind(X) returns zero.
** and expression, then sqlite3_value_frombind(X) returns zero.
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
** or [sqlite3_value_text16()].
**
5489
5490
5491
5492
5493
5494
5495
5496
5497


5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514

5515
5516
5517
5518
5519
5520
5521
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







-
-
+
+
















-
+







** CAPI3REF: Obtain Aggregate Function Context
** METHOD: sqlite3_context
**
** Implementations of aggregate SQL functions use this
** routine to allocate memory for storing their state.
**
** ^The first time the sqlite3_aggregate_context(C,N) routine is called 
** for a particular aggregate function, SQLite allocates
** N bytes of memory, zeroes out that memory, and returns a pointer
** for a particular aggregate function, SQLite
** allocates N of memory, zeroes out that memory, and returns a pointer
** to the new memory. ^On second and subsequent calls to
** sqlite3_aggregate_context() for the same aggregate function instance,
** the same buffer is returned.  Sqlite3_aggregate_context() is normally
** called once for each invocation of the xStep callback and then one
** last time when the xFinal callback is invoked.  ^(When no rows match
** an aggregate query, the xStep() callback of the aggregate function
** implementation is never called and xFinal() is called exactly once.
** In those cases, sqlite3_aggregate_context() might be called for the
** first time from within xFinal().)^
**
** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer 
** when first called if N is less than or equal to zero or if a memory
** allocate error occurs.
**
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call.  Changing the
** value of N in any subsequent call to sqlite3_aggregate_context() within
** value of N in subsequent call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory
** allocation.)^  Within the xFinal callback, it is customary to set
** N=0 in calls to sqlite3_aggregate_context(C,N) so that no 
** pointless memory allocations occur.
**
** ^SQLite automatically frees the memory allocated by 
** sqlite3_aggregate_context() when the aggregate query concludes.
5664
5665
5666
5667
5668
5669
5670
5671

5672
5673

5674
5675
5676
5677
5678
5679
5680
5302
5303
5304
5305
5306
5307
5308

5309


5310
5311
5312
5313
5314
5315
5316
5317







-
+
-
-
+







**
** ^The sqlite3_result_error() and sqlite3_result_error16() functions
** cause the implemented SQL function to throw an exception.
** ^SQLite uses the string pointed to by the
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
** as the text of an error message.  ^SQLite interprets the error
** message string from sqlite3_result_error() as UTF-8. ^SQLite
** interprets the string from sqlite3_result_error16() as UTF-16 using
** interprets the string from sqlite3_result_error16() as UTF-16 in native
** the same [byte-order determination rules] as [sqlite3_bind_text16()].
** ^If the third parameter to sqlite3_result_error()
** byte order.  ^If the third parameter to sqlite3_result_error()
** or sqlite3_result_error16() is negative then SQLite takes as the error
** message all text up through the first zero character.
** ^If the third parameter to sqlite3_result_error() or
** sqlite3_result_error16() is non-negative then SQLite takes that many
** bytes (not characters) from the 2nd parameter as the error message.
** ^The sqlite3_result_error() and sqlite3_result_error16()
** routines make a private copy of the error message text before
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5371
5372
5373
5374
5375
5376
5377



















5378
5379
5380
5381
5382
5383
5384







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







** copy the content of the parameter nor call a destructor on the content
** when it has finished using that result.
** ^If the 4th parameter to the sqlite3_result_text* interfaces
** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
** then SQLite makes a copy of the result into space obtained
** from [sqlite3_malloc()] before it returns.
**
** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
** sqlite3_result_text16be() routines, and for sqlite3_result_text64()
** when the encoding is not UTF8, if the input UTF16 begins with a
** byte-order mark (BOM, U+FEFF) then the BOM is removed from the
** string and the rest of the string is interpreted according to the
** byte-order specified by the BOM.  ^The byte-order specified by
** the BOM at the beginning of the text overrides the byte-order
** specified by the interface procedure.  ^So, for example, if
** sqlite3_result_text16le() is invoked with text that begins
** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
** first two bytes of input are skipped and the remaining input
** is interpreted as UTF16BE text.
**
** ^For UTF16 input text to the sqlite3_result_text16(),
** sqlite3_result_text16be(), sqlite3_result_text16le(), and
** sqlite3_result_text64() routines, if the text contains invalid
** UTF16 characters, the invalid characters might be converted
** into the unicode replacement character, U+FFFD.
**
** ^The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy of the
** [unprotected sqlite3_value] object specified by the 2nd parameter.  ^The
** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
** so that the [sqlite3_value] specified in the parameter may change or
** be deallocated after sqlite3_result_value() returns without harm.
** ^A [protected sqlite3_value] object may always be used where an
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
5456
5457
5458
5459
5460
5461
5462

5463
5464
5465
5466
5467
5468
5469
5470
5471

5472
5473
5474
5475

5476
5477
5478
5479
5480
5481

5482


5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499

5500
5501
5502
5503
5504
5505
5506
5507







-
+








-
+



-
+





-
+
-
-
+
















-
+







** <li> [SQLITE_UTF8],
** <li> [SQLITE_UTF16LE],
** <li> [SQLITE_UTF16BE],
** <li> [SQLITE_UTF16], or
** <li> [SQLITE_UTF16_ALIGNED].
** </ul>)^
** ^The eTextRep argument determines the encoding of strings passed
** to the collating function callback, xCompare.
** to the collating function callback, xCallback.
** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
** force strings to be UTF16 with native byte order.
** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
** on an even byte address.
**
** ^The fourth argument, pArg, is an application data pointer that is passed
** through as the first argument to the collating function callback.
**
** ^The fifth argument, xCompare, is a pointer to the collating function.
** ^The fifth argument, xCallback, is a pointer to the collating function.
** ^Multiple collating functions can be registered using the same name but
** with different eTextRep parameters and SQLite will use whichever
** function requires the least amount of data transformation.
** ^If the xCompare argument is NULL then the collating function is
** ^If the xCallback argument is NULL then the collating function is
** deleted.  ^When all collating functions having the same name are deleted,
** that collation is no longer usable.
**
** ^The collating function callback is invoked with a copy of the pArg 
** application data pointer and with two strings in the encoding specified
** by the eTextRep argument.  The two integer parameters to the collating
** by the eTextRep argument.  The collating function must return an
** function callback are the length of the two strings, in bytes. The collating
** function must return an integer that is negative, zero, or positive
** integer that is negative, zero, or positive
** if the first string is less than, equal to, or greater than the second,
** respectively.  A collating function must always return the same answer
** given the same inputs.  If two or more collating functions are registered
** to the same collation name (using different eTextRep values) then all
** must give an equivalent answer when invoked with equivalent strings.
** The collating function must obey the following properties for all
** strings A, B, and C:
**
** <ol>
** <li> If A==B then B==A.
** <li> If A==B and B==C then A==C.
** <li> If A&lt;B THEN B&gt;A.
** <li> If A&lt;B and B&lt;C then A&lt;C.
** </ol>
**
** If a collating function fails any of the above constraints and that
** collating function is registered and used, then the behavior of SQLite
** collating function is  registered and used, then the behavior of SQLite
** is undefined.
**
** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
** with the addition that the xDestroy callback is invoked on pArg when
** the collating function is deleted.
** ^Collating functions are deleted when they are overridden by later
** calls to the collation creation functions or when the
5957
5958
5959
5960
5961
5962
5963













































5964
5965
5966
5967
5968
5969
5970
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632







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







  void(*)(void*,sqlite3*,int eTextRep,const char*)
);
int sqlite3_collation_needed16(
  sqlite3*, 
  void*,
  void(*)(void*,sqlite3*,int eTextRep,const void*)
);

#ifdef SQLITE_HAS_CODEC
/*
** Specify the key for an encrypted database.  This routine should be
** called right after sqlite3_open().
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
int sqlite3_key(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The key */
);
int sqlite3_key_v2(
  sqlite3 *db,                   /* Database to be rekeyed */
  const char *zDbName,           /* Name of the database */
  const void *pKey, int nKey     /* The key */
);

/*
** Change the key on an open database.  If the current database is not
** encrypted, this routine will encrypt it.  If pNew==0 or nNew==0, the
** database is decrypted.
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
int sqlite3_rekey(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The new key */
);
int sqlite3_rekey_v2(
  sqlite3 *db,                   /* Database to be rekeyed */
  const char *zDbName,           /* Name of the database */
  const void *pKey, int nKey     /* The new key */
);

/*
** Specify the activation key for a SEE database.  Unless 
** activated, none of the SEE routines will work.
*/
void sqlite3_activate_see(
  const char *zPassPhrase        /* Activation phrase */
);
#endif

#ifdef SQLITE_ENABLE_CEROD
/*
** Specify the activation key for a CEROD database.  Unless 
** activated, none of the CEROD routines will work.
*/
void sqlite3_activate_cerod(
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
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
5820
5821
5822
5823
5824
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







-
-
-
+
+
+



-
-
-
-




-
-
-
-
-
-
-
-
-
-
-













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







*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

/*
** CAPI3REF: Return The Filename For A Database Connection
** METHOD: sqlite3
**
** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
** associated with database N of connection D.
** ^If there is no attached database N on the database
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
** associated with database N of connection D.  ^The main database file
** has the name "main".  If there is no attached database N on the database
** connection D, or if database N is a temporary or in-memory database, then
** this function will return either a NULL pointer or an empty string.
**
** ^The string value returned by this routine is owned and managed by
** the database connection.  ^The value will be valid until the database N
** is [DETACH]-ed or until the database connection closes.
**
** ^The filename returned by this function is the output of the
** xFullPathname method of the [VFS].  ^In other words, the filename
** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname.
**
** If the filename pointer returned by this routine is not NULL, then it
** can be used as the filename input parameter to these routines:
** <ul>
** <li> [sqlite3_uri_parameter()]
** <li> [sqlite3_uri_boolean()]
** <li> [sqlite3_uri_int64()]
** <li> [sqlite3_filename_database()]
** <li> [sqlite3_filename_journal()]
** <li> [sqlite3_filename_wal()]
** </ul>
*/
const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);

/*
** CAPI3REF: Determine if a database is read-only
** METHOD: sqlite3
**
** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
** of connection D is read-only, 0 if it is read/write, or -1 if N is not
** the name of a database on connection D.
*/
int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);

/*
** CAPI3REF: Determine the transaction state of a database
** METHOD: sqlite3
**
** ^The sqlite3_txn_state(D,S) interface returns the current
** [transaction state] of schema S in database connection D.  ^If S is NULL,
** then the highest transaction state of any schema on database connection D
** is returned.  Transaction states are (in order of lowest to highest):
** <ol>
** <li value="0"> SQLITE_TXN_NONE
** <li value="1"> SQLITE_TXN_READ
** <li value="2"> SQLITE_TXN_WRITE
** </ol>
** ^If the S argument to sqlite3_txn_state(D,S) is not the name of
** a valid schema, then -1 is returned.
*/
int sqlite3_txn_state(sqlite3*,const char *zSchema);

/*
** CAPI3REF: Allowed return values from [sqlite3_txn_state()]
** KEYWORDS: {transaction state}
**
** These constants define the current transaction state of a database file.
** ^The [sqlite3_txn_state(D,S)] interface returns one of these
** constants in order to describe the transaction state of schema S
** in [database connection] D.
**
** <dl>
** [[SQLITE_TXN_NONE]] <dt>SQLITE_TXN_NONE</dt>
** <dd>The SQLITE_TXN_NONE state means that no transaction is currently
** pending.</dd>
**
** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt>
** <dd>The SQLITE_TXN_READ state means that the database is currently
** in a read transaction.  Content has been read from the database file
** but nothing in the database file has changed.  The transaction state
** will advanced to SQLITE_TXN_WRITE if any changes occur and there are
** no other conflicting concurrent write transactions.  The transaction
** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or
** [COMMIT].</dd>
**
** [[SQLITE_TXN_WRITE]] <dt>SQLITE_TXN_WRITE</dt>
** <dd>The SQLITE_TXN_WRITE state means that the database is currently
** in a write transaction.  Content has been written to the database file
** but has not yet committed.  The transaction state will change to
** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd>
*/
#define SQLITE_TXN_NONE  0
#define SQLITE_TXN_READ  1
#define SQLITE_TXN_WRITE 2

/*
** CAPI3REF: Find the next prepared statement
** METHOD: sqlite3
**
** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb.  ^If pStmt is NULL
** then this interface returns a pointer to the first prepared statement
6337
6338
6339
6340
6341
6342
6343
6344

6345
6346
6347
6348
6349
6350
6351
5933
5934
5935
5936
5937
5938
5939

5940
5941
5942
5943
5944
5945
5946
5947







-
+







** to be invoked.
** ^The third and fourth arguments to the callback contain pointers to the
** database and table name containing the affected row.
** ^The final callback parameter is the [rowid] of the row.
** ^In the case of an update, this is the [rowid] after the update takes place.
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_sequence).)^
** modified (i.e. sqlite_master and sqlite_sequence).)^
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when conflicting rows are deleted because of an
** [ON CONFLICT | ON CONFLICT REPLACE] clause.  ^Nor is the update hook
** invoked when rows are deleted using the [truncate optimization].
** The exceptions defined in this paragraph might change in a future
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
5979
5980
5981
5982
5983
5984
5985

5986
5987
5988
5989
5990
5991


5992
5993


5994



5995
5996
5997
5998
5999
6000
6001







-
+





-
-
+
+
-
-
+
-
-
-







** ^Cache sharing is enabled and disabled for an entire process.
** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). 
** In prior versions of SQLite,
** sharing was enabled or disabled for each thread separately.
**
** ^(The cache sharing mode set by this interface effects all subsequent
** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
** Existing database connections continue to use the sharing mode
** Existing database connections continue use the sharing mode
** that was in effect at the time they were opened.)^
**
** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
** successfully.  An [error code] is returned otherwise.)^
**
** ^Shared cache is disabled by default. It is recommended that it stay
** that way.  In other words, do not use this routine.  This interface
** ^Shared cache is disabled by default. But this might change in
** future releases of SQLite.  Applications that care about shared
** continues to be provided for historical compatibility, but its use is
** discouraged.  Any use of shared cache is discouraged.  If shared cache
** cache setting should set it explicitly.
** must be used, it is recommended that shared cache only be enabled for
** individual database connections using the [sqlite3_open_v2()] interface
** with the [SQLITE_OPEN_SHAREDCACHE] flag.
**
** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
** and will always return SQLITE_MISUSE. On those systems, 
** shared cache mode should be enabled per-database connection via 
** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
**
** This interface is threadsafe on processors where writing a
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470


6471
6472
6473
6474



6475
6476
6477
6478
6479

6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492

6493
6494
6495
6496

6497
6498
6499
6500
6501
6502
6503
6504
6505
6506











6507

6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
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
6082
6083
6084
6085

6086
6087
6088
6089

6090
6091
6092
6093
6094
6095
6096







-
-
-










-
-
-
-
-
-
-
-
-
+
+

-
-
-
+
+
+

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

-
-
-
-
+



-
+










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



-







** See also: [sqlite3_release_memory()]
*/
int sqlite3_db_release_memory(sqlite3*);

/*
** CAPI3REF: Impose A Limit On Heap Size
**
** These interfaces impose limits on the amount of heap memory that will be
** by all database connections within a single process.
**
** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
** soft limit on the amount of heap memory that may be allocated by SQLite.
** ^SQLite strives to keep heap memory utilization below the soft heap
** limit by reducing the number of pages held in the page cache
** as heap memory usages approaches the limit.
** ^The soft heap limit is "soft" because even though SQLite strives to stay
** below the limit, it will exceed the limit rather than generate
** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
** is advisory only.
**
** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of
** N bytes on the amount of memory that will be allocated.  ^The
** sqlite3_hard_heap_limit64(N) interface is similar to
** sqlite3_soft_heap_limit64(N) except that memory allocations will fail
** when the hard heap limit is reached.
**
** ^The return value from both sqlite3_soft_heap_limit64() and
** sqlite3_hard_heap_limit64() is the size of
** the heap limit prior to the call, or negative in the case of an
** ^The return value from sqlite3_soft_heap_limit64() is the size of
** the soft heap limit prior to the call, or negative in the case of an
** error.  ^If the argument N is negative
** then no change is made to the heap limit.  Hence, the current
** size of heap limits can be determined by invoking
** sqlite3_soft_heap_limit64(-1) or sqlite3_hard_heap_limit(-1).
** then no change is made to the soft heap limit.  Hence, the current
** size of the soft heap limit can be determined by invoking
** sqlite3_soft_heap_limit64() with a negative argument.
**
** ^Setting the heap limits to zero disables the heap limiter mechanism.
**
** ^The soft heap limit may not be greater than the hard heap limit.
** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N)
** ^If the argument N is zero then the soft heap limit is disabled.
** is invoked with a value of N that is greater than the hard heap limit,
** the the soft heap limit is set to the value of the hard heap limit.
** ^The soft heap limit is automatically enabled whenever the hard heap
** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and
** the soft heap limit is outside the range of 1..N, then the soft heap
** limit is set to N.  ^Invoking sqlite3_soft_heap_limit64(0) when the
** hard heap limit is enabled makes the soft heap limit equal to the
** hard heap limit.
**
** The memory allocation limits can also be adjusted using
** [PRAGMA soft_heap_limit] and [PRAGMA hard_heap_limit].
**
** ^(The heap limits are not enforced in the current implementation
** ^(The soft heap limit is not enforced in the current implementation
** if one or more of following conditions are true:
**
** <ul>
** <li> The limit value is set to zero.
** <li> The soft heap limit is set to zero.
** <li> Memory accounting is disabled using a combination of the
**      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
**      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
** <li> An alternative page cache implementation is specified using
**      [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...).
** <li> The page cache allocates from its own memory pool supplied
**      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
**      from the heap.
** </ul>)^
**
** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]), 
** the soft heap limit is enforced
** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
** compile-time option is invoked.  With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
** the soft heap limit is enforced on every memory allocation.  Without
** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced
** when memory is allocated by the page cache.  Testing suggests that because
** the page cache is the predominate memory user in SQLite, most
** applications will achieve adequate soft heap limit enforcement without
** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT].
**
** The circumstances under which SQLite will enforce the heap limits may
** The circumstances under which SQLite will enforce the soft heap limit may
** changes in future releases of SQLite.
*/
sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);

/*
** CAPI3REF: Deprecated Soft Heap Limit Interface
** DEPRECATED
**
** This is a deprecated version of the [sqlite3_soft_heap_limit64()]
** interface.  This routine is provided for historical compatibility
6528
6529
6530
6531
6532
6533
6534
6535

6536
6537
6538
6539
6540
6541
6542
6106
6107
6108
6109
6110
6111
6112

6113
6114
6115
6116
6117
6118
6119
6120







-
+







**
** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
** information about column C of table T in database D
** on [database connection] X.)^  ^The sqlite3_table_column_metadata()
** interface returns SQLITE_OK and fills in the non-NULL pointers in
** the final five arguments with appropriate values if the specified
** column exists.  ^The sqlite3_table_column_metadata() interface returns
** SQLITE_ERROR if the specified column does not exist.
** SQLITE_ERROR and if the specified column does not exist.
** ^If the column-name parameter to sqlite3_table_column_metadata() is a
** NULL pointer, then this routine simply checks for the existence of the
** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
** does not.  If the table name parameter T in a call to
** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
** undefined behavior.
**
6670
6671
6672
6673
6674
6675
6676
6677

6678
6679
6680
6681
6682
6683
6684
6248
6249
6250
6251
6252
6253
6254

6255
6256
6257
6258
6259
6260
6261
6262







-
+







**
** ^This interface enables or disables both the C-API
** [sqlite3_load_extension()] and the SQL function [load_extension()].
** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
** to enable or disable only the C-API.)^
**
** <b>Security warning:</b> It is recommended that extension loading
** be enabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
** rather than this interface, so the [load_extension()] SQL function
** remains disabled. This will prevent SQL injections from giving attackers
** access to extension loading capabilities.
*/
int sqlite3_enable_load_extension(sqlite3 *db, int onoff);

/*
6757
6758
6759
6760
6761
6762
6763
6764

6765
6766
6767
6768
6769
6770
6771
6335
6336
6337
6338
6339
6340
6341

6342
6343
6344
6345
6346
6347
6348
6349







-
+







typedef struct sqlite3_module sqlite3_module;

/*
** CAPI3REF: Virtual Table Object
** KEYWORDS: sqlite3_module {virtual table module}
**
** This structure, sometimes called a "virtual table module", 
** defines the implementation of a [virtual table].  
** defines the implementation of a [virtual tables].  
** This structure consists mostly of methods for the module.
**
** ^A virtual table module is created by filling in a persistent
** instance of this structure and passing a pointer to that instance
** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
** ^The registration remains valid until it is replaced by a different
** module or until the [database connection] closes.  The content
6854
6855
6856
6857
6858
6859
6860
6861

6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6432
6433
6434
6435
6436
6437
6438

6439






6440
6441
6442
6443
6444
6445
6446







-
+
-
-
-
-
-
-







** non-zero.
**
** The [xBestIndex] method must fill aConstraintUsage[] with information
** about what parameters to pass to xFilter.  ^If argvIndex>0 then
** the right-hand side of the corresponding aConstraint[] is evaluated
** and becomes the argvIndex-th entry in argv.  ^(If aConstraintUsage[].omit
** is true, then the constraint is assumed to be fully handled by the
** virtual table and might not be checked again by the byte code.)^ ^(The
** virtual table and is not checked again by SQLite.)^
** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
** is left in its default setting of false, the constraint will always be
** checked separately in byte code.  If the omit flag is change to true, then
** the constraint may or may not be checked in byte code.  In other words,
** when the omit flag is true there is no guarantee that the constraint will
** not be checked again using byte code.)^
**
** ^The idxNum and idxPtr values are recorded and passed into the
** [xFilter] method.
** ^[sqlite3_free()] is used to free idxPtr if and only if
** needToFreeIdxPtr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
6900
6901
6902
6903
6904
6905
6906
6907

6908
6909
6910
6911
6912
6913
6914
6472
6473
6474
6475
6476
6477
6478

6479
6480
6481
6482
6483
6484
6485
6486







-
+







** the xUpdate method are automatically rolled back by SQLite.
**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). 
** If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting 
** to read or write the estimatedRows field are undefined (but are likely 
** to include crashing the application). The estimatedRows field should
** to included crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
** value greater than or equal to 3008002. Similarly, the idxFlags field
** was added for [version 3.9.0] ([dateof:3.9.0]). 
** It may therefore only be used if
** sqlite3_libversion_number() returns a value greater than or equal to
** 3009000.
*/
6952
6953
6954
6955
6956
6957
6958
6959

6960
6961
6962
6963
6964
6965
6966
6524
6525
6526
6527
6528
6529
6530

6531
6532
6533
6534
6535
6536
6537
6538







-
+







** these bits.
*/
#define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */

/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros define the allowed values for the
** These macros defined the allowed values for the
** [sqlite3_index_info].aConstraint[].op field.  Each value represents
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
#define SQLITE_INDEX_CONSTRAINT_EQ         2
#define SQLITE_INDEX_CONSTRAINT_GT         4
#define SQLITE_INDEX_CONSTRAINT_LE         8
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
6570
6571
6572
6573
6574
6575
6576






6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591

















6592
6593
6594
6595
6596
6597
6598







-
-
-
-
-
-















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







** is a pointer to a destructor for the pClientData.  ^SQLite will
** invoke the destructor function (if it is not NULL) when SQLite
** no longer needs the pClientData pointer.  ^The destructor will also
** be invoked if the call to sqlite3_create_module_v2() fails.
** ^The sqlite3_create_module()
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
**
** ^If the third parameter (the pointer to the sqlite3_module object) is
** NULL then no new module is create and any existing modules with the
** same name are dropped.
**
** See also: [sqlite3_drop_modules()]
*/
int sqlite3_create_module(
  sqlite3 *db,               /* SQLite connection to register module with */
  const char *zName,         /* Name of the module */
  const sqlite3_module *p,   /* Methods for the module */
  void *pClientData          /* Client data for xCreate/xConnect */
);
int sqlite3_create_module_v2(
  sqlite3 *db,               /* SQLite connection to register module with */
  const char *zName,         /* Name of the module */
  const sqlite3_module *p,   /* Methods for the module */
  void *pClientData,         /* Client data for xCreate/xConnect */
  void(*xDestroy)(void*)     /* Module destructor function */
);

/*
** CAPI3REF: Remove Unnecessary Virtual Table Implementations
** METHOD: sqlite3
**
** ^The sqlite3_drop_modules(D,L) interface removes all virtual
** table modules from database connection D except those named on list L.
** The L parameter must be either NULL or a pointer to an array of pointers
** to strings where the array is terminated by a single NULL pointer.
** ^If the L parameter is NULL, then all virtual table modules are removed.
**
** See also: [sqlite3_create_module()]
*/
int sqlite3_drop_modules(
  sqlite3 *db,                /* Remove modules from this connection */
  const char **azKeep         /* Except, do not remove the ones named here */
);

/*
** CAPI3REF: Virtual Table Instance Object
** KEYWORDS: sqlite3_vtab
**
** Every [virtual table module] implementation uses a subclass
** of this object to describe a particular instance
** of the [virtual table].  Each subclass will
7439
7440
7441
7442
7443
7444
7445
7446

7447
7448
7449
7450
7451
7452
7453
6988
6989
6990
6991
6992
6993
6994

6995
6996
6997
6998
6999
7000
7001
7002







-
+







** routine returns NULL if it is unable to allocate the requested
** mutex.  The argument to sqlite3_mutex_alloc() must one of these
** integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MAIN
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_OPEN
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_PMEM
** <li>  SQLITE_MUTEX_STATIC_APP1
** <li>  SQLITE_MUTEX_STATIC_APP2
7562
7563
7564
7565
7566
7567
7568
7569

7570
7571
7572
7573
7574
7575
7576
7111
7112
7113
7114
7115
7116
7117

7118
7119
7120
7121
7122
7123
7124
7125







-
+







**   <li>  [sqlite3_mutex_held()] </li>
**   <li>  [sqlite3_mutex_notheld()] </li>
** </ul>)^
**
** The only difference is that the public sqlite3_XXX functions enumerated
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
** by this structure are not required to handle this case. The results
** by this structure are not required to handle this case, the results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
**
** The xMutexInit() method must be threadsafe.  It must be harmless to
** invoke xMutexInit() multiple times within the same process and without
** intervening calls to xMutexEnd().  Second and subsequent calls to
7641
7642
7643
7644
7645
7646
7647
7648

7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7190
7191
7192
7193
7194
7195
7196

7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210




7211
7212
7213
7214
7215
7216
7217







-
+













-
-
-
-







**
** The set of static mutexes may change from one SQLite release to the
** next.  Applications that override the built-in mutex logic must be
** prepared to accommodate additional static mutexes.
*/
#define SQLITE_MUTEX_FAST             0
#define SQLITE_MUTEX_RECURSIVE        1
#define SQLITE_MUTEX_STATIC_MAIN      2
#define SQLITE_MUTEX_STATIC_MASTER    2
#define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2      4  /* NOT USED */
#define SQLITE_MUTEX_STATIC_OPEN      4  /* sqlite3BtreeOpen() */
#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_randomness() */
#define SQLITE_MUTEX_STATIC_LRU       6  /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2      7  /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM      7  /* sqlite3PageMalloc() */
#define SQLITE_MUTEX_STATIC_APP1      8  /* For use by application */
#define SQLITE_MUTEX_STATIC_APP2      9  /* For use by application */
#define SQLITE_MUTEX_STATIC_APP3     10  /* For use by application */
#define SQLITE_MUTEX_STATIC_VFS1     11  /* For use by built-in VFS */
#define SQLITE_MUTEX_STATIC_VFS2     12  /* For use by extension VFS */
#define SQLITE_MUTEX_STATIC_VFS3     13  /* For use by application VFS */

/* Legacy compatibility: */
#define SQLITE_MUTEX_STATIC_MASTER    2


/*
** CAPI3REF: Retrieve the mutex for a database connection
** METHOD: sqlite3
**
** ^This interface returns a pointer the [sqlite3_mutex] object that 
** serializes access to the [database connection] given in the argument
7748
7749
7750
7751
7752
7753
7754
7755

7756
7757
7758
7759
7760
7761
7762

7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782

7783
7784
7785
7786
7787
7788
7789
7293
7294
7295
7296
7297
7298
7299

7300
7301
7302
7303
7304
7305
7306

7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321






7322
7323
7324
7325
7326
7327
7328
7329







-
+






-
+














-
-
-
-
-
-
+







** without notice.  These values are for testing purposes only.
** 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_PRNG_RESET               7
#define SQLITE_TESTCTRL_BITVEC_TEST              8
#define SQLITE_TESTCTRL_FAULT_INSTALL            9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
#define SQLITE_TESTCTRL_PENDING_BYTE            11
#define SQLITE_TESTCTRL_ASSERT                  12
#define SQLITE_TESTCTRL_ALWAYS                  13
#define SQLITE_TESTCTRL_RESERVE                 14  /* NOT USED */
#define SQLITE_TESTCTRL_RESERVE                 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS           15
#define SQLITE_TESTCTRL_ISKEYWORD               16  /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC           17  /* NOT USED */
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS      17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
#define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
#define SQLITE_TESTCTRL_NEVER_CORRUPT           20
#define SQLITE_TESTCTRL_VDBE_COVERAGE           21
#define SQLITE_TESTCTRL_BYTEORDER               22
#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 */
#define SQLITE_TESTCTRL_LAST                    26  /* 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,
8041
8042
8043
8044
8045
8046
8047
8048

8049
8050
8051
8052
8053
8054
8055
7581
7582
7583
7584
7585
7586
7587

7588
7589
7590
7591
7592
7593
7594
7595







-
+







** returned value includes allocations that overflowed because they
** where too large (they were larger than the "sz" parameter to
** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
** no space was left in the page cache.</dd>)^
**
** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to the [pagecache memory allocator].  Only the value returned in the
** handed to [pagecache memory allocator].  Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.  
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
8117
8118
8119
8120
8121
8122
8123
8124

8125
8126
8127
8128
8129
8130
8131
7657
7658
7659
7660
7661
7662
7663

7664
7665
7666
7667
7668
7669
7670
7671







-
+







**
** <dl>
** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
** <dd>This parameter returns the number of lookaside memory slots currently
** checked out.</dd>)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
** <dd>This parameter returns the number of malloc attempts that were 
** <dd>This parameter returns the number malloc attempts that were 
** satisfied using lookaside memory. Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
** <dd>This parameter returns the number malloc attempts that might have
** been satisfied using lookaside memory but failed due to the amount of
8199
8200
8201
8202
8203
8204
8205
8206

8207
8208
8209
8210
8211
8212
8213
7739
7740
7741
7742
7743
7744
7745

7746
7747
7748
7749
7750
7751
7752
7753







-
+







**
** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
** <dd>This parameter returns the number of dirty cache entries that have
** been written to disk in the middle of a transaction due to the page
** cache overflowing. Transactions are more efficient if they are written
** to disk all at once. When pages spill mid-transaction, that introduces
** additional overhead. This parameter can be used help identify
** inefficiencies that can be resolved by increasing the cache size.
** inefficiencies that can be resolve by increasing the cache size.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
** resolved.)^  ^The highwater mark is always 0.
** </dd>
8288
8289
8290
8291
8292
8293
8294
8295

8296
8297
8298
8299
8300
8301
8302
7828
7829
7830
7831
7832
7833
7834

7835
7836
7837
7838
7839
7840
7841
7842







-
+







** to 2147483647.  The number of virtual machine operations can be 
** used as a proxy for the total work done by the prepared statement.
** If the number of virtual machine operations exceeds 2147483647
** then the value returned by this statement status code is undefined.
**
** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
** <dd>^This is the number of times that the prepare statement has been
** automatically regenerated due to schema changes or changes to 
** automatically regenerated due to schema changes or change to 
** [bound parameters] that might affect the query plan.
**
** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
** <dd>^This is the number of times that the prepared statement has
** been run.  A single "run" for the purposes of this counter is one
** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
** The counter is incremented on the first [sqlite3_step()] call of each
8459
8460
8461
8462
8463
8464
8465
8466

8467
8468
8469
8470
8471
8472
8473
7999
8000
8001
8002
8003
8004
8005

8006
8007
8008
8009
8010
8011
8012
8013







-
+







**                 Otherwise return NULL.
** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return
**                 NULL if allocating a new page is effectively impossible.
** </table>
**
** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  SQLite
** will only use a createFlag of 2 after a prior call with a createFlag of 1
** failed.)^  In between the xFetch() calls, SQLite may
** failed.)^  In between the to xFetch() calls, SQLite may
** attempt to unpin one or more cache pages by spilling the content of
** pinned pages to disk and synching the operating system disk cache.
**
** [[the xUnpin() page cache method]]
** ^xUnpin() is called by SQLite with a pointer to a currently pinned page
** as its second argument.  If the third parameter, discard, is non-zero,
** then the page must be evicted from the cache.
8777
8778
8779
8780
8781
8782
8783
8784

8785
8786
8787
8788
8789
8790
8791
8317
8318
8319
8320
8321
8322
8323

8324
8325
8326
8327
8328
8329
8330
8331







-
+







** identity of the database connection (the blocking connection) that
** has locked the required resource is stored internally. ^After an 
** application receives an SQLITE_LOCKED error, it may call the
** sqlite3_unlock_notify() method with the blocked connection handle as 
** the first argument to register for a callback that will be invoked
** when the blocking connections current transaction is concluded. ^The
** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
** call that concludes the blocking connection's transaction.
** call that concludes the blocking connections transaction.
**
** ^(If sqlite3_unlock_notify() is called in a multi-threaded application,
** there is a chance that the blocking connection will have already
** concluded its transaction by the time sqlite3_unlock_notify() is invoked.
** If this happens, then the specified callback is invoked immediately,
** from within the call to sqlite3_unlock_notify().)^
**
8815
8816
8817
8818
8819
8820
8821
8822

8823
8824
8825
8826
8827
8828
8829
8355
8356
8357
8358
8359
8360
8361

8362
8363
8364
8365
8366
8367
8368
8369







-
+







** When an unlock-notify callback is registered, the application provides a 
** single void* pointer that is passed to the callback when it is invoked.
** However, the signature of the callback function allows SQLite to pass
** it an array of void* context pointers. The first argument passed to
** an unlock-notify callback is a pointer to an array of void* pointers,
** and the second is the number of entries in the array.
**
** When a blocking connection's transaction is concluded, there may be
** When a blocking connections transaction is concluded, there may be
** more than one blocked connection that has registered for an unlock-notify
** callback. ^If two or more such blocked connections have specified the
** same callback function, then instead of invoking the callback function
** multiple times, it is invoked once with the set of void* context pointers
** specified by the blocked connections bundled together into an array.
** This gives the application an opportunity to prioritize any actions 
** related to the set of unblocked database connections.
9163
9164
9165
9166
9167
9168
9169
9170
9171


9172
9173
9174
9175
9176

9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191

9192
9193
9194
9195
9196
9197
9198
8703
8704
8705
8706
8707
8708
8709


8710
8711





8712
8713
8714
8715
8716
8717


8718
8719
8720
8721
8722
8723
8724

8725
8726
8727
8728
8729
8730
8731
8732







-
-
+
+
-
-
-
-
-
+





-
-







-
+







** This function may be called by either the [xConnect] or [xCreate] method
** of a [virtual table] implementation to configure
** various facets of the virtual table interface.
**
** If this interface is invoked outside the context of an xConnect or
** xCreate virtual table method then the behavior is undefined.
**
** In the call sqlite3_vtab_config(D,C,...) the D parameter is the
** [database connection] in which the virtual table is being created and
** At present, there is only one option that may be configured using
** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].)  Further options
** which is passed in as the first argument to the [xConnect] or [xCreate]
** method that is invoking sqlite3_vtab_config().  The C parameter is one
** of the [virtual table configuration options].  The presence and meaning
** of parameters after C depend on which [virtual table configuration option]
** is used.
** may be added in the future.
*/
int sqlite3_vtab_config(sqlite3*, int op, ...);

/*
** CAPI3REF: Virtual Table Configuration Options
** KEYWORDS: {virtual table configuration options} 
** KEYWORDS: {virtual table configuration option}
**
** These macros define the various options to the
** [sqlite3_vtab_config()] interface that [virtual table] implementations
** can use to customize and optimize their behavior.
**
** <dl>
** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT</dt>
** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
** <dd>Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
** where X is an integer.  If X is zero, then the [virtual table] whose
** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
** support constraints.  In this configuration (which is the default) if
** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire
** statement is rolled back as if [ON CONFLICT | OR ABORT] had been
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262

9263
9264

9265
9266

9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
8747
8748
8749
8750
8751
8752
8753




















8754
8755
8756


8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773

8774
8775

8776


8777
8778
8779
8780
8781
8782
8783
8784
8785






8786
8787
8788
8789
8790
8791
8792







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



-
-

















-
+

-
+
-
-
+








-
-
-
-
-
-







** must do so within the [xUpdate] method. If a call to the 
** [sqlite3_vtab_on_conflict()] function indicates that the current ON 
** CONFLICT policy is REPLACE, the virtual table implementation should 
** silently replace the appropriate rows within the xUpdate callback and
** return SQLITE_OK. Or, if this is not possible, it may return
** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT 
** constraint handling.
** </dd>
**
** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt>
** <dd>Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the
** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
** prohibits that virtual table from being used from within triggers and
** views.
** </dd>
**
** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt>
** <dd>Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the
** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
** identify that virtual table as being safe to use from within triggers
** and views.  Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the
** virtual table can do no serious harm even if it is controlled by a
** malicious hacker.  Developers should avoid setting the SQLITE_VTAB_INNOCUOUS
** flag unless absolutely necessary.
** </dd>
** </dl>
*/
#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
#define SQLITE_VTAB_INNOCUOUS          2
#define SQLITE_VTAB_DIRECTONLY         3

/*
** CAPI3REF: Determine The Virtual Table Conflict Policy
**
** This function may only be called from within a call to the [xUpdate] method
** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
int sqlite3_vtab_on_conflict(sqlite3 *);

/*
** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
**
** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
** method of a [virtual table], then it might return true if the
** method of a [virtual table], then it returns true if and only if the
** column is being fetched as part of an UPDATE operation during which the
** column value will not change.  The virtual table implementation can use
** column value will not change.  Applications might use this to substitute
** this hint as permission to substitute a return value that is less
** expensive to compute and that the corresponding
** a return value that is less expensive to compute and that the corresponding
** [xUpdate] method understands as a "no-change" value.
**
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
** the column is not changed by the UPDATE statement, then the xColumn
** method can optionally return without setting a result, without calling
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
** In that case, [sqlite3_value_nochange(X)] will return true for the
** same column in the [xUpdate] method.
**
** The sqlite3_vtab_nochange() routine is an optimization.  Virtual table
** implementations should continue to give a correct answer even if the
** sqlite3_vtab_nochange() interface were to always return false.  In the
** current implementation, the sqlite3_vtab_nochange() interface does always
** returns false for the enhanced [UPDATE FROM] statement.
*/
int sqlite3_vtab_nochange(sqlite3_context*);

/*
** CAPI3REF: Determine The Collation For a Virtual Table Constraint
**
** This function may only be called from within a call to the [xBestIndex]
9324
9325
9326
9327
9328
9329
9330
9331

9332
9333
9334
9335

9336
9337
9338
9339

9340
9341
9342
9343
9344
9345
9346
9347

9348
9349
9350
9351
9352

9353
9354
9355
9356
9357

9358
9359
9360
9361
9362
9363
9364
8829
8830
8831
8832
8833
8834
8835

8836
8837
8838
8839

8840
8841
8842
8843

8844
8845
8846
8847
8848
8849
8850
8851

8852
8853
8854
8855
8856

8857
8858
8859
8860
8861

8862
8863
8864
8865
8866
8867
8868
8869







-
+



-
+



-
+







-
+




-
+




-
+







**
** When the value returned to V is a string, space to hold that string is
** managed by the prepared statement S and will be automatically freed when
** S is finalized.
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
** set to the total number of times that the X-th loop has run.</dd>
**
** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be set
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
** to the total number of rows examined by all iterations of the X-th loop.</dd>
**
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
** <dd>^The "double" variable pointed to by the V parameter will be set to the
** <dd>^The "double" variable pointed to by the T parameter will be set to the
** query planner's estimate for the average number of rows output from each
** iteration of the X-th loop.  If the query planner's estimates was accurate,
** then this value will approximate the quotient NVISIT/NLOOP and the
** product of this value for all prior loops with the same SELECTID will
** be the NLOOP value for the current loop.
**
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
** <dd>^The "const char *" variable pointed to by the V parameter will be set
** <dd>^The "const char *" variable pointed to by the T parameter will be set
** to a zero-terminated UTF-8 string containing the name of the index or table
** used for the X-th loop.
**
** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
** <dd>^The "const char *" variable pointed to by the V parameter will be set
** <dd>^The "const char *" variable pointed to by the T parameter will be set
** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
** description for the X-th loop.
**
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
** <dd>^The "int" variable pointed to by the V parameter will be set to the
** <dd>^The "int" variable pointed to by the T parameter will be set to the
** "select-id" for the X-th loop.  The select-id identifies which query or
** subquery the loop is part of.  The main query has a select-id of zero.
** The select-id is the same value as is output in the first column
** of an [EXPLAIN QUERY PLAN] query.
** </dl>
*/
#define SQLITE_SCANSTAT_NLOOP    0
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
8920
8921
8922
8923
8924
8925
8926

8927
8928
8929
8930
8931
8932
8933







-







** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);

/*
** CAPI3REF: Flush caches to disk mid-transaction
** METHOD: sqlite3
**
** ^If a write-transaction is open on [database connection] D when the
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
** pages in the pager-cache that are not currently in use are written out 
** to disk. A dirty page may be in use if a database cursor created by an
** active SQL statement is reading from it, or if it is page 1 of a database
** file (page 1 is always "in use").  ^The [sqlite3_db_cacheflush(D)]
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473

9474
9475
9476
9477
9478
9479
9480
8952
8953
8954
8955
8956
8957
8958

8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975

8976
8977
8978
8979
8980
8981
8982
8983







-

















-
+







** ^This function does not set the database handle error code or message
** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
*/
int sqlite3_db_cacheflush(sqlite3*);

/*
** CAPI3REF: The pre-update hook.
** METHOD: sqlite3
**
** ^These interfaces are only available if SQLite is compiled using the
** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
**
** ^The [sqlite3_preupdate_hook()] interface registers a callback function
** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
** on a database table.
** ^At most one preupdate hook may be registered at a time on a single
** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
** the previous setting.
** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
** with a NULL pointer as the second parameter.
** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
** the first parameter to callbacks.
**
** ^The preupdate hook only fires for changes to real database tables; the
** preupdate hook is not invoked for changes to [virtual tables] or to
** system tables like sqlite_sequence or sqlite_stat1.
** system tables like sqlite_master or sqlite_stat1.
**
** ^The second parameter to the preupdate callback is a pointer to
** the [database connection] that registered the preupdate hook.
** ^The third parameter to the preupdate callback is one of the constants
** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the
** kind of update operation that is about to occur.
** ^(The fourth parameter to the preupdate callback is the name of the
9489
9490
9491
9492
9493
9494
9495
9496

9497
9498
9499
9500
9501
9502
9503
8992
8993
8994
8995
8996
8997
8998

8999
9000
9001
9002
9003
9004
9005
9006







-
+







** parameter passed to the preupdate callback is the initial [rowid] of the 
** row being modified or deleted. For an INSERT operation on a rowid table,
** or any operation on a WITHOUT ROWID table, the value of the sixth 
** parameter is undefined. For an INSERT or UPDATE on a rowid table the
** seventh parameter is the final rowid value of the row being inserted
** or updated. The value of the seventh parameter passed to the callback
** function is not defined for operations on WITHOUT ROWID tables, or for
** DELETE operations on rowid tables.
** INSERT operations on rowid tables.
**
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
** provide additional information about a preupdate event. These routines
** may only be called from within a preupdate callback.  Invoking any of
** these routines from outside of a preupdate callback or with a
** [database connection] pointer that is different from the one supplied
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9054
9055
9056
9057
9058
9059
9060

9061
9062
9063
9064
9065
9066
9067







-







int sqlite3_preupdate_count(sqlite3 *);
int sqlite3_preupdate_depth(sqlite3 *);
int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
#endif

/*
** CAPI3REF: Low-level system error code
** METHOD: sqlite3
**
** ^Attempt to return the underlying operating system error code or error
** number that caused the most recent I/O error or failure to open a file.
** The return value is OS-dependent.  For example, on unix systems, after
** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
** called to get back the underlying "errno" that caused the problem, such
** as ENOSPC, EAUTH, EISDIR, and so forth.  

Changes to src/sqlite3ext.h.

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
318
319
320
321
322
323
324















325
326
327
328
329
330
331







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







                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
                            void(*xDestroy)(void*));
  /* Version 3.26.0 and later */
  const char *(*normalized_sql)(sqlite3_stmt*);
  /* Version 3.28.0 and later */
  int (*stmt_isexplain)(sqlite3_stmt*);
  int (*value_frombind)(sqlite3_value*);
  /* Version 3.30.0 and later */
  int (*drop_modules)(sqlite3*,const char**);
  /* Version 3.31.0 and later */
  sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
  const char *(*uri_key)(const char*,int);
  const char *(*filename_database)(const char*);
  const char *(*filename_journal)(const char*);
  const char *(*filename_wal)(const char*);
  /* Version 3.32.0 and later */
  char *(*create_filename)(const char*,const char*,const char*,
                           int,const char**);
  void (*free_filename)(char*);
  sqlite3_file *(*database_file_object)(const char*);
  /* Version 3.34.0 and later */
  int (*txn_state)(sqlite3*,const char*);
};

/*
** This is the function signature used for all extension entry points.  It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
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
608
609
610
611
612
613
614


615
616














617
618
619
620
621
622
623







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







#define sqlite3_str_length             sqlite3_api->str_length
#define sqlite3_str_value              sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
/* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain         sqlite3_api->stmt_isexplain
#define sqlite3_value_frombind         sqlite3_api->value_frombind
#define sqlite3_stmt_isexplain         sqlite3_api->isexplain
#define sqlite3_value_frombind         sqlite3_api->frombind
/* Version 3.30.0 and later */
#define sqlite3_drop_modules           sqlite3_api->drop_modules
/* Version 3.31.0 and later */
#define sqlite3_hard_heap_limit64      sqlite3_api->hard_heap_limit64
#define sqlite3_uri_key                sqlite3_api->uri_key
#define sqlite3_filename_database      sqlite3_api->filename_database
#define sqlite3_filename_journal       sqlite3_api->filename_journal
#define sqlite3_filename_wal           sqlite3_api->filename_wal
/* Version 3.32.0 and later */
#define sqlite3_create_filename        sqlite3_api->create_filename
#define sqlite3_free_filename          sqlite3_api->free_filename
#define sqlite3_database_file_object   sqlite3_api->database_file_object
/* Version 3.34.0 and later */
#define sqlite3_txn_state              sqlite3_api->txn_state
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */

#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
  /* This case when the file really is being compiled as a loadable 
  ** extension */
# define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;

Changes to src/sqliteInt.h.

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
115
116
117
118
119
120
121












122
123
124
125
126
127
128
129
130









131
132
133
134
135
136
137







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









-
-
-
-
-
-
-
-
-







#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
#endif

/*
** Macro to disable warnings about missing "break" at the end of a "case".
*/
#if GCC_VERSION>=7000000
# define deliberate_fall_through __attribute__((fallthrough));
#else
# define deliberate_fall_through
#endif

/*
** For MinGW, check to see if we can include the header file containing its
** version information, among other things.  Normally, this internal MinGW
** header file would [only] be included automatically by other MinGW header
** files; however, the contained version information is now required by this
** header file to work around binary compatibility issues (see below) and
** this is the only known way to reliably obtain it.  This entire #if block
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
182
183
184
185
186
187
188
















189
190
191
192
193
194
195







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







#pragma warn -rch /* unreachable code */
#pragma warn -ccc /* Condition is always true or false */
#pragma warn -aus /* Assigned value is never used */
#pragma warn -csu /* Comparing signed and unsigned */
#pragma warn -spa /* Suspicious pointer arithmetic */
#endif

/*
** 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

/*
** Include standard header files as necessary
*/
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H
245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260



261
262
263
264
265
266
267
208
209
210
211
212
213
214




215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230







-
-
-
-
+





+
+
+







** that vary from one machine to the next.
**
** Ticket #3860:  The llvm-gcc-4.2 compiler from Apple chokes on
** the ((void*)&((char*)0)[X]) construct.  But MSVC chokes on ((void*)(X)).
** So we have to define the macros in different ways depending on the
** compiler.
*/
#if defined(HAVE_STDINT_H)   /* Use this case if we have ANSI headers */
# define SQLITE_INT_TO_PTR(X)  ((void*)(intptr_t)(X))
# define SQLITE_PTR_TO_INT(X)  ((int)(intptr_t)(X))
#elif defined(__PTRDIFF_TYPE__)  /* This case should work for GCC */
#if defined(__PTRDIFF_TYPE__)  /* This case should work for GCC */
# define SQLITE_INT_TO_PTR(X)  ((void*)(__PTRDIFF_TYPE__)(X))
# define SQLITE_PTR_TO_INT(X)  ((int)(__PTRDIFF_TYPE__)(X))
#elif !defined(__GNUC__)       /* Works for compilers other than LLVM */
# define SQLITE_INT_TO_PTR(X)  ((void*)&((char*)0)[X])
# define SQLITE_PTR_TO_INT(X)  ((int)(((char*)X)-(char*)0))
#elif defined(HAVE_STDINT_H)   /* Use this case if we have ANSI headers */
# define SQLITE_INT_TO_PTR(X)  ((void*)(intptr_t)(X))
# define SQLITE_PTR_TO_INT(X)  ((int)(intptr_t)(X))
#else                          /* Generates a warning - but it always works */
# define SQLITE_INT_TO_PTR(X)  ((void*)(X))
# define SQLITE_PTR_TO_INT(X)  ((int)(X))
#endif

/*
** A macro to hint to the compiler that a function should not be
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
442
443
444
445
446
447
448




















449
450
451
452
453
454
455







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







# define ALWAYS(X)      ((X)?1:(assert(0),0))
# define NEVER(X)       ((X)?(assert(0),1):0)
#else
# define ALWAYS(X)      (X)
# define NEVER(X)       (X)
#endif

/*
** The harmless(X) macro indicates that expression X is usually false
** but can be true without causing any problems, but we don't know of
** any way to cause X to be true.
**
** In debugging and testing builds, this macro will abort if X is ever
** true.  In this way, developers are alerted to a possible test case
** that causes X to be true.  If a harmless macro ever fails, that is
** an opportunity to change the macro into a testcase() and add a new
** test case to the test suite.
**
** For normal production builds, harmless(X) is a no-op, since it does
** not matter whether expression X is true or false.
*/
#ifdef SQLITE_DEBUG
# define harmless(X)  assert(!(X));
#else
# define harmless(X)
#endif

/*
** Some conditionals are optimizations only.  In other words, if the
** conditionals are replaced with a constant 1 (true) or 0 (false) then
** the correct answer is still obtained, though perhaps not as quickly.
**
** The following macros mark these optimizations conditionals.
*/
883
884
885
886
887
888
889
890
891
892
893




894
895

896
897
898
899
900
901
902
903
826
827
828
829
830
831
832




833
834
835
836
837

838

839
840
841
842
843
844
845







-
-
-
-
+
+
+
+

-
+
-







**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros.  If that is unsuccessful, or if
** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
** at run-time.
*/
#ifndef SQLITE_BYTEORDER
# if defined(i386)      || defined(__i386__)      || defined(_M_IX86) ||    \
     defined(__x86_64)  || defined(__x86_64__)    || defined(_M_X64)  ||    \
     defined(_M_AMD64)  || defined(_M_ARM)        || defined(__x86)   ||    \
     defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
# if defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
     defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
     defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
     defined(__arm__)  || defined(_M_ARM64)
#   define SQLITE_BYTEORDER    1234
# elif defined(sparc)     || defined(__ppc__) || \
# elif defined(sparc)    || defined(__ppc__)
       defined(__ARMEB__) || defined(__AARCH64EB__)
#   define SQLITE_BYTEORDER    4321
# else
#   define SQLITE_BYTEORDER 0
# endif
#endif
#if SQLITE_BYTEORDER==4321
# define SQLITE_BIGENDIAN    1
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
862
863
864
865
866
867
868

869
870
871
872
873
874
875







-








/*
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
#define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)

/*
** Round up a number to the next larger multiple of 8.  This is used
** to force 8-byte alignment on 64-bit architectures.
*/
#define ROUND8(x)     (((x)+7)&~7)
989
990
991
992
993
994
995














996
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041

1042
1043
1044

1045


1046
1047
1048


1049
1050
1051
1052
1053
1054

1055
1056

1057
1058
1059

1060
1061

1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083

1084
1085
1086
1087
1088
1089
1090
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954




955

956




957

958
959













960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979

980
981
982


983
984


985

986

987
988

989
990
991

992
993

994

995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
1022







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




-
-
-
-
+
-

-
-
-
-

-


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















+



+
-
+
+

-
-
+
+
-
-

-

-
+

-
+


-
+

-
+
-




















-
+







# define SQLITE_DEFAULT_MMAP_SIZE 0
#endif
#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE
# undef SQLITE_DEFAULT_MMAP_SIZE
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
#endif

/*
** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined.
** Priority is given to SQLITE_ENABLE_STAT4.  If either are defined, also
** define SQLITE_ENABLE_STAT3_OR_STAT4
*/
#ifdef SQLITE_ENABLE_STAT4
# undef SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3_OR_STAT4
# undef SQLITE_ENABLE_STAT3_OR_STAT4
#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) \
#if defined(SQLITE_ENABLE_SELECTTRACE)
    && (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
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
** callback is currently invoked only from within pager.c.
*/
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
  int (*xBusyHandler)(void *,int);  /* The busy callback */
  void *pBusyArg;                   /* First arg to busy callback */
  int nBusy;                        /* Incremented with each busy call */
  u8 bExtraFileArg;                 /* Include sqlite3_file as callback arg */
};

/*
** Name of the master database table.  The master database table
** Name of table that holds the database schema.
** is a special table that holds the names and attributes of all
** user tables and indices.
*/
#define DFLT_SCHEMA_TABLE          "sqlite_master"
#define DFLT_TEMP_SCHEMA_TABLE     "sqlite_temp_master"
#define MASTER_NAME       "sqlite_master"
#define TEMP_MASTER_NAME  "sqlite_temp_master"
#define ALT_SCHEMA_TABLE           "sqlite_schema"
#define ALT_TEMP_SCHEMA_TABLE      "sqlite_temp_schema"


/*
** The root-page of the schema table.
** The root-page of the master database table.
*/
#define SCHEMA_ROOT    1
#define MASTER_ROOT       1

/*
** The name of the schema table.  The name is different for TEMP.
** The name of the schema table.
*/
#define SCHEMA_TABLE(x) \
#define SCHEMA_TABLE(x)  ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME)
    ((!OMIT_TEMPDB)&&(x==1)?DFLT_TEMP_SCHEMA_TABLE:DFLT_SCHEMA_TABLE)

/*
** A convenience macro that returns the number of elements in
** an array.
*/
#define ArraySize(X)    ((int)(sizeof(X)/sizeof(X[0])))

/*
** Determine if the argument is a power of two
*/
#define IsPowerOfTwo(X) (((X)&((X)-1))==0)

/*
** The following value as a destructor means to use sqlite3DbFree().
** The sqlite3DbFree() routine requires two parameters instead of the
** one parameter that destructors normally want.  So we have to introduce
** this magic value that the code knows to handle differently.  Any
** pointer will work here as long as it is distinct from SQLITE_STATIC
** and SQLITE_TRANSIENT.
*/
#define SQLITE_DYNAMIC   ((sqlite3_destructor_type)sqlite3OomFault)
#define SQLITE_DYNAMIC   ((sqlite3_destructor_type)sqlite3MallocSize)

/*
** When SQLITE_OMIT_WSD is defined, it means that the target platform does
** not support Writable Static Data (WSD) such as global and static variables.
** All variables must either be on the stack or dynamically allocated from
** the heap.  When WSD is unsupported, the variable declarations scattered
** throughout the SQLite code must become constants instead.  The SQLITE_WSD
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
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







-
-

-

















-



-





-







*/
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 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;
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
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







-
















-
-
-
+
+
+







*/
#define BMS  ((int)(sizeof(Bitmask)*8))

/*
** A bit in a Bitmask
*/
#define MASKBIT(n)   (((Bitmask)1)<<(n))
#define MASKBIT64(n) (((u64)1)<<(n))
#define MASKBIT32(n) (((unsigned int)1)<<(n))
#define ALLBITS      ((Bitmask)-1)

/* A VList object records a mapping between parameters/variables/wildcards
** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
** variable number associated with that parameter.  See the format description
** on the sqlite3VListAdd() routine for more information.  A VList is really
** just an array of integers.
*/
typedef int VList;

/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
** pointer types (i.e. FuncDef) defined above.
*/
#include "pager.h"
#include "btree.h"
#include "vdbe.h"
#include "btree.h"
#include "vdbe.h"
#include "pager.h"
#include "pcache.h"
#include "os.h"
#include "mutex.h"

/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
** synchronous setting to EXTRA.  It is no longer supported.
*/
1327
1328
1329
1330
1331
1332
1333

1334
1335
1336
1337
1338
1339
1340
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266







+







**
** DB_UnresetViews means that one or more views have column names that
** have been filled out.  If the schema changes, these column names might
** changes and so the view will need to be reset.
*/
#define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
#define DB_UnresetViews    0x0002  /* Some views have defined column names */
#define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */
#define DB_ResetWanted     0x0008  /* Reset the schema when nSchemaLock==0 */

/*
** The number of different kinds of things that can be limited
** using the sqlite3_limit() interface.
*/
#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
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
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







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




-





-
-
-
-
-
-







-
-
-
-
-
-
-
-
-
-
-







**
** Lookaside allocations are only allowed for objects that are associated
** with a particular database connection.  Hence, schema information cannot
** be stored in lookaside because in shared cache mode the schema information
** is shared by multiple database connections.  Therefore, while parsing
** schema information, the Lookaside.bEnabled flag is cleared so that
** lookaside allocations are not used to construct the schema objects.
**
** New lookaside allocations are only allowed if bDisable==0.  When
** bDisable is greater than zero, sz is set to zero which effectively
** disables lookaside without adding a new test for the bDisable flag
** in a performance-critical path.  sz should be set by to szTrue whenever
** bDisable changes back to zero.
**
** Lookaside buffers are initially held on the pInit list.  As they are
** used and freed, they are added back to the pFree list.  New allocations
** come off of pFree first, then pInit as a fallback.  This dual-list
** allows use to compute a high-water mark - the maximum number of allocations
** outstanding at any point in the past - by subtracting the number of
** allocations on the pInit list from the total number of allocations.
**
** Enhancement on 2019-12-12:  Two-size-lookaside
** The default lookaside configuration is 100 slots of 1200 bytes each.
** The larger slot sizes are important for performance, but they waste
** a lot of space, as most lookaside allocations are less than 128 bytes.
** The two-size-lookaside enhancement breaks up the lookaside allocation
** into two pools:  One of 128-byte slots and the other of the default size
** (1200-byte) slots.   Allocations are filled from the small-pool first,
** failing over to the full-size pool if that does not work.  Thus more
** lookaside slots are available while also using less memory.
** This enhancement can be omitted by compiling with
** SQLITE_OMIT_TWOSIZE_LOOKASIDE.
*/
struct Lookaside {
  u32 bDisable;           /* Only operate the lookaside when zero */
  u16 sz;                 /* Size of each buffer in bytes */
  u16 szTrue;             /* True value of sz, even if disabled */
  u8 bMalloced;           /* True if pStart obtained from sqlite3_malloc() */
  u32 nSlot;              /* Number of lookaside slots allocated */
  u32 anStat[3];          /* 0: hits.  1: size misses.  2: full misses */
  LookasideSlot *pInit;   /* List of buffers not previously used */
  LookasideSlot *pFree;   /* List of available buffers */
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
  LookasideSlot *pSmallInit; /* List of small buffers not prediously used */
  LookasideSlot *pSmallFree; /* List of available small buffers */
  void *pMiddle;          /* First byte past end of full-size buffers and
                          ** the first byte of LOOKASIDE_SMALL buffers */
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
  void *pStart;           /* First byte of available memory space */
  void *pEnd;             /* First byte past end of available space */
};
struct LookasideSlot {
  LookasideSlot *pNext;    /* Next buffer in the list of free buffers */
};

#define DisableLookaside  db->lookaside.bDisable++;db->lookaside.sz=0
#define EnableLookaside   db->lookaside.bDisable--;\
   db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue

/* Size of the smaller allocations in two-size lookside */
#ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE
#  define LOOKASIDE_SMALL           0
#else
#  define LOOKASIDE_SMALL         128
#endif

/*
** A hash table for built-in function definitions.  (Application-defined
** functions use a regular table table from hash.h.)
**
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
** Collisions are on the FuncDef.u.pHash chain.  Use the SQLITE_FUNC_HASH()
** macro to compute a hash on the function name.
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496

1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509

1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530

1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550

1551
1552
1553
1554
1555
1556
1557
1558
1360
1361
1362
1363
1364
1365
1366





1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386

1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413




1414
1415
1416
1417
1418
1419
1420
1421



1422

1423
1424
1425
1426
1427
1428
1429







-
-
-
-
-







-
+












-
+




















-
+





-
-
-
-








-
-
-
+
-







#define SQLITE_TRACE_XPROFILE        0x80     /* Use the legacy xProfile */
#else
#define SQLITE_TRACE_LEGACY          0
#define SQLITE_TRACE_XPROFILE        0
#endif /* SQLITE_OMIT_DEPRECATED */
#define SQLITE_TRACE_NONLEGACY_MASK  0x0f     /* Normal flags */

/*
** 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 */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  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 */
  u16 dbOptFlags;               /* Flags to enable/disable optimizations */
  u8 enc;                       /* Text encoding */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  u8 mallocFailed;              /* True if we have seen a malloc failure */
  u8 bBenignMalloc;             /* Do not require OOMs if true */
  u8 dfltLockMode;              /* Default locking-mode for attached dbs */
  signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  u8 suppressErr;               /* Do not issue error messages if true */
  u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
  u8 isTransactionSavepoint;    /* True if the outermost savepoint is a TS */
  u8 mTrace;                    /* zero or more SQLITE_TRACE flags */
  u8 noSharedCache;             /* True if no shared-cache backends */
  u8 nSqlExec;                  /* Number of pending OP_SqlExec opcodes */
  int nextPagesize;             /* Pagesize after VACUUM if >0 */
  u32 magic;                    /* Magic number for detect library misuse */
  int nChange;                  /* Value returned by sqlite3_changes() */
  int nTotalChange;             /* Value returned by sqlite3_total_changes() */
  int aLimit[SQLITE_N_LIMIT];   /* Limits */
  int nMaxSorterMmap;           /* Maximum size of regions mapped by sorter */
  struct sqlite3InitInfo {      /* Information used during initialization */
    Pgno newTnum;               /* Rootpage of table being initialized */
    int newTnum;                /* Rootpage of table being initialized */
    u8 iDb;                     /* Which db file is being initialized */
    u8 busy;                    /* TRUE if currently initializing */
    unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
    unsigned imposterTable : 1; /* Building an imposter table */
    unsigned reopenMemdb : 1;   /* ATTACH is really a reopen using MemDB */
    unsigned bDropColumn : 1;   /* Doing schema check after DROP COLUMN */
    char **azInit;              /* "type", "name", and "tbl_name" columns */
                                /*   or if bDropColumn, then azInit[0] is the */
                                /*   name of the column being dropped */
  } init;
  int nVdbeActive;              /* Number of VDBEs currently running */
  int nVdbeRead;                /* Number of active VDBEs that read or write */
  int nVdbeWrite;               /* Number of active VDBEs that read and write */
  int nVdbeExec;                /* Number of nested calls to VdbeExec() */
  int nVDestroy;                /* Number of active OP_VDestroy operations */
  int nExtension;               /* Number of loaded extensions */
  void **aExtension;            /* Array of shared library handles */
  union {
    void (*xLegacy)(void*,const char*);     /* Legacy trace function */
    int (*xV2)(u32,void*,void*,void*);      /* V2 Trace function */
  int (*xTrace)(u32,void*,void*,void*);     /* Trace function */
  } trace;
  void *pTraceArg;                          /* Argument to the trace function */
#ifndef SQLITE_OMIT_DEPRECATED
  void (*xProfile)(void*,const char*,u64);  /* Profiling function */
  void *pProfileArg;                        /* Argument to profile function */
#endif
  void *pCommitArg;                 /* Argument to xCommitCallback() */
  int (*xCommitCallback)(void*);    /* Invoked at every commit. */
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613

1614
1615
1616
1617
1618
1619
1620
1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482

1483
1484
1485
1486
1487
1488
1489
1490







-







-
+







  VTable *pDisconnect;          /* Disconnect these in next sqlite3_prepare() */
#endif
  Hash aFunc;                   /* Hash table of connection functions */
  Hash aCollSeq;                /* All collating sequences */
  BusyHandler busyHandler;      /* Busy callback */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
  Savepoint *pSavepoint;        /* List of active savepoints */
  int nAnalysisLimit;           /* Number of index rows to ANALYZE */
  int busyTimeout;              /* Busy handler timeout, in msec */
  int nSavepoint;               /* Number of non-transaction savepoints */
  int nStatement;               /* Number of nested statement-transactions  */
  i64 nDeferredCons;            /* Net deferred constraints this transaction. */
  i64 nDeferredImmCons;         /* Net deferred immediate constraints */
  int *pnBytesFreed;            /* If not NULL, increment this in DbFree() */
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
  /* The following variables are all protected by the STATIC_MAIN
  /* The following variables are all protected by the STATIC_MASTER
  ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
  **
  ** When X.pUnlockConnection==Y, that means that X is waiting for Y to
  ** unlock so that it can proceed.
  **
  ** When X.pBlockingConnection==Y, that means that something that X tried
  ** tried to do recently failed with an SQLITE_LOCKED error due to locks
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
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







-
-
-
-
-
-
-








-
+






-
-
+
+
+








/*
** A macro to discover the encoding of a database.
*/
#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc)
#define ENC(db)        ((db)->enc)

/*
** A u64 constant where the lower 32 bits are all zeros.  Only the
** upper 32 bits are included in the argument.  Necessary because some
** C-compilers still do not accept LL integer literals.
*/
#define HI(X)  ((u64)(X)<<32)

/*
** Possible values for the sqlite3.flags.
**
** Value constraints (enforced via assert()):
**      SQLITE_FullFSync     == PAGER_FULLFSYNC
**      SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
**      SQLITE_CacheSpill    == PAGER_CACHE_SPILL
*/
#define SQLITE_WriteSchema    0x00000001  /* OK to update SQLITE_SCHEMA */
#define SQLITE_WriteSchema    0x00000001  /* OK to update SQLITE_MASTER */
#define SQLITE_LegacyFileFmt  0x00000002  /* Create new databases in format 1 */
#define SQLITE_FullColNames   0x00000004  /* Show full column names on SELECT */
#define SQLITE_FullFSync      0x00000008  /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync  0x00000010  /* Use full fsync for checkpoint */
#define SQLITE_CacheSpill     0x00000020  /* OK to spill pager cache */
#define SQLITE_ShortColNames  0x00000040  /* Show short columns names */
#define SQLITE_TrustedSchema  0x00000080  /* Allow unsafe functions and
                                          ** vtabs in the schema definition */
#define SQLITE_CountRows      0x00000080  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_IgnoreChecks   0x00000200  /* Do not enforce check constraints */
#define SQLITE_ReadUncommit   0x00000400  /* READ UNCOMMITTED in shared-cache */
#define SQLITE_NoCkptOnClose  0x00000800  /* No checkpoint on close()/DETACH */
#define SQLITE_ReverseOrder   0x00001000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x00002000  /* Enable recursive triggers */
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693

1694
1695
1696
1697
1698
1699
1700






1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735

















1736
1737
1738

1739
1740
1741
1742
1743
1744
1745
1543
1544
1545
1546
1547
1548
1549






1550
1551
1552
1553






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


1570
1571
1572
1573
1574
1575

















1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592



1593
1594
1595
1596
1597
1598
1599
1600







-
-
-
-
-
-


+

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










-
-






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







#define SQLITE_Fts3Tokenizer  0x00400000  /* Enable fts3_tokenizer(2) */
#define SQLITE_EnableQPSG     0x00800000  /* Query Planner Stability Guarantee*/
#define SQLITE_TriggerEQP     0x01000000  /* Show trigger EXPLAIN QUERY PLAN */
#define SQLITE_ResetDatabase  0x02000000  /* Reset the database */
#define SQLITE_LegacyAlter    0x04000000  /* Legacy ALTER TABLE behaviour */
#define SQLITE_NoSchemaError  0x08000000  /* Do not report schema parse errors*/
#define SQLITE_Defensive      0x10000000  /* Input SQL is likely hostile */
#define SQLITE_DqsDDL         0x20000000  /* dbl-quoted strings allowed in DDL*/
#define SQLITE_DqsDML         0x40000000  /* dbl-quoted strings allowed in DML*/
#define SQLITE_EnableView     0x80000000  /* Enable the use of views */
#define SQLITE_CountRows      HI(0x00001) /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */

/* Flags used only if debugging */
#define HI(X)  ((u64)(X)<<32)
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace       HI(0x0100000) /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    HI(0x0200000) /* Debug listings of VDBE progs */
#define SQLITE_VdbeTrace      HI(0x0400000) /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_VdbeEQP        HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_ParserTrace    HI(0x2000000) /* PRAGMA parser_trace=ON */
#define SQLITE_SqlTrace       HI(0x0001)  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    HI(0x0002)  /* Debug listings of VDBE progs */
#define SQLITE_VdbeTrace      HI(0x0004)  /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace HI(0x0008)  /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_VdbeEQP        HI(0x0010)  /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_ParserTrace    HI(0x0020)  /* PRAGMA parser_trace=ON */
#endif

/*
** Allowed values for sqlite3.mDbFlags
*/
#define DBFLAG_SchemaChange   0x0001  /* Uncommitted Hash table changes */
#define DBFLAG_PreferBuiltin  0x0002  /* Preference to built-in funcs */
#define DBFLAG_Vacuum         0x0004  /* Currently in a VACUUM */
#define DBFLAG_VacuumInto     0x0008  /* Currently running VACUUM INTO */
#define DBFLAG_SchemaKnownOk  0x0010  /* Schema is known to be valid */
#define DBFLAG_InternalFunc   0x0020  /* Allow use of internal functions */
#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_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_Stat34         0x0800   /* Use STAT3 or STAT4 data */
   /* TH3 expects the Stat34  ^^^^^^ 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_MinMaxOpt      0x00010000 /* The min/max optimization */
#define SQLITE_ExistsToIN     0x00020000 /* The EXISTS-to-IN optimization */
#define SQLITE_AllOpts        0xffffffff /* All optimizations */
#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)

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
1669
1670
1671
1672
1673
1674
1675


1676
1677
1678
1679
1680
1681
1682
1683
1684
1685

1686
1687
1688
1689
1690
1691

1692
1693
1694
1695













1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
















1711
1712
1713
1714
1715
1716
1717



1718
1719
1720
1721
1722
1723
1724







-
-










-
+





-
+



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















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







-
-
-







** are assert() statements in the code to verify this.
**
** Value constraints (enforced via assert()):
**     SQLITE_FUNC_MINMAX    ==  NC_MinMaxAgg      == SF_MinMaxAgg
**     SQLITE_FUNC_LENGTH    ==  OPFLAG_LENGTHARG
**     SQLITE_FUNC_TYPEOF    ==  OPFLAG_TYPEOFARG
**     SQLITE_FUNC_CONSTANT  ==  SQLITE_DETERMINISTIC from the API
**     SQLITE_FUNC_DIRECT    ==  SQLITE_DIRECTONLY from the API
**     SQLITE_FUNC_UNSAFE    ==  SQLITE_INNOCUOUS
**     SQLITE_FUNC_ENCMASK   depends on SQLITE_UTF* macros in the API
*/
#define SQLITE_FUNC_ENCMASK  0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
#define SQLITE_FUNC_LIKE     0x0004 /* Candidate for the LIKE optimization */
#define SQLITE_FUNC_CASE     0x0008 /* Case-sensitive LIKE-type function */
#define SQLITE_FUNC_EPHEM    0x0010 /* Ephemeral.  Delete with VDBE */
#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/
#define SQLITE_FUNC_LENGTH   0x0040 /* Built-in length() function */
#define SQLITE_FUNC_TYPEOF   0x0080 /* Built-in typeof() function */
#define SQLITE_FUNC_COUNT    0x0100 /* Built-in count(*) aggregate */
/*                           0x0200 -- available for reuse */
#define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */
#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
#define SQLITE_FUNC_MINMAX   0x1000 /* True for min() and max() aggregates */
#define SQLITE_FUNC_SLOCHNG  0x2000 /* "Slow Change". Value constant during a
                                    ** single query - might change over time */
#define SQLITE_FUNC_TEST     0x4000 /* Built-in testing functions */
#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
#define SQLITE_FUNC_OFFSET   0x8000 /* Built-in sqlite_offset() function */
#define SQLITE_FUNC_WINDOW   0x00010000 /* Built-in window-only function */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
#define SQLITE_FUNC_DIRECT   0x00080000 /* Not for use in TRIGGERs or VIEWs */
#define SQLITE_FUNC_SUBTYPE  0x00100000 /* Result likely to have sub-type */
#define SQLITE_FUNC_UNSAFE   0x00200000 /* Function has side effects */
#define SQLITE_FUNC_INLINE   0x00400000 /* Functions implemented in-line */

/* Identifier numbers for each in-line function */
#define INLINEFUNC_coalesce             0
#define INLINEFUNC_implies_nonnull_row  1
#define INLINEFUNC_expr_implies_expr    2
#define INLINEFUNC_expr_compare         3      
#define INLINEFUNC_affinity             4
#define INLINEFUNC_iif                  5
#define INLINEFUNC_unlikely            99  /* Default case */

/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** used to create the initializers for the FuncDef structures.
**
**   FUNCTION(zName, nArg, iArg, bNC, xFunc)
**     Used to create a scalar function definition of a function zName
**     implemented by C function xFunc that accepts nArg arguments. The
**     value passed as iArg is cast to a (void*) and made available
**     as the user-data (sqlite3_user_data()) for the function. If
**     argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
**   VFUNCTION(zName, nArg, iArg, bNC, xFunc)
**     Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag.
**
**   SFUNCTION(zName, nArg, iArg, bNC, xFunc)
**     Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
**     adds the SQLITE_DIRECTONLY flag.
**
**   INLINE_FUNC(zName, nArg, iFuncId, mFlags)
**     zName is the name of a function that is implemented by in-line
**     byte code rather than by the usual callbacks. The iFuncId
**     parameter determines the function id.  The mFlags parameter is
**     optional SQLITE_FUNC_ flags for this function.
**
**   TEST_FUNC(zName, nArg, iFuncId, mFlags)
**     zName is the name of a test-only function implemented by in-line
**     byte code rather than by the usual callbacks. The iFuncId
**     parameter determines the function id.  The mFlags parameter is
**     optional SQLITE_FUNC_ flags for this function.
**
**   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)
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
1743
1744
1745
1746
1747
1748
1749













1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777







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















+
+
+
+
+
+







*/
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
  {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
   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} }
#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
  {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
   0, 0, xFunc, 0, 0, 0, #zName, {0} }
#define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
  {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
   (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} }
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
  {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
  {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
   pArg, 0, xFunc, 0, 0, 0, #zName, }
#define LIKEFUNC(zName, nArg, arg, flags) \
  {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
   (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \
  {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
  {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
  {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
  {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
   0, 0, xFunc, 0, 0, 0, #zName, {0} }

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







-






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



-
+




-
-
+


-
+
-
-
-
-
-

-
-
-
-
+
+
+
+

-
-
-
-
-
-







** Each SQLite module (virtual table definition) is defined by an
** instance of the following structure, stored in the sqlite3.aModule
** hash table.
*/
struct Module {
  const sqlite3_module *pModule;       /* Callback pointers */
  const char *zName;                   /* Name passed to create_module() */
  int nRefModule;                      /* Number of pointers to this object */
  void *pAux;                          /* pAux passed to create_module() */
  void (*xDestroy)(void *);            /* Module destructor function */
  Table *pEpoTab;                      /* Eponymous table for this module */
};

/*
** Information about each column of an SQL table is held in an instance
** of the Column structure, in the Table.aCol[] array.
** information about each column of an SQL table is held in an instance
** of this structure.
**
** Definitions:
**
**   "table column index"     This is the index of the column in the
**                            Table.aCol[] array, and also the index of
**                            the column in the original CREATE TABLE stmt.
**
**   "storage column index"   This is the index of the column in the
**                            record BLOB generated by the OP_MakeRecord
**                            opcode.  The storage column index is less than
**                            or equal to the table column index.  It is
**                            equal if and only if there are no VIRTUAL
**                            columns to the left.
*/
struct Column {
  char *zName;     /* Name of this column, \000, then the type */
  Expr *pDflt;     /* Default value or GENERATED ALWAYS AS value */
  Expr *pDflt;     /* Default value of this column */
  char *zColl;     /* Collating sequence.  If NULL, use the default */
  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 */
  u8 colFlags;     /* Boolean properties.  See COLFLAG_ defines below */
};

/* Allowed values for Column.colFlags.
/* 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_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 */
#define COLFLAG_STORED    0x0040   /* GENERATED ALWAYS AS ... STORED */
#define COLFLAG_NOTAVAIL  0x0080   /* STORED column not yet calculated */
#define COLFLAG_BUSY      0x0100   /* Blocks recursion on GENERATED columns */
#define COLFLAG_GENERATED 0x0060   /* Combo: _STORED, _VIRTUAL */
#define COLFLAG_NOINSERT  0x0062   /* Combo: _HIDDEN, _STORED, _VIRTUAL */

/*
** A "Collating Sequence" is defined by an instance of the following
** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence.
**
** If CollSeq.xCmp is NULL, it means that the
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091





2092
2093
2094
2095
2096
2097
2098
1867
1868
1869
1870
1871
1872
1873






1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885







-
-
-
-
-
-
+
+
+
+
+







** But rather than start with 0 or 1, we begin with 'A'.  That way,
** when multiple affinity types are concatenated into a string and
** used as the P4 operand, they will be more readable.
**
** Note also that the numeric types are grouped together so that testing
** for a numeric type is a single comparison.  And the BLOB type is first.
*/
#define SQLITE_AFF_NONE     0x40  /* '@' */
#define SQLITE_AFF_BLOB     0x41  /* 'A' */
#define SQLITE_AFF_TEXT     0x42  /* 'B' */
#define SQLITE_AFF_NUMERIC  0x43  /* 'C' */
#define SQLITE_AFF_INTEGER  0x44  /* 'D' */
#define SQLITE_AFF_REAL     0x45  /* 'E' */
#define SQLITE_AFF_BLOB     'A'
#define SQLITE_AFF_TEXT     'B'
#define SQLITE_AFF_NUMERIC  'C'
#define SQLITE_AFF_INTEGER  'D'
#define SQLITE_AFF_REAL     'E'

#define sqlite3IsNumericAffinity(X)  ((X)>=SQLITE_AFF_NUMERIC)

/*
** The SQLITE_AFF_MASK values masks off the significant bits of an
** affinity value.
*/
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188

2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209

2210
2211
2212
2213
2214
2215
2216
2217
2218
2219

2220
2221
2222
2223
2224
2225
2226
2227
2228

2229
2230
2231
2232
2233


2234
2235

2236
2237
2238
2239
2240
2241


2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
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







-




-
-
-
-
-
-













-
+




-
















+









-
+
-
-
-
-
-
-


-
+



-
-
+
+
-
-
+


-
-
-
-
+
+
-
-








-
-


-







*/
struct VTable {
  sqlite3 *db;              /* Database connection associated with this table */
  Module *pMod;             /* Pointer to module implementation */
  sqlite3_vtab *pVtab;      /* Pointer to vtab instance */
  int nRef;                 /* Number of pointers to this structure */
  u8 bConstraint;           /* True if constraints are supported */
  u8 eVtabRisk;             /* Riskiness of allowing hacker access */
  int iSavepoint;           /* Depth of the SAVEPOINT stack */
  VTable *pNext;            /* Next in linked list (see above) */
};

/* Allowed values for VTable.eVtabRisk
*/
#define SQLITE_VTABRISK_Low          0
#define SQLITE_VTABRISK_Normal       1
#define SQLITE_VTABRISK_High         2

/*
** The schema for each SQL table and view is represented in memory
** by an instance of the following structure.
*/
struct Table {
  char *zName;         /* Name of the table or view */
  Column *aCol;        /* Information about each column */
  Index *pIndex;       /* List of SQL indexes on this table. */
  Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
  FKey *pFKey;         /* Linked list of all foreign keys in this table */
  char *zColAff;       /* String defining the affinity of each column */
  ExprList *pCheck;    /* All CHECK constraints */
                       /*   ... also used as column name list in a VIEW */
  Pgno tnum;           /* Root BTree page for this table */
  int tnum;            /* Root BTree page for this table */
  u32 nTabRef;         /* Number of pointers to this Table */
  u32 tabFlags;        /* Mask of TF_* values */
  i16 iPKey;           /* If not negative, use aCol[iPKey] as the rowid */
  i16 nCol;            /* Number of columns in this table */
  i16 nNVCol;          /* Number of columns that are not VIRTUAL */
  LogEst nRowLogEst;   /* Estimated rows in table - from sqlite_stat1 table */
  LogEst szTabRow;     /* Estimated size of each table row in bytes */
#ifdef SQLITE_ENABLE_COSTMULT
  LogEst costMult;     /* Cost multiplier for using this table */
#endif
  u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
  int addColOffset;    /* Offset in CREATE TABLE stmt to add a new column */
#endif
#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".
** special handling during INSERT processing.
**
** 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_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_WithoutRowid    0x0020    /* No rowid.  PRIMARY KEY is the key */
#define TF_NoVisibleRowid  0x0040    /* No user-visible "rowid" column */
#define TF_HasGenerated    0x0060    /* Combo: HasVirtual + HasStored */
#define TF_WithoutRowid    0x0080    /* No rowid.  PRIMARY KEY is the key */
#define TF_OOOHidden       0x0080    /* Out-of-Order hidden columns */
#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_HasNotNull      0x0200    /* Contains NOT NULL constraints */
#define TF_Shadow          0x0400    /* 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
#  define IsVirtual(X)      ((X)->nModuleArg)
#  define ExprIsVtab(X)  \
              ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg)
#else
#  define IsVirtual(X)      0
#  define ExprIsVtab(X)     0
#endif

/*
** Macros to determine if a column is hidden.  IsOrdinaryHiddenColumn()
** only works for non-virtual tables (ordinary tables and views) and is
** always false unless SQLITE_ENABLE_HIDDEN_COLUMNS is defined.  The
** IsHiddenColumn() macro is general purpose.
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343

2344
2345
2346
2347

2348
2349
2350
2351
2352
2353
2354
2355

2356
2357
2358
2359
2360
2361
2362
2099
2100
2101
2102
2103
2104
2105


2106

2107
2108
2109


2110
2111
2112
2113



2114

2115
2116
2117
2118
2119
2120
2121
2122







-
-

-
+


-
-
+



-
-
-

-
+







** 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, 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.  SETDFLT means that the foreign key is set
** to its default value.  CASCADE means that a DELETE or UPDATE of the
** 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 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.
** 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 */
2379
2380
2381
2382
2383
2384
2385
2386

2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2139
2140
2141
2142
2143
2144
2145

2146
2147
2148
2149






2150
2151
2152
2153
2154
2155
2156







-
+



-
-
-
-
-
-







*/
struct KeyInfo {
  u32 nRef;           /* Number of references to this KeyInfo object */
  u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  u16 nKeyField;      /* Number of key columns in the index */
  u16 nAllField;      /* Total columns, including key plus others */
  sqlite3 *db;        /* The database connection */
  u8 *aSortFlags;     /* Sort order for each column. */
  u8 *aSortOrder;     /* Sort order for each column. */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
};

/*
** Allowed bit values for entries in the KeyInfo.aSortFlags[] array.
*/
#define KEYINFO_ORDER_DESC    0x01    /* DESC sort order */
#define KEYINFO_ORDER_BIGNULL 0x02    /* NULL is larger than any other value */

/*
** This object holds a record which has been parsed out into individual
** fields, for the purposes of doing a comparison.
**
** A record is an object that contains one or more fields of data.
** Records are used to store the content of a table row and to store
** the key of an index.  A blob encoding of a record is created by
2463
2464
2465
2466
2467
2468
2469
2470

2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489

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

2505
2506
2507
2508
2509
2510
2511
2217
2218
2219
2220
2221
2222
2223

2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242

2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255



2256
2257
2258
2259
2260
2261
2262
2263







-
+


















-
+












-
-
-
+







** must be unique and what to do if they are not.  When Index.onError=OE_None,
** it means this is not a unique index.  Otherwise it is a unique index
** and the value of Index.onError indicate the which conflict resolution
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
**
** While parsing a CREATE TABLE or CREATE INDEX statement in order to
** generate VDBE code (as opposed to parsing one read from an sqlite_schema
** generate VDBE code (as opposed to parsing one read from an sqlite_master
** table as part of parsing an existing database schema), transient instances
** of this structure may be created. In this case the Index.tnum variable is
** used to store the address of a VDBE instruction, not a database page
** number (it cannot - the database page is not allocated until the VDBE
** program is executed). See convertToWithoutRowidTable() for details.
*/
struct Index {
  char *zName;             /* Name of this index */
  i16 *aiColumn;           /* Which columns are used by this index.  1st is 0 */
  LogEst *aiRowLogEst;     /* From ANALYZE: Est. rows selected by each column */
  Table *pTable;           /* The SQL table being indexed */
  char *zColAff;           /* String defining the affinity of each column */
  Index *pNext;            /* The next index associated with the same table */
  Schema *pSchema;         /* Schema containing this index */
  u8 *aSortOrder;          /* for each column: True==DESC, False==ASC */
  const char **azColl;     /* Array of collation sequence names for index */
  Expr *pPartIdxWhere;     /* WHERE clause for partial indices */
  ExprList *aColExpr;      /* Column expressions */
  Pgno tnum;               /* DB Page containing root of this index */
  int tnum;                /* DB Page containing root of this index */
  LogEst szIdxRow;         /* Estimated average row size in bytes */
  u16 nKeyCol;             /* Number of columns forming the key */
  u16 nColumn;             /* Number of columns stored in the index */
  u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  unsigned idxType:2;      /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */
  unsigned bUnordered:1;   /* Use this index for == or IN queries only */
  unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
  unsigned isResized:1;    /* True if resizeIndexObject() has been called */
  unsigned isCovering:1;   /* True if this is a covering index */
  unsigned noSkipScan:1;   /* Do not try to use skip-scan if true */
  unsigned hasStat1:1;     /* aiRowLogEst values come from sqlite_stat1 */
  unsigned bNoQuery:1;     /* Do not use this index to optimize queries */
  unsigned bAscKeyBug:1;   /* True if the bba7b69f9849b5bf bug applies */
  unsigned bHasVCol:1;     /* Index references one or more VIRTUAL columns */
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  int nSample;             /* Number of elements in aSample[] */
  int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
  tRowcnt *aAvgEq;         /* Average nEq values for keys not in aSample */
  IndexSample *aSample;    /* Samples of the left-most key */
  tRowcnt *aiRowEst;       /* Non-logarithmic stat1 data for this index */
  tRowcnt nRowEst0;        /* Non-logarithmic number of rows in the index */
#endif
2529
2530
2531
2532
2533
2534
2535
2536

2537
2538
2539
2540
2541
2542
2543
2281
2282
2283
2284
2285
2286
2287

2288
2289
2290
2291
2292
2293
2294
2295







-
+







/* The Index.aiColumn[] values are normally positive integer.  But
** there are some negative values that have special meaning:
*/
#define XN_ROWID     (-1)     /* Indexed column is the rowid */
#define XN_EXPR      (-2)     /* Indexed column is an expression */

/*
** Each sample stored in the sqlite_stat4 table is represented in memory
** Each sample stored in the sqlite_stat3 table is represented in memory
** using a structure of this type.  See documentation at the top of the
** analyze.c source file for additional information.
*/
struct IndexSample {
  void *p;          /* Pointer to sampled record */
  int n;            /* Size of record in bytes */
  tRowcnt *anEq;    /* Est. number of rows where the key equals this sample */
2567
2568
2569
2570
2571
2572
2573
2574

2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598




2599
2600
2601
2602
2603
2604
2605

2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621

2622
2623
2624

2625
2626
2627
2628
2629
2630
2631
2319
2320
2321
2322
2323
2324
2325

2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345

2346



2347
2348
2349
2350
2351
2352
2353
2354
2355
2356

2357
2358
2359
2360
2361
2362

2363
2364
2365
2366
2367
2368
2369
2370
2371

2372
2373
2374

2375
2376
2377
2378
2379
2380
2381
2382







-
+



















-

-
-
-
+
+
+
+






-
+





-









-
+


-
+







};

/*
** An instance of this structure contains information needed to generate
** code for a SELECT that contains aggregate functions.
**
** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
** pointer to this structure.  The Expr.iAgg field is the index in
** pointer to this structure.  The Expr.iColumn field is the index in
** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
** code for that node.
**
** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
** original Select structure that describes the SELECT statement.  These
** fields do not need to be freed when deallocating the AggInfo structure.
*/
struct AggInfo {
  u8 directMode;          /* Direct rendering mode means take data directly
                          ** from source tables rather than from accumulators */
  u8 useSortingIdx;       /* In direct mode, reference the sorting index rather
                          ** than the source table */
  int sortingIdx;         /* Cursor number of the sorting index */
  int sortingIdxPTab;     /* Cursor number of pseudo-table */
  int nSortingColumn;     /* Number of columns in the sorting index */
  int mnReg, mxReg;       /* Range of registers allocated for aCol and aFunc */
  ExprList *pGroupBy;     /* The group by clause */
  struct AggInfo_col {    /* For each column used in source tables */
    Table *pTab;             /* Source table */
    Expr *pCExpr;            /* The original expression */
    int iTable;              /* Cursor number of the source table */
    int iMem;                /* Memory location that acts as accumulator */
    i16 iColumn;             /* Column number within the source table */
    i16 iSorterColumn;       /* Column number in the sorting index */
    int iColumn;             /* Column number within the source table */
    int iSorterColumn;       /* Column number in the sorting index */
    int iMem;                /* Memory location that acts as accumulator */
    Expr *pExpr;             /* The original expression */
  } *aCol;
  int nColumn;            /* Number of used entries in aCol[] */
  int nAccumulator;       /* Number of columns that show through to the output.
                          ** Additional columns are used only as parameters to
                          ** aggregate functions */
  struct AggInfo_func {   /* For each aggregate function */
    Expr *pFExpr;            /* Expression encoding the function */
    Expr *pExpr;             /* 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
** in systems with lots of prepared statements.  And few applications
** need more than about 10 or 20 variables.  But some extreme users want
** to have prepared statements with over 32766 variables, and for them
** to have prepared statements with over 32767 variables, and for them
** the option is available (at compile-time).
*/
#if SQLITE_MAX_VARIABLE_NUMBER<32767
#if SQLITE_MAX_VARIABLE_NUMBER<=32767
typedef i16 ynVar;
#else
typedef int ynVar;
#endif

/*
** Each node of an expression in the parse tree is an instance
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701

2702
2703
2704
2705
2706
2707
2708
2709
2439
2440
2441
2442
2443
2444
2445







2446

2447
2448
2449
2450
2451
2452
2453







-
-
-
-
-
-
-
+
-







** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
** are contained within the same memory allocation.  Note, however, that
** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately
** allocated, regardless of whether or not EP_Reduced is set.
*/
struct Expr {
  u8 op;                 /* Operation performed by this node */
  char affExpr;          /* affinity, or RAISE type */
  u8 op2;                /* TK_REGISTER/TK_TRUTH: original value of Expr.op
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth
                         ** TK_FUNCTION: NC_SelfRef flag if needs OP_PureFunc */
#ifdef SQLITE_DEBUG
  u8 vvaFlags;           /* Verification flags. */
  char affinity;         /* The affinity of the column or 0 if not a column */
#endif
  u32 flags;             /* Various flags.  EP_* See below */
  union {
    char *zToken;          /* Token value. Zero terminated and dequoted */
    int iValue;            /* Non-negative integer value if EP_IntValue */
  } u;

  /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740




2741
2742
2743
2744
2745

2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787




























2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821

2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871







2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885



2886

2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2470
2471
2472
2473
2474
2475
2476


2477
2478
2479
2480
2481

2482
2483
2484
2485
2486
2487
2488
2489

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




























2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532




2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547








2548
2549
2550
2551
2552
2553

2554


2555
2556


2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573












2574
2575
2576
2577
2578
2579
2580
2581







2582
2583
2584
2585
2586
2587
2588






2589
2590
2591
2592
2593



2594
2595
2596
2597
2598
2599
2600

2601
2602
2603
2604
2605
2606
2607
2608
2609
2610







2611
2612
2613
2614
2615
2616
2617







-
-





-
+
+
+
+




-
+














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















-
-
-
-
-
-
-
-






-
+
-
-


-
-

















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








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





-
-
-
+
+
+

+


-










-
-
-
-
-
-
-







#if SQLITE_MAX_EXPR_DEPTH>0
  int nHeight;           /* Height of the tree headed by this node */
#endif
  int iTable;            /* TK_COLUMN: cursor number of table holding column
                         ** TK_REGISTER: register number
                         ** TK_TRIGGER: 1 -> new, 0 -> old
                         ** EP_Unlikely:  134217728 times likelihood
                         ** 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 */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u8 op2;                /* TK_REGISTER: original value of Expr.op
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */
  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 */
    Window *pWin;          /* TK_FUNCTION: Window definition for the func */
    struct {               /* TK_IN, TK_SELECT, and TK_EXISTS */
      int iAddr;             /* Subroutine entry address */
      int regReturn;         /* Register used to hold return address */
    } sub;
  } y;
};

/*
** The following are the meanings of bits in the Expr.flags field.
** Value restrictions:
**
**          EP_Agg == NC_HasAgg == SF_HasAgg
**          EP_Win == NC_HasWin
*/
#define EP_FromJoin   0x000001 /* Originates in ON/USING clause of outer join */
#define EP_Distinct   0x000002 /* Aggregate function with DISTINCT keyword */
#define EP_HasFunc    0x000004 /* Contains one or more functions of any kind */
#define EP_FixedCol   0x000008 /* TK_Column with a known fixed value */
#define EP_Agg        0x000010 /* Contains one or more aggregate functions */
#define EP_VarSelect  0x000020 /* pSelect is correlated, not constant */
#define EP_DblQuoted  0x000040 /* token.z was originally in "..." */
#define EP_InfixFunc  0x000080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_Collate    0x000100 /* Tree contains a TK_COLLATE operator */
#define EP_Commuted   0x000200 /* Comparison operator has been commuted */
#define EP_IntValue   0x000400 /* Integer value contained in u.iValue */
#define EP_xIsSelect  0x000800 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Skip       0x001000 /* Operator does not contribute to affinity */
#define EP_Reduced    0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly  0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#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_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
#define EP_Distinct  0x000002 /* Aggregate function with DISTINCT keyword */
#define EP_HasFunc   0x000004 /* Contains one or more functions of any kind */
#define EP_FixedCol  0x000008 /* TK_Column with a known fixed value */
#define EP_Agg       0x000010 /* Contains one or more aggregate functions */
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_Collate   0x000100 /* Tree contains a TK_COLLATE operator */
#define EP_Generic   0x000200 /* Ignore COLLATE or affinity on this tree */
#define EP_IntValue  0x000400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Skip      0x001000 /* COLLATE, AS, or UNLIKELY */
#define EP_Reduced   0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_Win       0x008000 /* Contains window functions */
#define EP_MemToken  0x010000 /* Need to sqlite3DbFree() Expr.zToken */
#define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#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 */
#define EP_FromDDL  0x40000000 /* Originates from sqlite_schema */
               /*   0x80000000 // Available */

/*
** The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes.
*/
#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)

/*
** These macros can be used to test, set, or clear bits in the
** Expr.flags field.
*/
#define ExprHasProperty(E,P)     (((E)->flags&(P))!=0)
#define ExprHasAllProperty(E,P)  (((E)->flags&(P))==(P))
#define ExprSetProperty(E,P)     (E)->flags|=(P)
#define ExprClearProperty(E,P)   (E)->flags&=~(P)
#define ExprAlwaysTrue(E)   (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
#define ExprAlwaysFalse(E)  (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)


/* Flags for use with Expr.vvaFlags
*/
#define EP_NoReduce   0x01  /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Immutable  0x02  /* Do not change this Expr node */

/* The ExprSetVVAProperty() macro is used for Verification, Validation,
** and Accreditation only.  It works like ExprSetProperty() during VVA
** processes but is a no-op for delivery.
*/
#ifdef SQLITE_DEBUG
# define ExprSetVVAProperty(E,P)   (E)->vvaFlags|=(P)
# define ExprSetVVAProperty(E,P)  (E)->flags|=(P)
# define ExprHasVVAProperty(E,P)   (((E)->vvaFlags&(P))!=0)
# define ExprClearVVAProperties(E) (E)->vvaFlags = 0
#else
# define ExprSetVVAProperty(E,P)
# define ExprHasVVAProperty(E,P)   0
# define ExprClearVVAProperties(E)
#endif

/*
** Macros to determine the number of bytes required by a normal Expr
** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
** and an Expr struct with the EP_TokenOnly flag set.
*/
#define EXPR_FULLSIZE           sizeof(Expr)           /* Full size */
#define EXPR_REDUCEDSIZE        offsetof(Expr,iTable)  /* Common features */
#define EXPR_TOKENONLYSIZE      offsetof(Expr,pLeft)   /* Fewer features */

/*
** Flags passed to the sqlite3ExprDup() function. See the header comment
** above sqlite3ExprDup() for details.
*/
#define EXPRDUP_REDUCE         0x0001  /* Used reduced-size Expr nodes */

/*
** True if the expression passed as an argument was a function with
** an OVER() clause (a window function).
*/
#ifdef SQLITE_OMIT_WINDOWFUNC
# define IsWindowFunc(p) 0
#else
# define IsWindowFunc(p) ( \
    ExprHasProperty((p), EP_WinFunc) && p->y.pWin->eFrmType!=TK_FILTER \
 )
#endif

/*
** A list of expressions.  Each expression may optionally have a
** name.  An expr/name combination can be used in several ways, such
** as the list of "expr AS ID" fields following a "SELECT" or in the
** list of "ID = expr" items in an UPDATE.  A list of expressions can
** also be used as the argument to a function, in which case the a.zName
** field is not used.
**
** In order to try to keep memory usage down, the Expr.a.zEName field
** is used for multiple purposes:
**
**     eEName          Usage
**    ----------       -------------------------
**    ENAME_NAME       (1) the AS of result set column
**                     (2) COLUMN= of an UPDATE
** By default the Expr.zSpan field holds a human-readable description of
** the expression that is used in the generation of error messages and
** column labels.  In this case, Expr.zSpan is typically the text of a
** column expression as it exists in a SELECT statement.  However, if
** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name
** of the result column in the form: DATABASE.TABLE.COLUMN.  This later
** form is used for name resolution with nested FROM clauses.
**
**    ENAME_TAB        DB.TABLE.NAME used to resolve names
**                     of subqueries
**
**    ENAME_SPAN       Text of the original result set
**                     expression.
*/
struct ExprList {
  int nExpr;             /* Number of expressions on the list */
  struct ExprList_item { /* For each expression in the list */
    Expr *pExpr;            /* The parse tree for this expression */
    char *zEName;           /* Token associated with this expression */
    u8 sortFlags;           /* Mask of KEYINFO_ORDER_* flags */
    unsigned eEName :2;     /* Meaning of zEName */
    char *zName;            /* Token associated with this expression */
    char *zSpan;            /* Original text of the expression */
    u8 sortOrder;           /* 1 for DESC or 0 for ASC */
    unsigned done :1;       /* A flag to indicate when processing is finished */
    unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
    unsigned reusable :1;   /* Constant expression is reusable */
    unsigned bSorterRef :1; /* Defer evaluation until after sorting */
    unsigned bNulls: 1;     /* True if explicit "NULLS FIRST/LAST" */
    union {
      struct {
        u16 iOrderByCol;      /* For ORDER BY, column number in result set */
        u16 iAlias;           /* Index into Parse.aAlias[] for zName */
      } x;
      int iConstExprReg;      /* Register in which Expr value is cached */
    } u;
  } a[1];                  /* One slot for each expression in the list */
};

/*
** Allowed values for Expr.a.eEName
*/
#define ENAME_NAME  0       /* The AS clause of a result set */
#define ENAME_SPAN  1       /* Complete text of the result set expression */
#define ENAME_TAB   2       /* "DB.TABLE.NAME" for the result set */

/*
** An instance of this structure can hold a simple list of identifiers,
** such as the list "a,b,c" in the following statements:
**
**      INSERT INTO t(a,b,c) VALUES ...;
**      CREATE INDEX idx ON t(a,b,c);
**      CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...;
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2627
2628
2629
2630
2631
2632
2633







































2634
2635
2636
2637
2638
2639
2640







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







  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
2984
2985
2986
2987
2988
2989
2990




























2991

2992
2993
2994
2995
2996
2997
2998
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







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







**
** 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 */
    } 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 */
  SrcItem a[1];    /* One entry for each identifier on the list */
  } 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 */
3018
3019
3020
3021
3022
3023
3024
3025

3026
3027

3028
3029
3030
3031
3032
3033
3034
2711
2712
2713
2714
2715
2716
2717

2718
2719

2720
2721
2722
2723
2724
2725
2726
2727







-
+

-
+







#define WHERE_DUPLICATES_OK    0x0010 /* Ok to return a row more than once */
#define WHERE_OR_SUBCLAUSE     0x0020 /* Processing a sub-WHERE as part of
                                      ** the OR optimization  */
#define WHERE_GROUPBY          0x0040 /* pOrderBy is really a GROUP BY */
#define WHERE_DISTINCTBY       0x0080 /* pOrderby is really a DISTINCT clause */
#define WHERE_WANT_DISTINCT    0x0100 /* All output needs to be distinct */
#define WHERE_SORTBYGROUP      0x0200 /* Support sqlite3WhereIsSorted() */
                        /*     0x0400    not currently used */
#define WHERE_SEEK_TABLE       0x0400 /* Do not defer seeks on main table */
#define WHERE_ORDERBY_LIMIT    0x0800 /* ORDERBY+LIMIT on the inner loop */
                        /*     0x1000    not currently used */
#define WHERE_SEEK_UNIQ_TABLE  0x1000 /* Do not defer seeks if unique */
                        /*     0x2000    not currently used */
#define WHERE_USE_LIMIT        0x4000 /* Use the LIMIT in cost estimates */
                        /*     0x8000    not currently used */

/* Allowed return values from sqlite3WhereIsDistinct()
*/
#define WHERE_DISTINCT_NOOP      0  /* DISTINCT keyword not used */
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072

3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090






3091
3092
3093
3094
3095




3096
3097
3098
3099
3100




3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120

3121
3122
3123
3124
3125
3126

3127
3128
3129
3130
3131


3132
3133
3134


3135
3136
3137
3138
3139
3140
3141
2753
2754
2755
2756
2757
2758
2759

2760
2761
2762
2763

2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776






2777
2778
2779
2780
2781
2782





2783
2784
2785
2786





2787
2788
2789
2790



2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806

2807
2808
2809
2810



2811





2812
2813



2814
2815
2816
2817
2818
2819
2820
2821
2822







-




-
+












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
















-
+



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







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 */
  u16 ncFlags;         /* Zero or more NC_* flags defined below */
  Select *pWinSelect;  /* SELECT statement for any window functions */
};

/*
** Allowed values for the NameContext, ncFlags field.
**
** Value constraints (all checked via assert()):
**    NC_HasAgg    == SF_HasAgg    == EP_Agg
**    NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
**    NC_HasWin    == EP_Win
**
*/
#define NC_AllowAgg  0x00001  /* Aggregate functions are allowed here */
#define NC_PartIdx   0x00002  /* True if resolving a partial index WHERE */
#define NC_IsCheck   0x00004  /* True if resolving a CHECK constraint */
#define NC_GenCol    0x00008  /* True for a GENERATED ALWAYS AS clause */
#define NC_HasAgg    0x00010  /* One or more aggregate functions seen */
#define NC_IdxExpr   0x00020  /* True if resolving columns of CREATE INDEX */
#define NC_AllowAgg  0x0001  /* Aggregate functions are allowed here */
#define NC_PartIdx   0x0002  /* True if resolving a partial index WHERE */
#define NC_IsCheck   0x0004  /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x0008  /* True if analyzing arguments to an agg func */
#define NC_HasAgg    0x0010  /* One or more aggregate functions seen */
#define NC_IdxExpr   0x0020  /* 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_VarSelect 0x0040  /* A correlated subquery has been seen */
#define NC_UEList    0x0080  /* True if uNC.pEList is used */
#define NC_UAggInfo  0x0100  /* True if uNC.pAggInfo is used */
#define NC_UUpsert   0x0200  /* 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_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
#define NC_Complex   0x2000  /* True if a function or subquery seen */
#define NC_AllowWin  0x4000  /* Window functions are allowed here */
#define NC_HasWin    0x8000  /* 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 */

/*
** An instance of the following object describes a single ON CONFLICT
** clause in an upsert.
**
** The pUpsertTarget field is only set if the ON CONFLICT clause includes
** conflict-target clause.  (In "ON CONFLICT(a,b)" the "(a,b)" is the
** conflict-target clause.)  The pUpsertTargetWhere is the optional
** WHERE clause used to identify partial unique indexes.
**
** 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 */
  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 */
  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 fields above comprise the parse tree for the upsert clause.
  ** 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
  ** The fields below are used to transfer information from the INSERT
  ** processing down into the UPDATE processing while generating code.
  ** 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 */
  ** 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 */
};

/*
3152
3153
3154
3155
3156
3157
3158

3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846

2847
2848
2849
2850
2851
2852
2853







+






-







** as the OP_OpenEphm instruction is coded because not
** enough information about the compound query is known at that point.
** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
** for the result set.  The KeyInfo for addrOpenEphm[2] contains collating
** sequences for the ORDER BY clause.
*/
struct Select {
  ExprList *pEList;      /* The fields of the result */
  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  LogEst nSelectRow;     /* Estimated number of result rows */
  u32 selFlags;          /* Various SF_* values */
  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
  u32 selId;             /* Unique identifier number for this SELECT */
  int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
  ExprList *pEList;      /* The fields of the result */
  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
  Select *pPrior;        /* Prior select in a compound select statement */
  Select *pNext;         /* Next select to the left in a compound */
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208



















3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232



3233
3234
3235
3236
3237
3238
3239
2864
2865
2866
2867
2868
2869
2870



















2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889







2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916







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

















+
+
+







** "Select Flag".
**
** Value constraints (all checked via assert())
**     SF_HasAgg     == NC_HasAgg
**     SF_MinMaxAgg  == NC_MinMaxAgg     == SQLITE_FUNC_MINMAX
**     SF_FixedLimit == WHERE_USE_LIMIT
*/
#define SF_Distinct      0x0000001 /* Output should be DISTINCT */
#define SF_All           0x0000002 /* Includes the ALL keyword */
#define SF_Resolved      0x0000004 /* Identifiers have been resolved */
#define SF_Aggregate     0x0000008 /* Contains agg functions or a GROUP BY */
#define SF_HasAgg        0x0000010 /* Contains aggregate functions */
#define SF_UsesEphemeral 0x0000020 /* Uses the OpenEphemeral opcode */
#define SF_Expanded      0x0000040 /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo   0x0000080 /* FROM subqueries have Table metadata */
#define SF_Compound      0x0000100 /* Part of a compound query */
#define SF_Values        0x0000200 /* Synthesized from VALUES clause */
#define SF_MultiValue    0x0000400 /* Single VALUES term with multiple rows */
#define SF_NestedFrom    0x0000800 /* Part of a parenthesized FROM clause */
#define SF_MinMaxAgg     0x0001000 /* Aggregate containing min() or max() */
#define SF_Recursive     0x0002000 /* The recursive part of a recursive CTE */
#define SF_FixedLimit    0x0004000 /* nSelectRow set by a constant LIMIT */
#define SF_MaybeConvert  0x0008000 /* Need convertCompoundSelectToSubquery() */
#define SF_Converted     0x0010000 /* By convertCompoundSelectToSubquery() */
#define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */
#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */
#define SF_Distinct       0x00001  /* Output should be DISTINCT */
#define SF_All            0x00002  /* Includes the ALL keyword */
#define SF_Resolved       0x00004  /* Identifiers have been resolved */
#define SF_Aggregate      0x00008  /* Contains agg functions or a GROUP BY */
#define SF_HasAgg         0x00010  /* Contains aggregate functions */
#define SF_UsesEphemeral  0x00020  /* Uses the OpenEphemeral opcode */
#define SF_Expanded       0x00040  /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo    0x00080  /* FROM subqueries have Table metadata */
#define SF_Compound       0x00100  /* Part of a compound query */
#define SF_Values         0x00200  /* Synthesized from VALUES clause */
#define SF_MultiValue     0x00400  /* Single VALUES term with multiple rows */
#define SF_NestedFrom     0x00800  /* Part of a parenthesized FROM clause */
#define SF_MinMaxAgg      0x01000  /* Aggregate containing min() or max() */
#define SF_Recursive      0x02000  /* The recursive part of a recursive CTE */
#define SF_FixedLimit     0x04000  /* nSelectRow set by a constant LIMIT */
#define SF_MaybeConvert   0x08000  /* Need convertCompoundSelectToSubquery() */
#define SF_Converted      0x10000  /* By convertCompoundSelectToSubquery() */
#define SF_IncludeHidden  0x20000  /* Include hidden columns in output */
#define SF_ComplexResult  0x40000  /* 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
**                     identified by pDest->iSDParm.
**
**     SRT_Except      Remove results from the temporary index pDest->iSDParm.
**
**     SRT_Exists      Store a 1 in memory cell pDest->iSDParm if the result
**                     set is not empty.
**
**     SRT_Discard     Throw the results away.  This is used by SELECT
**                     statements within triggers whose only purpose is
**                     the side-effects of functions.
**
** All of the above are free to ignore their ORDER BY clause. Those that
** follow must honor the ORDER BY clause.
**
**     SRT_Output      Generate a row of output (using the OP_ResultRow
**                     opcode) for each row in the result set.
**
**     SRT_Mem         Only valid if the result is a single column.
**                     Store the first column of the first result row
**                     in register pDest->iSDParm then abandon the rest
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292

3293
3294
3295
3296

3297
3298

3299
3300
3301

3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316

3317
3318
3319
3320
3321
3322
3323
3324
3325
2947
2948
2949
2950
2951
2952
2953








2954
2955
2956
2957
2958



2959




2960
2961

2962
2963
2964

2965
2966
2967
2968
2969
2970
2971
2972

2973
2974
2975
2976
2977
2978

2979
2980

2981
2982
2983
2984
2985
2986
2987







-
-
-
-
-
-
-
-





-
-
-
+
-
-
-
-
+

-
+


-
+







-






-
+

-







**     SRT_Queue       Store results in priority queue pDest->iSDParm (really
**                     an index).  Append a sequence number so that all entries
**                     are distinct.
**
**     SRT_DistQueue   Store results in priority queue pDest->iSDParm only if
**                     the same record has never been stored before.  The
**                     index at pDest->iSDParm+1 hold all prior stores.
**
**     SRT_Upfrom      Store results in the temporary table already opened by
**                     pDest->iSDParm. If (pDest->iSDParm<0), then the temp
**                     table is an intkey table - in this case the first
**                     column returned by the SELECT is used as the integer
**                     key. If (pDest->iSDParm>0), then the table is an index
**                     table. (pDest->iSDParm) is the number of key columns in
**                     each index record in this case.
*/
#define SRT_Union        1  /* Store result as keys in an index */
#define SRT_Except       2  /* Remove result from a UNION index */
#define SRT_Exists       3  /* Store 1 if the result is not empty */
#define SRT_Discard      4  /* Do not save the results anywhere */
#define SRT_DistFifo     5  /* Like SRT_Fifo, but unique results only */
#define SRT_DistQueue    6  /* Like SRT_Queue, but unique results only */

#define SRT_Fifo         5  /* Store result as data with an automatic rowid */
/* The DISTINCT clause is ignored for all of the above.  Not that
** IgnorableDistinct() implies IgnorableOrderby() */
#define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue)

#define SRT_DistFifo     6  /* Like SRT_Fifo, but unique results only */
#define SRT_Queue        7  /* Store result in an queue */
#define SRT_Fifo         8  /* Store result as data with an automatic rowid */
#define SRT_DistQueue    8  /* Like SRT_Queue, but unique results only */

/* The ORDER BY clause is ignored for all of the above */
#define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo)
#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue)

#define SRT_Output       9  /* Output each row of result */
#define SRT_Mem         10  /* Store result in a memory cell */
#define SRT_Set         11  /* Store results as keys in an index */
#define SRT_EphemTab    12  /* Create transient tab and store like SRT_Table */
#define SRT_Coroutine   13  /* Generate a single row of result */
#define SRT_Table       14  /* Store result as data with an automatic rowid */
#define SRT_Upfrom      15  /* Store result as data with rowid */

/*
** An instance of this object describes where to put of the results of
** a SELECT statement.
*/
struct SelectDest {
  u8 eDest;            /* How to dispose of the results.  One of SRT_* above. */
  u8 eDest;            /* How to dispose of the results.  On of SRT_* above. */
  int iSDParm;         /* A parameter used by the eDest disposal method */
  int iSDParm2;        /* A second parameter for the eDest disposal method */
  int iSdst;           /* Base register where results are written */
  int nSdst;           /* Number of registers allocated */
  char *zAffSdst;      /* Affinity used when eDest==SRT_Set */
  ExprList *pOrderBy;  /* Key columns for SRT_Queue and SRT_DistQueue */
};

/*
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3041
3042
3043
3044
3045
3046
3047











3048
3049
3050
3051
3052
3053
3054







-
-
-
-
-
-
-
-
-
-
-







# 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
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3072
3073
3074
3075
3076
3077
3078



3079
3080
3081
3082
3083
3084
3085







-
-
-







  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
3451
3452
3453
3454
3455
3456
3457
3458
3459

3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3099
3100
3101
3102
3103
3104
3105


3106


3107
3108
3109
3110

3111
3112
3113
3114
3115
3116
3117







-
-
+
-
-




-







  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 */
  int addrCrTab;       /* Address of OP_CreateBtree opcode 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
3484
3485
3486
3487
3488
3489
3490

3491

3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511

3512
3513
3514

3515
3516
3517
3518
3519
3520
3521
3522
3523


3524
3525
3526
3527
3528
3529
3530
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







+

+




















+


-
+







-
-
+
+







  ** first field in the recursive region.
  ************************************************************************/

  Token sLastToken;       /* The last token parsed */
  ynVar nVar;               /* Number of '?' variables seen in the SQL so far */
  u8 iPkSortOrder;          /* ASC or DESC for INTEGER PRIMARY KEY */
  u8 explain;               /* True if the EXPLAIN flag is found on the query */
#if !(defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE))
  u8 eParseMode;            /* PARSE_MODE_XXX constant */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  int nVtabLock;            /* Number of virtual tables to lock */
#endif
  int nHeight;              /* Expression tree height of current sub-select */
#ifndef SQLITE_OMIT_EXPLAIN
  int addrExplain;          /* Address of current OP_Explain opcode */
#endif
  VList *pVList;            /* Mapping between variable names and numbers */
  Vdbe *pReprepare;         /* VM being reprepared (sqlite3Reprepare()) */
  const char *zTail;        /* All SQL text past the last semicolon parsed */
  Table *pNewTable;         /* A table being constructed by CREATE TABLE */
  Index *pNewIndex;         /* An index being constructed by CREATE INDEX.
                            ** Also used to hold redundant UNIQUE constraints
                            ** 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 */
  ParseCleanup *pCleanup;   /* List of cleanup operations to run after parse */
  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
#define PARSE_MODE_RENAME        2
#define PARSE_MODE_UNMAP         3
#define PARSE_MODE_RENAME_COLUMN 2
#define PARSE_MODE_RENAME_TABLE  3

/*
** Sizes and pointers of various parts of the Parse object.
*/
#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken)    /* Recursive part */
#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
3538
3539
3540
3541
3542
3543
3544
3545

3546
3547
3548
3549
3550
3551
3552
3185
3186
3187
3188
3189
3190
3191

3192
3193
3194
3195
3196
3197
3198
3199







-
+







#else
  #define IN_DECLARE_VTAB (pParse->eParseMode==PARSE_MODE_DECLARE_VTAB)
#endif

#if defined(SQLITE_OMIT_ALTERTABLE)
  #define IN_RENAME_OBJECT 0
#else
  #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME)
  #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN)
#endif

#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE)
  #define IN_SPECIAL_PARSE 0
#else
  #define IN_SPECIAL_PARSE (pParse->eParseMode!=PARSE_MODE_NORMAL)
#endif
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3234
3235
3236
3237
3238
3239
3240

3241
3242
3243
3244
3245
3246
3247







-







#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
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3255
3256
3257
3258
3259
3260
3261

3262
3263
3264
3265
3266
3267
3268







-







 * 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 */
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
3313
3314
3315
3316
3317
3318
3319

3320

3321
3322
3323
3324

3325

3326
3327
3328
3329
3330
3331
3332
3333
3334

3335
3336
3337
3338
3339


3340
3341






3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353







-
+
-




-

-
+








-
+
+
+

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







 *              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 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 */
  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 */
};

/*
** Information about a RETURNING clause
** 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 Returning {
  Parse *pParse;        /* The parse that includes the RETURNING clause */
struct DbFixer {
  Parse *pParse;      /* The parsing context.  Error messages written here */
  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 */
  Schema *pSchema;    /* Fix items to this schema */
  int bVarOnly;       /* Check for variable references only */
  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 {
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741

3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755





3756
3757
3758
3759
3760
3761
3762
3763
3373
3374
3375
3376
3377
3378
3379

3380
3381
3382
3383
3384

3385

3386
3387
3388
3389
3390
3391
3392
3393





3394
3395
3396
3397
3398

3399
3400
3401
3402
3403
3404
3405







-





-
+
-








-
-
-
-
-
+
+
+
+
+
-







typedef struct {
  sqlite3 *db;        /* The database being initialized */
  char **pzErrMsg;    /* Error message stored here */
  int iDb;            /* 0 for main database.  1 for TEMP, 2.. for ATTACHed */
  int rc;             /* Result code stored here */
  u32 mInitFlags;     /* Flags controlling error messages */
  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_AlterTable   0x0001  /* This is a reparse after ALTER TABLE */
#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 {
  int bMemstat;                     /* True to enable memory status */
  u8 bCoreMutex;                    /* True to enable core mutexing */
  u8 bFullMutex;                    /* True to enable full mutexing */
  u8 bOpenUri;                      /* True to interpret filenames as URIs */
  u8 bUseCis;                       /* Use covering indices for full-scans */
  u8 bSmallMalloc;                  /* Avoid large memory allocations if true */
  int bCoreMutex;                   /* True to enable core mutexing */
  int bFullMutex;                   /* True to enable full mutexing */
  int bOpenUri;                     /* True to interpret filenames as URIs */
  int bUseCis;                      /* Use covering indices for full-scans */
  int bSmallMalloc;                 /* Avoid large memory allocations if true */
  u8 bExtraSchemaChecks;            /* Verify type,name,tbl_name in schema */
  int mxStrlen;                     /* Maximum string length */
  int neverCorrupt;                 /* Database is always well-formed */
  int szLookaside;                  /* Default lookaside buffer size */
  int nLookaside;                   /* Default lookaside buffer count */
  int nStmtSpill;                   /* Stmt-journal spill-to-disk threshold */
  sqlite3_mem_methods m;            /* Low-level memory allocation interface */
  sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
3798
3799
3800
3801
3802
3803
3804

3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449

3450
3451
3452
3453
3454
3455
3456







+


-







#ifdef SQLITE_ENABLE_DESERIALIZE
  sqlite3_int64 mxMemdbSize;        /* Default max memdb size */
#endif
#ifndef SQLITE_UNTESTABLE
  int (*xTestCallback)(int);        /* Invoked by sqlite3FaultSim() */
#endif
  int bLocaltimeFault;              /* True to fail localtime() calls */
  int bInternalFunctions;           /* Internal SQL functions are visible */
  int iOnceResetThreshold;          /* When to reset OP_Once counters */
  u32 szSorterRef;                  /* Min size in bytes to use sorter-refs */
  unsigned int iPrngSeed;           /* Alternative fixed seed for the PRNG */
};

/*
** This macro is used inside of assert() statements to indicate that
** the assert is only valid on a well-formed database.  Instead of:
**
**     assert( X );
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
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909

3910
3911
3912
3913
3914
3915
3916
3917
3918
3919

3920
3921
3922
3923
3924



3925
3926

3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939

3940
3941
3942

3943
3944


3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960

3961
3962
3963
3964

3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000


4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022


4023
4024

4025
4026
4027
4028
4029
4030
4031
3472
3473
3474
3475
3476
3477
3478

3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494



3495
3496
3497















3498
3499
3500
3501
3502
3503
3504
3505
3506



3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519











3520










3521
3522
3523



3524
3525
3526


3527













3528



3529


3530
3531
3532

3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545

3546

3547
3548

3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559




3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574

3575
3576
3577
3578


3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589


3590
3591
3592
3593

3594
3595
3596



3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608







-
+















-
-
-



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









-
-
-













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


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

-













-
+
-


-
+










-
-
-
-















-




-
-
+
+









-
-




-



-
-
-
+
+


+







*/
struct Walker {
  Parse *pParse;                            /* Parser context.  */
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
  int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
  void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
  int walkerDepth;                          /* Number of subqueries */
  u16 eCode;                                /* A small processing code */
  u8 eCode;                                 /* A small processing code */
  union {                                   /* Extra data for callback */
    NameContext *pNC;                         /* Naming context */
    int n;                                    /* A counter */
    int iCur;                                 /* A cursor number */
    SrcList *pSrcList;                        /* FROM clause */
    struct SrcCount *pSrcCount;               /* Counting column references */
    struct CCurHint *pCCurHint;               /* Used by codeCursorHint() */
    int *aiCol;                               /* array of column indexes */
    struct IdxCover *pIdxCover;               /* Check for index coverage */
    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*);
int sqlite3ExprWalkNoop(Walker*, Expr*);
int sqlite3SelectWalkNoop(Walker*, Select*);
int sqlite3SelectWalkFail(Walker*, Select*);
int sqlite3WalkerDepthIncrease(Walker*,Select*);
void sqlite3WalkerDepthDecrease(Walker*,Select*);

#ifdef SQLITE_DEBUG
void sqlite3SelectWalkAssert2(Walker*, Select*);
#endif

/*
** Return code from the parse-tree walking primitives and their
** 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 */
};

** An instance of this structure represents a set of one or more CTEs
/*
** 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).
** (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 */
  Cte a[1];               /* For each CTE in the WITH clause.... */
  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 */
/*
** 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 */
    ExprList *pCols;                /* List of explicit column names, or NULL */
  int addrM9e;           /* Start of subroutine to compute materialization */
  int regRtn;            /* Return address register for addrM9e subroutine */
  int iCur;              /* Ephemeral table holding the materialization */
    Select *pSelect;                /* The definition of this CTE */
  LogEst nRowEst;        /* Estimated number of rows in the table */
  u8 eM10d;              /* The MATERIALIZED flag */
    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 {
  int iLevel;             /* Which level of the tree we are on */
  u8  bLine[100];         /* Draw vertical in column i if bLine[i] is true */
};
#endif /* SQLITE_DEBUG */

/*
** This object is used in various ways, most (but not all) related to window
** This object is used in various ways, all related to window functions
** functions.
**
**   (1) A single instance of this structure is attached to the
**       the Expr.y.pWin field for each window function in an expression tree.
**       the Expr.pWin field for each window function in an expression tree.
**       This object holds the information contained in the OVER clause,
**       plus additional fields used during code generation.
**
**   (2) All window functions in a single SELECT form a linked-list
**       attached to Select.pWin.  The Window.pFunc and Window.pExpr
**       fields point back to the expression that is the window function.
**
**   (3) The terms of the WINDOW clause of a SELECT are instances of this
**       object on a linked list attached to Select.pWinDefn.
**
**   (4) For an aggregate function with a FILTER clause, an instance
**       of this object is stored in Expr.y.pWin with eFrmType set to
**       TK_FILTER. In this case the only field used is Window.pFilter.
**
** The uses (1) and (2) are really the same Window object that just happens
** to be accessible in two different ways.  Use case (3) are separate objects.
*/
struct Window {
  char *zName;            /* Name of window (may be NULL) */
  char *zBase;            /* Name of base window for chaining (may be NULL) */
  ExprList *pPartition;   /* PARTITION BY clause */
  ExprList *pOrderBy;     /* ORDER BY clause */
  u8 eFrmType;            /* TK_RANGE, TK_GROUPS, TK_ROWS, or 0 */
  u8 eStart;              /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
  u8 eEnd;                /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
  u8 bImplicitFrame;      /* True if frame was implicitly specified */
  u8 eExclude;            /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
  Expr *pStart;           /* Expression for "<expr> PRECEDING" */
  Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
  Window **ppThis;        /* Pointer to this object in Select.pWin list */
  Window *pNextWin;       /* Next window function belonging to this SELECT */
  Expr *pFilter;          /* The FILTER expression */
  FuncDef *pFunc;         /* The function */
  int iEphCsr;            /* Partition buffer or Peer buffer */
  int regAccum;           /* Accumulator */
  int regResult;          /* Interim result */
  int regAccum;
  int regResult;
  int csrApp;             /* Function cursor (used by min/max) */
  int regApp;             /* Function register (also used by min/max) */
  int regPart;            /* Array of registers for PARTITION BY values */
  Expr *pOwner;           /* Expression object this window is attached to */
  int nBufferCol;         /* Number of columns in buffer table */
  int iArgCol;            /* Offset of first argument for this function */
  int regOne;             /* Register containing constant value 1 */
  int regStartRowid;
  int regEndRowid;
  u8 bExprArgs;           /* Defer evaluation of window function arguments
                          ** due to the SQLITE_SUBTYPE flag */
};

#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3WindowDelete(sqlite3*, Window*);
void sqlite3WindowUnlinkFromSelect(Window*);
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
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*);
int sqlite3WindowCompare(Parse*, Window*, Window*);
void sqlite3WindowCodeInit(Parse*, Window*);
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
4057
4058
4059
4060
4061
4062
4063

4064
4065

4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647





3648
3649
3650
3651
3652
3653
3654







+


+



-
-
-
-
-







int sqlite3CantopenError(int);
#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
#ifdef SQLITE_DEBUG
  int sqlite3NomemError(int);
  int sqlite3IoerrnomemError(int);
  int sqlite3CorruptPgnoError(int,Pgno);
# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
#else
# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO)
  int sqlite3CorruptPgnoError(int,Pgno);
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
#else
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__)
#endif

/*
** FTS3 and FTS4 both require virtual table support
*/
#if defined(SQLITE_OMIT_VIRTUALTABLE)
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
3790
3791
3792
3793
3794
3795
3796



3797
3798

3799
3800
3801
3802
3803
3804
3805







-
-
-


-







#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
void sqlite3MutexWarnOnContention(sqlite3_mutex*);
#else
# define sqlite3MutexWarnOnContention(x)
#endif

#ifndef SQLITE_OMIT_FLOATING_POINT
# define EXP754 (((u64)0x7ff)<<52)
# define MAN754 ((((u64)1)<<52)-1)
# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
  int sqlite3IsNaN(double);
#else
# define IsNaN(X)         0
# define sqlite3IsNaN(X)  0
#endif

/*
** An instance of the following structure holds information about SQL
** functions arguments that are the parameters to the printf() function.
*/
4280
4281
4282
4283
4284
4285
4286
4287

4288
4289
4290
4291
4292
4293
4294
4295
4296
4297

4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318



4319
4320

4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337

4338
4339
4340
4341
4342
4343
4344



4345


4346
4347
4348
4349
4350
4351
4352
3850
3851
3852
3853
3854
3855
3856

3857

3858

3859
3860


3861
3862

3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881



3882
3883
3884
3885

3886







3887
3888
3889
3890
3891
3892
3893
3894
3895

3896
3897
3898

3899

3900
3901
3902
3903
3904

3905
3906
3907
3908
3909
3910
3911
3912
3913







-
+
-

-


-
-


-
+


















-
-
-
+
+
+

-
+
-
-
-
-
-
-
-









-
+


-

-


+
+
+
-
+
+







int sqlite3NoTempsInRange(Parse*,int,int);
#endif
Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
Expr *sqlite3Expr(sqlite3*,int,const char*);
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
Expr *sqlite3ExprSimplifiedAndOr(Expr*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
void sqlite3ExprDeferredDelete(Parse*, Expr*);
void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
void sqlite3ExprListSetSortOrder(ExprList*,int,int);
void sqlite3ExprListSetSortOrder(ExprList*,int);
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
void sqlite3ExprListDelete(sqlite3*, ExprList*);
u32 sqlite3ExprListFlags(const ExprList*);
int sqlite3IndexHasDuplicateRootPage(Index*);
int sqlite3Init(sqlite3*, char**);
int sqlite3InitCallback(void*, int, char**, char**);
int sqlite3InitOne(sqlite3*, int, char**, u32);
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
#ifndef SQLITE_OMIT_VIRTUALTABLE
Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
#endif
void sqlite3ResetAllSchemasOfConnection(sqlite3*);
void sqlite3ResetOneSchema(sqlite3*,int);
void sqlite3CollapseDatabaseArray(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*);
void sqlite3DeleteColumnNames(sqlite3*,Table*);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
void sqlite3OpenSchemaTable(Parse *, int);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*);
Table *sqlite3ResultSetOfSelect(Parse*,Select*);
void sqlite3OpenMasterTable(Parse *, int);
Index *sqlite3PrimaryKeyIndex(Table*);
i16 sqlite3TableColumnToIndex(Index*, i16);
i16 sqlite3ColumnOfIndex(Index*, i16);
#ifdef SQLITE_OMIT_GENERATED_COLUMNS
# define sqlite3TableColumnToStorage(T,X) (X)  /* No-op pass-through */
# define sqlite3StorageColumnToTable(T,X) (X)  /* No-op pass-through */
#else
  i16 sqlite3TableColumnToStorage(Table*, i16);
  i16 sqlite3StorageColumnToTable(Table*, i16);
#endif
void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
#if SQLITE_ENABLE_HIDDEN_COLUMNS
  void sqlite3ColumnPropertiesFromName(Table*, Column*);
#else
# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
#endif
void sqlite3AddColumn(Parse*,Token*,Token*);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);
void sqlite3AddCheckConstraint(Parse*, Expr*);
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 **);
#ifdef SQLITE_HAS_CODEC
  int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*);
#else
#define sqlite3CodecQueryParameters(A,B,C) 0
# define sqlite3CodecQueryParameters(A,B,C) 0
#endif
Btree *sqlite3DbNameToBtree(sqlite3*,const char*);

#ifdef SQLITE_UNTESTABLE
# define sqlite3FaultSim(X) SQLITE_OK
#else
  int sqlite3FaultSim(int);
#endif
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408

4409
4410
4411
4412
4413
4414
4415
3949
3950
3951
3952
3953
3954
3955



3956
3957
3958
3959

3960
3961
3962
3963
3964

3965
3966
3967
3968
3969
3970
3971
3972







-
-
-




-





-
+







  void sqlite3AutoincrementBegin(Parse *pParse);
  void sqlite3AutoincrementEnd(Parse *pParse);
#else
# define sqlite3AutoincrementBegin(X)
# define sqlite3AutoincrementEnd(X)
#endif
void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*);
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  void sqlite3ComputeGeneratedColumns(Parse*, int, Table*);
#endif
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*);
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 *);
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);
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455

4456
4457

4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470

4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
3986
3987
3988
3989
3990
3991
3992

3993
3994
3995
3996
3997
3998
3999

4000
4001
4002
4003
4004



4005
4006

4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022

4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034

4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051

4052
4053
4054
4055
4056
4057
4058







-







-





-
-
-


-
+


+












-
+











-

















-







                   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 */
int sqlite3WhereUsesDeferredSeek(WhereInfo*);
void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
void sqlite3ExprCodeMove(Parse*, int, int, int);
void sqlite3ExprCode(Parse*, Expr*, int);
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int);
#endif
void sqlite3ExprCodeCopy(Parse*, Expr*, int);
void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int);
int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
int sqlite3ExprCodeTarget(Parse*, Expr*, int);
void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
#define SQLITE_ECEL_DUP      0x01  /* Deep, not shallow copies */
#define SQLITE_ECEL_FACTOR   0x02  /* Factor out constant terms */
#define SQLITE_ECEL_REF      0x04  /* Use ExprList.u.x.iOrderByCol */
#define SQLITE_ECEL_OMITREF  0x08  /* Omit if ExprList.u.x.iOrderByCol */
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 *);
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);
int sqlite3ExprCompareSkip(Expr*, Expr*, int);
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
int sqlite3ExprImpliesNonNullRow(Expr*,int);
void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
Vdbe *sqlite3GetVdbe(Parse*);
#ifndef SQLITE_UNTESTABLE
void sqlite3PrngSaveState(void);
void sqlite3PrngRestoreState(void);
#endif
void sqlite3RollbackAll(sqlite3*,int);
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
void sqlite3BeginTransaction(Parse*, int);
void sqlite3EndTransaction(Parse*,int);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
u32 sqlite3IsTrueOrFalse(const char*);
int sqlite3ExprIdToTrueFalse(Expr*);
int sqlite3ExprTruthValue(const Expr*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
int sqlite3ExprIsTableConstant(Expr*,int);
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
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
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
4190







-
-
+
+





-













-



-
-














-






+

-
-


-












-
+







  void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
  void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
  TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*,
                                        const char*,const char*);
  TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*,
                                        Select*,u8,Upsert*,
                                        const char*,const char*);
  TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,SrcList*,ExprList*,
                                        Expr*, u8, const char*,const char*);
  TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8,
                                        const char*,const char*);
  TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*,
                                        const char*,const char*);
  void sqlite3DeleteTrigger(sqlite3*, Trigger*);
  void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
  u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
  SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*);
# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
# define sqlite3IsToplevel(p) ((p)->pToplevel==0)
#else
# define sqlite3TriggersExist(B,C,D,E,F) 0
# define sqlite3DeleteTrigger(A,B)
# define sqlite3DropTriggerPtr(A,B)
# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I)
# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F)
# define sqlite3TriggerList(X, Y) 0
# 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*);
  void sqlite3AuthContextPop(AuthContext*);
  int sqlite3AuthReadCol(Parse*, const char *, const char *, int);
#else
# define sqlite3AuthRead(a,b,c,d)
# define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a)  ((void)(a))
#endif
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*);
#ifndef SQLITE_OMIT_UTF16
int sqlite3Utf16ByteLen(const void *pData, int nChar);
#endif
int sqlite3Utf8CharLen(const char *pData, int nByte);
u32 sqlite3Utf8Read(const u8**);
LogEst sqlite3LogEst(u64);
LogEst sqlite3LogEstAdd(LogEst,LogEst);
#ifndef SQLITE_OMIT_VIRTUALTABLE
LogEst sqlite3LogEstFromDouble(double);
#endif
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
    defined(SQLITE_ENABLE_STAT4) || \
    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
u64 sqlite3LogEstToInt(LogEst);
#endif
VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
const char *sqlite3VListNumToName(VList*,int);
int sqlite3VListNameToNum(VList*,const char*,int);

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
4697
4698
4699
4700
4701
4702
4703
4704
4705



4706
4707
4708
4709
4710
4711
4712

4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744

4745
4746
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
4201
4202
4203
4204
4205
4206
4207


4208
4209
4210
4211
4212
4213
4214
4215
4216


4217
4218
4219

4220
4221
4222
4223
4224

4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242




4243
4244
4245
4246
4247
4248

4249
4250

4251
4252
4253
4254
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

4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301

4302

4303







4304
4305
4306
4307
4308
4309
4310
4311

4312
4313
4314
4315
4316
4317
4318

4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334


4335
4336
4337
4338
4339
4340
4341







-
-









-
-
+
+

-
+




-


















-
-
-
-
+
+
+



-


-
+


















-
-
-











+





-
+



-
+










-

-
+
-
-
-
-
-
-
-








-







-
+















-
-







/*
** The common case is for a varint to be a single byte.  They following
** macros handle the common case without a procedure call, but then call
** the procedure for larger varints.
*/
#define getVarint32(A,B)  \
  (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B)))
#define getVarint32NR(A,B) \
  B=(u32)*(A);if(B>=0x80)sqlite3GetVarint32((A),(u32*)&(B))
#define putVarint32(A,B)  \
  (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\
  sqlite3PutVarint((A),(B)))
#define getVarint    sqlite3GetVarint
#define putVarint    sqlite3PutVarint


const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
void sqlite3TableAffinity(Vdbe*, Table*, int);
char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3TableColumnAffinity(Table*,int);
char sqlite3ExprAffinity(const Expr *pExpr);
char sqlite3ExprAffinity(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);
#endif

#ifdef SQLITE_ENABLE_DESERIALIZE
int sqlite3MemdbInit(void);
#endif

const char *sqlite3ErrStr(int);
int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
int sqlite3IsBinary(const CollSeq*);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
void sqlite3SetTextEncoding(sqlite3 *db, u8);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr);
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr);
int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
Expr *sqlite3ExprSkipCollateAndLikely(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3WritableSchema(sqlite3*);
int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
int sqlite3AddInt64(i64*,i64);
int sqlite3SubInt64(i64*,i64);
int sqlite3MulInt64(i64*,i64);
int sqlite3AbsInt32(int);
#ifdef SQLITE_ENABLE_8_3_NAMES
void sqlite3FileSuffix3(const char*, char*);
#else
# define sqlite3FileSuffix3(X,Y)
#endif
u8 sqlite3GetBoolean(const char *z,u8);

const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
                        void(*)(void*));
void sqlite3ValueSetNull(sqlite3_value*);
void sqlite3ValueFree(sqlite3_value*);
#ifndef SQLITE_UNTESTABLE
void sqlite3ResultIntReal(sqlite3_context*);
#endif
sqlite3_value *sqlite3ValueNew(sqlite3 *);
#ifndef SQLITE_OMIT_UTF16
char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
#endif
int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
extern const unsigned char sqlite3OpcodeProperty[];
extern const char sqlite3StrBINARY[];
extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char sqlite3CtypeMap[];
extern const Token sqlite3IntTokens[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern FuncDefHash sqlite3BuiltinFunctions;
#ifndef SQLITE_OMIT_WSD
extern int sqlite3PendingByte;
#endif
#endif /* SQLITE_AMALGAMATION */
#endif
#ifdef VDBE_PROFILE
extern sqlite3_uint64 sqlite3NProfileCnt;
#endif
void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno);
void sqlite3RootPageMoved(sqlite3*, int, int, int);
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(
int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
  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*);
int sqlite3InvokeBusyHandler(BusyHandler*);
int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
int sqlite3FindDb(sqlite3*, Token*);
int sqlite3FindDbName(sqlite3 *, const char *);
int sqlite3AnalysisLoad(sqlite3*,int iDB);
void sqlite3DeleteIndexSamples(sqlite3*,Index*);
void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
void sqlite3SchemaClear(void *);
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 **),
  void (*)(sqlite3_context*,int,sqlite3_value **), 
4834
4835
4836
4837
4838
4839
4840
4841


4842
4843
4844
4845
4846
4847
4848
4360
4361
4362
4363
4364
4365
4366

4367
4368
4369
4370
4371
4372
4373
4374
4375







-
+
+








#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3ExprCheckIN(Parse*, Expr*);
#else
# define sqlite3ExprCheckIN(x,y) SQLITE_OK
#endif

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
void sqlite3AnalyzeFunctions(void);
int sqlite3Stat4ProbeSetValue(
    Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*);
int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
void sqlite3Stat4ProbeFree(UnpackedRecord*);
int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**);
char sqlite3IndexColumnAffinity(sqlite3*, Index*, int);
#endif
4864
4865
4866
4867
4868
4869
4870
4871

4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945

4946
4947
4948
4949
4950
4951
4952
4953
4954
4955

4956
4957
4958
4959
4960

4961
4962

4963
4964
4965
4966

4967
4968
4969
4970
4971
4972
4973
4974

4975
4976

4977
4978
4979
4980
4981
4982
4983
4984
4985
4391
4392
4393
4394
4395
4396
4397

4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414

4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425

4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438








4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454

4455
4456
4457
4458
4459


4460
4461
4462
4463
4464
4465
4466
4467



4468
4469
4470
4471


4472


4473

4474
4475

4476
4477
4478
4479
4480


4481

4482
4483

4484


4485
4486
4487
4488
4489
4490
4491







-
+
















-











-













-
-
-
-
-
-
-
-
















-





-
-
+







-
-
-
+



-
-
+
-
-
+
-


-
+




-
-

-
+

-
+
-
-







#ifndef SQLITE_OMIT_LOAD_EXTENSION
  void sqlite3CloseExtensions(sqlite3*);
#else
# define sqlite3CloseExtensions(X)
#endif

#ifndef SQLITE_OMIT_SHARED_CACHE
  void sqlite3TableLock(Parse *, int, Pgno, u8, const char *);
  void sqlite3TableLock(Parse *, int, int, u8, const char *);
#else
  #define sqlite3TableLock(v,w,x,y,z)
#endif

#ifdef SQLITE_TEST
  int sqlite3Utf8To8(unsigned char*);
#endif

#ifdef SQLITE_OMIT_VIRTUALTABLE
#  define sqlite3VtabClear(Y)
#  define sqlite3VtabSync(X,Y) SQLITE_OK
#  define sqlite3VtabRollback(X)
#  define sqlite3VtabCommit(X)
#  define sqlite3VtabInSync(db) 0
#  define sqlite3VtabLock(X)
#  define sqlite3VtabUnlock(X)
#  define sqlite3VtabModuleUnref(D,X)
#  define sqlite3VtabUnlockList(X)
#  define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
#  define sqlite3GetVTable(X,Y)  ((VTable*)0)
#else
   void sqlite3VtabClear(sqlite3 *db, Table*);
   void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
   int sqlite3VtabSync(sqlite3 *db, Vdbe*);
   int sqlite3VtabRollback(sqlite3 *db);
   int sqlite3VtabCommit(sqlite3 *db);
   void sqlite3VtabLock(VTable *);
   void sqlite3VtabUnlock(VTable *);
   void sqlite3VtabModuleUnref(sqlite3*,Module*);
   void sqlite3VtabUnlockList(sqlite3*);
   int sqlite3VtabSavepoint(sqlite3 *, int, int);
   void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
   VTable *sqlite3GetVTable(sqlite3*, Table*);
   Module *sqlite3VtabCreateModule(
     sqlite3*,
     const char*,
     const sqlite3_module*,
     void*,
     void(*)(void*)
   );
#  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
int sqlite3ReadOnlyShadowTables(sqlite3 *db);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
  int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
#else
# define sqlite3ShadowTableName(A,B) 0
# define sqlite3IsShadowTableOf(A,B,C) 0
#endif
int sqlite3VtabEponymousTableInit(Parse*,Module*);
void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
void sqlite3VtabMakeWritable(Parse*,Table*);
void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
void sqlite3VtabFinishParse(Parse*, Token*);
void sqlite3VtabArgInit(Parse*);
void sqlite3VtabArgExtend(Parse*, Token*);
int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
int sqlite3VtabCallConnect(Parse*, Table*);
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
int sqlite3VtabBegin(sqlite3 *, 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*);
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, 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*);
  With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*);
  void sqlite3WithDelete(sqlite3*,With*);
  void sqlite3WithPush(Parse*, With*, u8);
#else
# define sqlite3CteNew(P,T,E,S)   ((void*)0)
# define sqlite3CteDelete(D,C)
#define sqlite3WithPush(x,y,z)
# define sqlite3CteWithAdd(P,W,C) ((void*)0)
# define sqlite3WithDelete(x,y)
#define sqlite3WithDelete(x,y)
# define sqlite3WithPush(x,y,z)
#endif
#ifndef SQLITE_OMIT_UPSERT
  Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,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);
  Upsert *sqlite3UpsertOfIndex(Upsert*,Index*);
  int sqlite3UpsertNextIsIPK(Upsert*);
#else
#define sqlite3UpsertNew(u,v,w,x,y,z) ((Upsert*)0)
#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0)
#define sqlite3UpsertDelete(x,y)
#define sqlite3UpsertDup(x,y)         ((Upsert*)0)
#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/sqliteLimit.h.

56
57
58
59
60
61
62
63





64
65
66
67
68
69
70
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74







-
+
+
+
+
+







# define SQLITE_MAX_SQL_LENGTH 1000000000
#endif

/*
** The maximum depth of an expression tree. This is limited to 
** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might 
** want to place more severe limits on the complexity of an 
** expression. A value of 0 means that there is no limit.
** expression.
**
** A value of 0 used to mean that the limit was not enforced.
** But that is no longer true.  The limit is now strictly enforced
** at all times.
*/
#ifndef SQLITE_MAX_EXPR_DEPTH
# define SQLITE_MAX_EXPR_DEPTH 1000
#endif

/*
** The maximum number of terms in a compound SELECT statement.
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
127
128
129
130
131
132
133



134
135

136
137
138
139
140
141
142
143







-
-
-


-
+







#ifndef SQLITE_MAX_ATTACHED
# define SQLITE_MAX_ATTACHED 10
#endif


/*
** The maximum value of a ?nnn wildcard that the parser will accept.
** If the value exceeds 32767 then extra space is required for the Expr
** structure.  But otherwise, we believe that the number can be as large
** as a signed 32-bit integer can hold.
*/
#ifndef SQLITE_MAX_VARIABLE_NUMBER
# define SQLITE_MAX_VARIABLE_NUMBER 32766
# define SQLITE_MAX_VARIABLE_NUMBER 999
#endif

/* Maximum page size.  The upper bound on this value is 65536.  This a limit
** imposed by the use of 16-bit offsets within each page.
**
** Earlier versions of SQLite allowed the user to change this value at
** compile time. This is no longer permitted, on the grounds that it creates

Changes to src/status.c.

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
184
185
186
187
188
189
190




191
192
193
194
195
196
197







-
-
-
-








/*
** Count the number of slots of lookaside memory that are outstanding
*/
int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
  u32 nInit = countLookasideSlots(db->lookaside.pInit);
  u32 nFree = countLookasideSlots(db->lookaside.pFree);
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
  nInit += countLookasideSlots(db->lookaside.pSmallInit);
  nFree += countLookasideSlots(db->lookaside.pSmallFree);
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
  if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit;
  return db->lookaside.nSlot - (nInit+nFree);
}

/*
** Query status information for a single database connection
*/
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
216
217
218
219
220
221
222









223
224
225
226
227
228
229







-
-
-
-
-
-
-
-
-







        LookasideSlot *p = db->lookaside.pFree;
        if( p ){
          while( p->pNext ) p = p->pNext;
          p->pNext = db->lookaside.pInit;
          db->lookaside.pInit = db->lookaside.pFree;
          db->lookaside.pFree = 0;
        }
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
        p = db->lookaside.pSmallFree;
        if( p ){
          while( p->pNext ) p = p->pNext;
          p->pNext = db->lookaside.pSmallInit;
          db->lookaside.pSmallInit = db->lookaside.pSmallFree;
          db->lookaside.pSmallFree = 0;
        }
#endif
      }
      break;
    }

    case SQLITE_DBSTATUS_LOOKASIDE_HIT:
    case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
    case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349







-
+







    /*
    ** Set *pCurrent to the total cache hits or misses encountered by all
    ** pagers the database handle is connected to. *pHighwater is always set 
    ** to zero.
    */
    case SQLITE_DBSTATUS_CACHE_SPILL:
      op = SQLITE_DBSTATUS_CACHE_WRITE+1;
      /* no break */ deliberate_fall_through
      /* Fall through into the next case */
    case SQLITE_DBSTATUS_CACHE_HIT:
    case SQLITE_DBSTATUS_CACHE_MISS:
    case SQLITE_DBSTATUS_CACHE_WRITE:{
      int i;
      int nRet = 0;
      assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
      assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );

Changes to src/table.c.

52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66







-
+







    need = nCol*2;
  }else{
    need = nCol;
  }
  if( p->nData + need > p->nAlloc ){
    char **azNew;
    p->nAlloc = p->nAlloc*2 + need;
    azNew = sqlite3Realloc( p->azResult, sizeof(char*)*p->nAlloc );
    azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc );
    if( azNew==0 ) goto malloc_failed;
    p->azResult = azNew;
  }

  /* If this is the first row, then generate an extra row containing
  ** the names of all columns.
  */
161
162
163
164
165
166
167
168

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

168
169
170
171
172
173
174
175







-
+







  sqlite3_free(res.zErrMsg);
  if( rc!=SQLITE_OK ){
    sqlite3_free_table(&res.azResult[1]);
    return rc;
  }
  if( res.nAlloc>res.nData ){
    char **azNew;
    azNew = sqlite3Realloc( res.azResult, sizeof(char*)*res.nData );
    azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
    if( azNew==0 ){
      sqlite3_free_table(&res.azResult[1]);
      db->errCode = SQLITE_NOMEM;
      return SQLITE_NOMEM_BKPT;
    }
    res.azResult = azNew;
  }

Changes to src/tclsqlite.c.

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







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





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







  SqliteDb *pDb = (SqliteDb*)cd;
  int choice;
  int rc = TCL_OK;
  static const char *DB_strs[] = {
    "authorizer",             "backup",                "bind_fallback",
    "busy",                   "cache",                 "changes",
    "close",                  "collate",               "collation_needed",
    "commit_hook",            "complete",              "config",
    "copy",                   "deserialize",           "enable_load_extension",
    "errorcode",              "eval",                  "exists",
    "function",               "incrblob",              "interrupt",
    "last_insert_rowid",      "nullvalue",             "onecolumn",
    "preupdate",              "profile",               "progress",
    "rekey",                  "restore",               "rollback_hook",
    "serialize",              "status",                "timeout",
    "total_changes",          "trace",                 "trace_v2",
    "transaction",            "unlock_notify",         "update_hook",
    "version",                "wal_hook",              0
    "commit_hook",            "complete",              "copy",
    "deserialize",            "enable_load_extension", "errorcode",
    "eval",                   "exists",                "function",
    "incrblob",               "interrupt",             "last_insert_rowid",
    "nullvalue",              "onecolumn",             "preupdate",
    "profile",                "progress",              "rekey",
    "restore",                "rollback_hook",         "serialize",
    "status",                 "timeout",               "total_changes",
    "trace",                  "trace_v2",              "transaction",
    "unlock_notify",          "update_hook",           "version",
    "wal_hook",               0                        
  };
  enum DB_enum {
    DB_AUTHORIZER,            DB_BACKUP,               DB_BIND_FALLBACK,
    DB_BUSY,                  DB_CACHE,                DB_CHANGES,
    DB_CLOSE,                 DB_COLLATE,              DB_COLLATION_NEEDED,
    DB_COMMIT_HOOK,           DB_COMPLETE,             DB_CONFIG,
    DB_COPY,                  DB_DESERIALIZE,          DB_ENABLE_LOAD_EXTENSION,
    DB_ERRORCODE,             DB_EVAL,                 DB_EXISTS,
    DB_FUNCTION,              DB_INCRBLOB,             DB_INTERRUPT,
    DB_LAST_INSERT_ROWID,     DB_NULLVALUE,            DB_ONECOLUMN,
    DB_PREUPDATE,             DB_PROFILE,              DB_PROGRESS,
    DB_REKEY,                 DB_RESTORE,              DB_ROLLBACK_HOOK,
    DB_SERIALIZE,             DB_STATUS,               DB_TIMEOUT,
    DB_TOTAL_CHANGES,         DB_TRACE,                DB_TRACE_V2,
    DB_TRANSACTION,           DB_UNLOCK_NOTIFY,        DB_UPDATE_HOOK,
    DB_VERSION,               DB_WAL_HOOK             
    DB_COMMIT_HOOK,           DB_COMPLETE,             DB_COPY,
    DB_DESERIALIZE,           DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE,
    DB_EVAL,                  DB_EXISTS,               DB_FUNCTION,
    DB_INCRBLOB,              DB_INTERRUPT,            DB_LAST_INSERT_ROWID,
    DB_NULLVALUE,             DB_ONECOLUMN,            DB_PREUPDATE,
    DB_PROFILE,               DB_PROGRESS,             DB_REKEY,
    DB_RESTORE,               DB_ROLLBACK_HOOK,        DB_SERIALIZE,
    DB_STATUS,                DB_TIMEOUT,              DB_TOTAL_CHANGES,
    DB_TRACE,                 DB_TRACE_V2,             DB_TRANSACTION,
    DB_UNLOCK_NOTIFY,         DB_UPDATE_HOOK,          DB_VERSION,
    DB_WAL_HOOK             
  };
  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
    return TCL_ERROR;
  }
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2327
2328
2329
2330
2331
2332
2333






































































2334
2335
2336
2337
2338
2339
2340







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







    isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetBooleanObj(pResult, isComplete);
#endif
    break;
  }

  /*    $db config ?OPTION? ?BOOLEAN?
  **
  ** Configure the database connection using the sqlite3_db_config()
  ** interface.
  */
  case DB_CONFIG: {
    static const struct DbConfigChoices {
      const char *zName;
      int op;
    } aDbConfig[] = {
        { "defensive",          SQLITE_DBCONFIG_DEFENSIVE             },
        { "dqs_ddl",            SQLITE_DBCONFIG_DQS_DDL               },
        { "dqs_dml",            SQLITE_DBCONFIG_DQS_DML               },
        { "enable_fkey",        SQLITE_DBCONFIG_ENABLE_FKEY           },
        { "enable_qpsg",        SQLITE_DBCONFIG_ENABLE_QPSG           },
        { "enable_trigger",     SQLITE_DBCONFIG_ENABLE_TRIGGER        },
        { "enable_view",        SQLITE_DBCONFIG_ENABLE_VIEW           },
        { "fts3_tokenizer",     SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
        { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    },
        { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    },
        { "load_extension",     SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
        { "no_ckpt_on_close",   SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      },
        { "reset_database",     SQLITE_DBCONFIG_RESET_DATABASE        },
        { "trigger_eqp",        SQLITE_DBCONFIG_TRIGGER_EQP           },
        { "trusted_schema",     SQLITE_DBCONFIG_TRUSTED_SCHEMA        },
        { "writable_schema",    SQLITE_DBCONFIG_WRITABLE_SCHEMA       },
    };
    Tcl_Obj *pResult;
    int ii;
    if( objc>4 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?");
      return TCL_ERROR;
    }
    if( objc==2 ){
      /* With no arguments, list all configuration options and with the
      ** current value */
      pResult = Tcl_NewListObj(0,0);
      for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
        int v = 0;
        sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v);
        Tcl_ListObjAppendElement(interp, pResult,
           Tcl_NewStringObj(aDbConfig[ii].zName,-1));
        Tcl_ListObjAppendElement(interp, pResult,
           Tcl_NewIntObj(v));
      }
    }else{
      const char *zOpt = Tcl_GetString(objv[2]);
      int onoff = -1;
      int v = 0;
      if( zOpt[0]=='-' ) zOpt++;
      for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
        if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break;
      }
      if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){
        Tcl_AppendResult(interp, "unknown config option: \"", zOpt,
                                "\"", (void*)0);
        return TCL_ERROR;
      }
      if( objc==4 ){
        if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){
          return TCL_ERROR;
        }
      }
      sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v);
      pResult = Tcl_NewIntObj(v);
    }
    Tcl_SetObjResult(interp, pResult);
    break;
  }

  /*    $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
  **
  ** Copy data into table from filename, optionally using SEPARATOR
  ** as column separators.  If a column contains a null string, or the
  ** value of NULLINDICATOR, a NULL is inserted for the column.
  ** conflict-algorithm is one of the sqlite conflict algorithms:
  **    rollback, abort, fail, ignore, replace
2807
2808
2809
2810
2811
2812
2813
2814

2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2737
2738
2739
2740
2741
2742
2743

2744
2745
2746
2747







2748
2749
2750
2751
2752
2753
2754







-
+



-
-
-
-
-
-
-







      cd2[1] = (void *)pScript;
      rc = DbEvalNextCmd(cd2, interp, TCL_OK);
    }
    break;
  }

  /*
  **     $db function NAME [OPTIONS] SCRIPT
  **     $db function NAME [-argcount N] [-deterministic] SCRIPT
  **
  ** Create a new SQL function called NAME.  Whenever that function is
  ** called, invoke SCRIPT to evaluate the function.
  **
  ** Options:
  **         --argcount N           Function has exactly N arguments
  **         --deterministic        The function is pure
  **         --directonly           Prohibit use inside triggers and views
  **         --innocuous            Has no side effects or information leaks
  **         --returntype TYPE      Specify the return type of the function
  */
  case DB_FUNCTION: {
    int flags = SQLITE_UTF8;
    SqlFunc *pFunc;
    Tcl_Obj *pScript;
    char *zName;
    int nArg = -1;
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878

2879
2880
2881
2882
2883
2884
2885
2886
2773
2774
2775
2776
2777
2778
2779






2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794

2795

2796
2797
2798
2799
2800
2801
2802







-
-
-
-
-
-















-
+
-







          return TCL_ERROR;
        }
        i++;
      }else
      if( n>1 && strncmp(z, "-deterministic",n)==0 ){
        flags |= SQLITE_DETERMINISTIC;
      }else
      if( n>1 && strncmp(z, "-directonly",n)==0 ){
        flags |= SQLITE_DIRECTONLY;
      }else
      if( n>1 && strncmp(z, "-innocuous",n)==0 ){
        flags |= SQLITE_INNOCUOUS;
      }else
      if( n>1 && strncmp(z, "-returntype", n)==0 ){
        const char *azType[] = {"integer", "real", "text", "blob", "any", 0};
        assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 );
        assert( SQLITE_BLOB==4 && SQLITE_NULL==5 );
        if( i==(objc-2) ){
          Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
          return TCL_ERROR;
        }
        i++;
        if( Tcl_GetIndexFromObj(interp, objv[i], azType, "type", 0, &eType) ){
          return TCL_ERROR;
        }
        eType++;
      }else{
        Tcl_AppendResult(interp, "bad option \"", z,
            "\": must be -argcount, -deterministic, -directonly,"
            "\": must be -argcount, -deterministic or -returntype", (char*)0
            " -innocuous, or -returntype", (char*)0
        );
        return TCL_ERROR;
      }
    }

    pScript = objv[objc-1];
    zName = Tcl_GetStringFromObj(objv[2], 0);
3090
3091
3092
3093
3094
3095
3096




3097
3098
3099
3100








3101
3102
3103
3104
3105
3106
3107
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035







+
+
+
+




+
+
+
+
+
+
+
+








  /*
  **     $db rekey KEY
  **
  ** Change the encryption key on the currently open database.
  */
  case DB_REKEY: {
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
    int nKey;
    void *pKey;
#endif
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "KEY");
      return TCL_ERROR;
    }
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
    rc = sqlite3_rekey(pDb->db, pKey, nKey);
    if( rc ){
      Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
      rc = TCL_ERROR;
    }
#endif
    break;
  }

  /*    $db restore ?DATABASE? FILENAME
  **
  ** Open a database file named FILENAME.  Transfer the content
  ** of FILENAME into the local database DATABASE (default: "main").
3660
3661
3662
3663
3664
3665
3666
3667
3668



3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
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







-

+
+
+







-







*/
static int sqliteCmdUsage(
  Tcl_Interp *interp,
  Tcl_Obj *const*objv
){
  Tcl_WrongNumArgs(interp, 1, objv,
    "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
    " ?-nofollow BOOLEAN?"
    " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
    " ?-key CODECKEY?"
#endif
  );
  return TCL_ERROR;
}

/*
**   sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
**                           ?-create BOOLEAN? ?-nomutex BOOLEAN?
**                           ?-nofollow BOOLEAN?
**
** This is the main Tcl command.  When the "sqlite" Tcl command is
** invoked, this routine runs to process that command.
**
** The first argument, DBNAME, is an arbitrary name for a new
** database connection.  This command creates a new command named
** DBNAME that is used to control that connection.  The database
3695
3696
3697
3698
3699
3700
3701
3702
3703




3704
3705
3706
3707
3708
3709
3710
3624
3625
3626
3627
3628
3629
3630

3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642







-

+
+
+
+







  SqliteDb *p;
  const char *zArg;
  char *zErrMsg;
  int i;
  const char *zFile = 0;
  const char *zVfs = 0;
  int flags;
  int bTranslateFileName = 1;
  Tcl_DString translatedFilename;
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
  void *pKey = 0;
  int nKey = 0;
#endif
  int rc;

  /* In normal use, each TCL interpreter runs in a single thread.  So
  ** by default, we can turn off mutexing on SQLite database connections.
  ** However, for testing purposes it is useful to have mutexes turned
  ** on.  So, by default, mutexes default off.  But if compiled with
  ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
3723
3724
3725
3726
3727
3728
3729



3730

3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744


3745

3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
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







+
+
+

+














+
+
-
+




















-
-
-
-
-
-
-
-







      return TCL_OK;
    }
    if( strcmp(zArg,"-sourceid")==0 ){
      Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0);
      return TCL_OK;
    }
    if( strcmp(zArg,"-has-codec")==0 ){
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
      Tcl_AppendResult(interp,"1",(char*)0);
#else
      Tcl_AppendResult(interp,"0",(char*)0);
#endif
      return TCL_OK;
    }
    if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
  }
  for(i=2; i<objc; i++){
    zArg = Tcl_GetString(objv[i]);
    if( zArg[0]!='-' ){
      if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
      zFile = zArg;
      continue;
    }
    if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
    i++;
    if( strcmp(zArg,"-key")==0 ){
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
      pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
      /* no-op */
#endif
    }else if( strcmp(zArg, "-vfs")==0 ){
      zVfs = Tcl_GetString(objv[i]);
    }else if( strcmp(zArg, "-readonly")==0 ){
      int b;
      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
      if( b ){
        flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
        flags |= SQLITE_OPEN_READONLY;
      }else{
        flags &= ~SQLITE_OPEN_READONLY;
        flags |= SQLITE_OPEN_READWRITE;
      }
    }else if( strcmp(zArg, "-create")==0 ){
      int b;
      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
      if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
        flags |= SQLITE_OPEN_CREATE;
      }else{
        flags &= ~SQLITE_OPEN_CREATE;
      }
    }else if( strcmp(zArg, "-nofollow")==0 ){
      int b;
      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
      if( b ){
        flags |= SQLITE_OPEN_NOFOLLOW;
      }else{
        flags &= ~SQLITE_OPEN_NOFOLLOW;
      }
    }else if( strcmp(zArg, "-nomutex")==0 ){
      int b;
      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
      if( b ){
        flags |= SQLITE_OPEN_NOMUTEX;
        flags &= ~SQLITE_OPEN_FULLMUTEX;
      }else{
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814

3815
3816
3817
3818

3819
3820
3821
3822
3823
3824
3825
3826
3827
3828





3829
3830
3831
3832
3833
3834
3835
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







-
-
-
-









-
-
+
-

-
-
+
-









+
+
+
+
+







      int b;
      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
      if( b ){
        flags |= SQLITE_OPEN_URI;
      }else{
        flags &= ~SQLITE_OPEN_URI;
      }
    }else if( strcmp(zArg, "-translatefilename")==0 ){
      if( Tcl_GetBooleanFromObj(interp, objv[i], &bTranslateFileName) ){
        return TCL_ERROR;
      }
    }else{
      Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
      return TCL_ERROR;
    }
  }
  zErrMsg = 0;
  p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
  memset(p, 0, sizeof(*p));
  if( zFile==0 ) zFile = "";
  if( bTranslateFileName ){
    zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
  zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
  }
  rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
  if( bTranslateFileName ){
    Tcl_DStringFree(&translatedFilename);
  Tcl_DStringFree(&translatedFilename);
  }
  if( p->db ){
    if( SQLITE_OK!=sqlite3_errcode(p->db) ){
      zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
      sqlite3_close(p->db);
      p->db = 0;
    }
  }else{
    zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
  }
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
  if( p->db ){
    sqlite3_key(p->db, pKey, nKey);
  }
#endif
  if( p->db==0 ){
    Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
    Tcl_Free((char*)p);
    sqlite3_free(zErrMsg);
    return TCL_ERROR;
  }
  p->maxStmt = NUM_PREPARED_STMTS;

Changes to src/test1.c.

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







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














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







*/
static int SQLITE_TCLAPI test_key(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
  sqlite3 *db;
  const char *zKey;
  int nKey;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  zKey = argv[2];
  nKey = strlen(zKey);
  sqlite3_key(db, zKey, nKey);
#endif
  return TCL_OK;
}

/*
** Usage:  sqlite3_rekey DB KEY
**
** Change the codec key.
*/
static int SQLITE_TCLAPI test_rekey(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
#ifdef SQLITE_HAS_CODEC
  sqlite3 *db;
  const char *zKey;
  int nKey;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  zKey = argv[2];
  nKey = strlen(zKey);
  sqlite3_rekey(db, zKey, nKey);
#endif
  return TCL_OK;
}

/*
** Usage:  sqlite3_close DB
**
** Closes the database opened by sqlite3_open.
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







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







  int argc,  
  sqlite3_value **argv
){
  static int cnt = 0;
  sqlite3_result_int(context, cnt++);
}

/*
** This SQL function returns the integer value of its argument as a MEM_IntReal
** value.
*/
static void intrealFunction(
  sqlite3_context *context, 
  int argc,  
  sqlite3_value **argv
){
  sqlite3_int64 v = sqlite3_value_int64(argv[0]);
  sqlite3_result_int64(context, v);
  sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context);
}

/*
** Usage:  sqlite3_create_function DB
**
** Call the sqlite3_create_function API on the given database in order
** to create a function named "x_coalesce".  This function does the same thing
** as the "coalesce" function.  This function also registers an SQL function
** named "x_sqlite_exec" that invokes sqlite3_exec().  Invoking sqlite3_exec()
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1058
1059
1060
1061
1062
1063
1064








1065
1066
1067
1068
1069
1070
1071







-
-
-
-
-
-
-
-







          0, nondeterministicFunction, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "counter2", -1, SQLITE_UTF8|SQLITE_DETERMINISTIC,
          0, nondeterministicFunction, 0, 0);
  }

  /* The intreal() function converts its argument to an integer and returns
  ** it as a MEM_IntReal.
  */
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "intreal", 1, SQLITE_UTF8,
          0, intrealFunction, 0, 0);
  }

#ifndef SQLITE_OMIT_UTF16
  /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
  ** because it is not tested anywhere else. */
  if( rc==SQLITE_OK ){
    const void *zUtf16;
    sqlite3_value *pVal;
    sqlite3_mutex_enter(db->mutex);
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
1081
1082
1083
1084
1085
1086
1087



























1088
1089
1090
1091
1092
1093
1094







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







    sqlite3ValueFree(pVal);
    sqlite3_mutex_leave(db->mutex);
  }
#endif

  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
  return TCL_OK;
}

/*
** Usage:  sqlite3_drop_modules DB ?NAME ...?
**
** Invoke the sqlite3_drop_modules(D,L) interface on database
** connection DB, in order to drop all modules except those named in
** the argument.
*/
static int SQLITE_TCLAPI test_drop_modules(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite3 *db;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " DB\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0);
#endif
  return TCL_OK;
}

/*
** Routines to implement the x_count() aggregate function.
**
** x_count() counts the number of non-null arguments.  But there are
3936
3937
3938
3939
3940
3941
3942
3943

3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
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
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
3915
3916
3917
3918
3919
3920
3921

3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934





























































































































































































3935
3936
3937
3938
3939
3940
3941







-
+












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







  value = (char*)Tcl_GetByteArrayFromObj(objv[3], &len);
  if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;

  if( bytes>len ){
    char zBuf[200];
    sqlite3_snprintf(sizeof(zBuf), zBuf,
                     "cannot use %d blob bytes, have %d", bytes, len);
    Tcl_AppendResult(interp, zBuf, (char*)0);
    Tcl_AppendResult(interp, zBuf, -1);
    return TCL_ERROR;
  }

  rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor);
  if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
  if( rc!=SQLITE_OK ){
    return TCL_ERROR;
  }

  return TCL_OK;
}


#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** sqlite3_carray_bind [options...] STMT NAME VALUE ...
**
** Options:
**    -transient
**    -static
**    -int32
**    -int64
**    -double
**    -text
**
** Each call clears static data.  Called with no options does nothing
** but clear static data.
*/
static int SQLITE_TCLAPI test_carray_bind(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3_stmt *pStmt;
  int eType = 0;   /* CARRAY_INT32 */
  int nData = 0;
  void *aData = 0;
  int isTransient = 0;
  int isStatic = 0;
  int idx;
  int i, j;
  int rc;
  void (*xDel)(void*) = sqlite3_free;
  static void *aStaticData = 0;
  static int nStaticData = 0;
  static int eStaticType = 0;
  extern int sqlite3_carray_bind(
    sqlite3_stmt *pStmt,
    int i,
    void *aData,
    int nData,
    int mFlags,
    void (*xDestroy)(void*)
  );
  
  if( aStaticData ){
    /* Always clear preexisting static data on every call */
    if( eStaticType==3 ){
      for(i=0; i<nStaticData; i++){
        sqlite3_free(((char**)aStaticData)[i]);
      }
    }
    sqlite3_free(aStaticData);
    aStaticData = 0;
    nStaticData = 0;
    eStaticType = 0;
  }
  if( objc==1 ) return TCL_OK;

  for(i=1; i<objc && Tcl_GetString(objv[i])[0]=='-'; i++){
    const char *z = Tcl_GetString(objv[i]);
    if( strcmp(z, "-transient")==0 ){
      isTransient = 1;
      xDel = SQLITE_TRANSIENT;
    }else
    if( strcmp(z, "-static")==0 ){
      isStatic = 1;
      xDel = SQLITE_STATIC;
    }else
    if( strcmp(z, "-int32")==0 ){
      eType = 0;  /* CARRAY_INT32 */
    }else
    if( strcmp(z, "-int64")==0 ){
      eType = 1;  /* CARRAY_INT64 */
    }else
    if( strcmp(z, "-double")==0 ){
      eType = 2;  /* CARRAY_DOUBLE */
    }else
    if( strcmp(z, "-text")==0 ){
      eType = 3;  /* CARRAY_TEXT */
    }else
    if( strcmp(z, "--")==0 ){
      break;
    }else
    {
      Tcl_AppendResult(interp, "unknown option: ", z, (char*)0);
      return TCL_ERROR;
    }
  }
  if( eType==3 && !isStatic && !isTransient ){
    Tcl_AppendResult(interp, "text data must be either -static or -transient",
                     (char*)0);
    return TCL_ERROR;
  }
  if( isStatic && isTransient ){
    Tcl_AppendResult(interp, "cannot be both -static and -transient",
                     (char*)0);
    return TCL_ERROR;
  }
  if( objc-i < 2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "[OPTIONS] STMT IDX VALUE ...");
    return TCL_ERROR;
  }
  if( getStmtPointer(interp, Tcl_GetString(objv[i]), &pStmt) ) return TCL_ERROR;
  i++;
  if( Tcl_GetIntFromObj(interp, objv[i], &idx) ) return TCL_ERROR;
  i++;
  nData = objc - i;
  switch( eType + 4*(nData<=0) ){
    case 0: { /* INT32 */
      int *a = sqlite3_malloc( sizeof(int)*nData );
      if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; }
      for(j=0; j<nData; j++){
        int v;
        if( Tcl_GetIntFromObj(interp, objv[i+j], &v) ){
          sqlite3_free(a);
          return TCL_ERROR;
        }
        a[j] = v;
      }
      aData = a;
      break;
    }
    case 1: { /* INT64 */
      sqlite3_int64 *a = sqlite3_malloc( sizeof(sqlite3_int64)*nData );
      if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; }
      for(j=0; j<nData; j++){
        Tcl_WideInt v;
        if( Tcl_GetWideIntFromObj(interp, objv[i+j], &v) ){
          sqlite3_free(a);
          return TCL_ERROR;
        }
        a[j] = v;
      }
      aData = a;
      break;
    }
    case 2: { /* DOUBLE */
      double *a = sqlite3_malloc( sizeof(double)*nData );
      if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; }
      for(j=0; j<nData; j++){
        double v;
        if( Tcl_GetDoubleFromObj(interp, objv[i+j], &v) ){
          sqlite3_free(a);
          return TCL_ERROR;
        }
        a[j] = v;
      }
      aData = a;
      break;
    }
    case 3: { /* TEXT */
      char **a = sqlite3_malloc( sizeof(char*)*nData );
      if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; }
      for(j=0; j<nData; j++){
        const char *v = Tcl_GetString(objv[i+j]);
        a[j] = sqlite3_mprintf("%s", v);
      }
      aData = a;
      break;
    }
    case 4: { /* nData==0 */
      aData = "";
      xDel = SQLITE_STATIC;
      isTransient = 0;
      isStatic = 0;
      break;
    }
  }
  if( isStatic ){
    aStaticData = aData;
    nStaticData = nData;
    eStaticType = eType;
  }
  rc = sqlite3_carray_bind(pStmt, idx, aData, nData, eType, xDel);
  if( isTransient ){
    if( eType==3 ){
      for(i=0; i<nData; i++) sqlite3_free(((char**)aData)[i]);
    }
    sqlite3_free(aData);
  }
carray_bind_done:
  if( rc ){
    Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
    return TCL_ERROR;
  }
  return TCL_OK;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

/*
** Usage:   sqlite3_bind_parameter_count  STMT
**
** Return the number of wildcards in the given statement.
*/
static int SQLITE_TCLAPI test_bind_parameter_count(
  void * clientData,
4815
4816
4817
4818
4819
4820
4821
4822

4823
4824
4825
4826
4827
4828
4829
4605
4606
4607
4608
4609
4610
4611

4612
4613
4614
4615
4616
4617
4618
4619







-
+







      { "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY },
      { "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB },
      { "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB },
      { "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB },
      { "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL },
      { "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL },
      { "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL },
      { "SQLITE_OPEN_SUPER_JOURNAL", SQLITE_OPEN_SUPER_JOURNAL },
      { "SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL },
      { "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX },
      { "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX },
      { "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE },
      { "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE },
      { "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL },
      { "SQLITE_OPEN_URI", SQLITE_OPEN_URI },
      { 0, 0 }
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5473
5474
5475
5476
5477
5478
5479



























5480
5481
5482
5483
5484
5485
5486







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







    if( Tcl_GetWideIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
  }
  amt = sqlite3_soft_heap_limit64(N);
  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(amt));
  return TCL_OK;
}

/*
** Usage:  sqlite3_hard_heap_limit ?N?
**
** Query or set the hard heap limit for the current thread.  The
** limit is only changed if the N is present.  The previous limit
** is returned.
*/
static int SQLITE_TCLAPI test_hard_heap_limit(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3_int64 amt;
  Tcl_WideInt N = -1;
  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?N?");
    return TCL_ERROR;
  }
  if( objc==2 ){
    if( Tcl_GetWideIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
  }
  amt = sqlite3_hard_heap_limit64(N);
  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(amt));
  return TCL_OK;
}

/*
** Usage:   sqlite3_thread_cleanup
**
** Call the sqlite3_thread_cleanup API.
*/
static int SQLITE_TCLAPI test_thread_cleanup(
  void * clientData,
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6186
6187
6188
6189
6190
6191
6192






























6193
6194
6195
6196
6197
6198
6199







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







    zDbName = Tcl_GetString(objv[2]);
  }
  sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName);
  Tcl_AppendResult(interp, zVfsName, (char*)0);
  sqlite3_free(zVfsName);
  return TCL_OK;  
}

/*
** tclcmd:   file_control_reservebytes DB N
*/
static int SQLITE_TCLAPI file_control_reservebytes(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  sqlite3 *db;
  const char *zDbName = "main";
  int n = 0;
  int rc;

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB N");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
   || Tcl_GetIntFromObj(interp, objv[2], &n) 
  ){
    return TCL_ERROR;
  }

  rc = sqlite3_file_control(db, zDbName, SQLITE_FCNTL_RESERVE_BYTES, (void*)&n);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
  return TCL_OK;  
}


/*
** tclcmd:   file_control_tempfilename DB ?AUXDB?
**
** Return a string that is a temporary filename
*/
static int SQLITE_TCLAPI file_control_tempfilename(
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655

6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6347
6348
6349
6350
6351
6352
6353



































6354
























6355
6356
6357
6358
6359
6360
6361







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







*/
static int SQLITE_TCLAPI reset_prng_state(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  sqlite3_randomness(0,0);
  return TCL_OK;
}
/*
** tclcmd:  prng_seed INT ?DB?
**
** Set up the SQLITE_TESTCTRL_PRNG_SEED pragma with parameter INT and DB.
** INT is an integer.  DB is a database connection, or a NULL pointer if
** omitted.
**
** When INT!=0 and DB!=0, set the PRNG seed to the value of the schema
** cookie for DB, or to INT if the schema cookie happens to be zero.
**
** When INT!=0 and DB==0, set the PRNG seed to just INT.
**
** If INT==0 and DB==0 then use the default procedure of calling the
** xRandomness method on the default VFS to get the PRNG seed.
*/
static int SQLITE_TCLAPI prng_seed(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  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);
  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET);
  return TCL_OK;
}

/*
** tclcmd:  extra_schema_checks BOOLEAN
**
** Enable or disable schema checks when parsing the sqlite_schema file.
** This is always enabled in production, but it is sometimes useful to
** disable the checks in order to make some internal error states reachable
** for testing.
*/
static int SQLITE_TCLAPI extra_schema_checks(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  int i = 0;
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
    return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp,objv[1],&i) ) return TCL_ERROR;
  sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, i);
  return TCL_OK;
}

/*
** tclcmd:  database_may_be_corrupt
**
** Indicate that database files might be corrupt. In other words, set the normal
7083
7084
7085
7086
7087
7088
7089
7090

7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
6758
6759
6760
6761
6762
6763
6764

6765









6766
6767
6768
6769
6770
6771
6772







-
+
-
-
-
-
-
-
-
-
-







  rc = Tcl_GetIndexFromObjStruct(
      interp, objv[1], aVerb, sizeof(aVerb[0]), "VERB", 0, &iVerb
  );
  if( rc!=TCL_OK ) return rc;

  iFlag = aVerb[iVerb].i;
  switch( iFlag ){
    case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
    case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
      sqlite3 *db = 0;
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "DB");
        return TCL_ERROR;
      }
      if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
      sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, db);
      break;
    }
    case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
      int val;
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "ONOFF");
        return TCL_ERROR;
      }
      if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
7447
7448
7449
7450
7451
7452
7453

7454

7455
7456
7457
7458
7459
7460
7461
7462
7463
7113
7114
7115
7116
7117
7118
7119
7120

7121
7122

7123
7124
7125
7126
7127
7128
7129







+
-
+

-







    { "groupby-order",       SQLITE_GroupByOrder   },
    { "factor-constants",    SQLITE_FactorOutConst },
    { "distinct-opt",        SQLITE_DistinctOpt    },
    { "cover-idx-scan",      SQLITE_CoverIdxScan   },
    { "order-by-idx-join",   SQLITE_OrderByIdxJoin },
    { "transitive",          SQLITE_Transitive     },
    { "omit-noop-join",      SQLITE_OmitNoopJoin   },
    { "stat3",               SQLITE_Stat34         },
    { "stat4",               SQLITE_Stat4          },
    { "stat4",               SQLITE_Stat34         },
    { "skip-scan",           SQLITE_SkipScan       },
    { "push-down",           SQLITE_PushDown       },
  };

  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB OPT BOOLEAN");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7156
7157
7158
7159
7160
7161
7162

7163
7164
7165
7166
7167
7168

7169
7170
7171
7172
7173
7174
7175







-






-







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*);
  extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  extern int sqlite3_prefixes_init(sqlite3*,char**,const sqlite3_api_routines*);
#endif
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7184
7185
7186
7187
7188
7189
7190

7191
7192
7193

7194
7195
7196
7197
7198
7199
7200







-



-







  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               },
    { "fuzzer",                sqlite3_fuzzer_init               },
    { "ieee754",               sqlite3_ieee_init                 },
    { "nextchar",              sqlite3_nextchar_init             },
    { "percentile",            sqlite3_percentile_init           },
7569
7570
7571
7572
7573
7574
7575
7576

7577
7578
7579
7580
7581
7582
7583
7231
7232
7233
7234
7235
7236
7237

7238
7239
7240
7241
7242
7243
7244
7245







-
+







      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 ){
    if( rc!=SQLITE_OK || zErrMsg ){
      Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
                       (char*)0);
      sqlite3_free(zErrMsg);
      return TCL_ERROR;
    }
  }
  return TCL_OK;
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935









7936
7937
7938
7939
7940
7941
7942
7943

7944
7945
7946
7947
7948


7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965

7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
7582
7583
7584
7585
7586
7587
7588









7589
7590
7591
7592
7593
7594
7595
7596
7597





7598
7599

7600
7601
7602
7603


7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620


7621



7622
7623
7624
7625



























7626
7627
7628
7629
7630
7631
7632







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


-
+



-
-
+
+















-
-
+
-
-
-




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







  int objc,
  Tcl_Obj *CONST objv[]
){
  static const struct {
    const char *zName;
    int eVal;
  } aSetting[] = {
    { "FKEY",               SQLITE_DBCONFIG_ENABLE_FKEY },
    { "TRIGGER",            SQLITE_DBCONFIG_ENABLE_TRIGGER },
    { "FTS3_TOKENIZER",     SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
    { "LOAD_EXTENSION",     SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
    { "NO_CKPT_ON_CLOSE",   SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
    { "QPSG",               SQLITE_DBCONFIG_ENABLE_QPSG },
    { "TRIGGER_EQP",        SQLITE_DBCONFIG_TRIGGER_EQP },
    { "RESET_DB",           SQLITE_DBCONFIG_RESET_DATABASE },
    { "DEFENSIVE",          SQLITE_DBCONFIG_DEFENSIVE },
    { "FKEY",            SQLITE_DBCONFIG_ENABLE_FKEY },
    { "TRIGGER",         SQLITE_DBCONFIG_ENABLE_TRIGGER },
    { "FTS3_TOKENIZER",  SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
    { "LOAD_EXTENSION",  SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
    { "NO_CKPT_ON_CLOSE",SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
    { "QPSG",            SQLITE_DBCONFIG_ENABLE_QPSG },
    { "TRIGGER_EQP",     SQLITE_DBCONFIG_TRIGGER_EQP },
    { "RESET_DB",        SQLITE_DBCONFIG_RESET_DATABASE },
    { "DEFENSIVE",       SQLITE_DBCONFIG_DEFENSIVE },
    { "WRITABLE_SCHEMA",    SQLITE_DBCONFIG_WRITABLE_SCHEMA },
    { "LEGACY_ALTER_TABLE", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
    { "DQS_DML",            SQLITE_DBCONFIG_DQS_DML },
    { "DQS_DDL",            SQLITE_DBCONFIG_DQS_DDL },
    { "LEGACY_FILE_FORMAT", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT },
  };
  int i;
  int v = 0;
  int v;
  const char *zSetting;
  sqlite3 *db;

  if( objc!=4 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB SETTING [VALUE]");
  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB SETTING VALUE");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSetting = Tcl_GetString(objv[2]);
  if( sqlite3_strglob("SQLITE_*", zSetting)==0 ) zSetting += 7;
  if( sqlite3_strglob("DBCONFIG_*", zSetting)==0 ) zSetting += 9;
  if( sqlite3_strglob("ENABLE_*", zSetting)==0 ) zSetting += 7;
  for(i=0; i<ArraySize(aSetting); i++){
    if( strcmp(zSetting, aSetting[i].zName)==0 ) break;
  }
  if( i>=ArraySize(aSetting) ){
    Tcl_SetObjResult(interp,
      Tcl_NewStringObj("unknown sqlite3_db_config setting", -1));
    return TCL_ERROR;
  }
  if( objc==4 ){
    if( Tcl_GetIntFromObj(interp, objv[3], &v) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[3], &v) ) return TCL_ERROR;
  }else{
    v = -1;
  }
  sqlite3_db_config(db, aSetting[i].eVal, v, &v);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
  return TCL_OK;
}
/*
** tclcmd:   sqlite3_txn_state DB ?SCHEMA?
**
** Invoke sqlite3_txn_state(DB,SCHEMA) and return the
** numeric value that results.  Use NULL for SCHEMA if the 3 argument
** is omitted.
*/
static int SQLITE_TCLAPI test_sqlite3_txn_state(
  void *clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db;
  const char *zSchema;
  int iTxn;

  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB ?SCHEMA?");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSchema = objc==3 ? Tcl_GetString(objv[2]) : 0;
  iTxn = sqlite3_txn_state(db, zSchema);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(iTxn));
  return TCL_OK;
}

/*
** Change the name of the main database schema from "main" to "icecube".
*/
static int SQLITE_TCLAPI test_dbconfig_maindbname_icecube(
  void * clientData,
  Tcl_Interp *interp,
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
7672
7673
7674
7675
7676
7677
7678













































































7679
7680
7681
7682
7683
7684
7685







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







    }
    rc = sqlite3_mmap_warm(db, zDb);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
    return TCL_OK;
  }
}

/*
** Usage:  test_write_db DB OFFSET DATA
**
** Obtain the sqlite3_file* object for the database file for the "main" db
** of handle DB. Then invoke its xWrite method to write data DATA to offset
** OFFSET.
*/
static int SQLITE_TCLAPI test_write_db(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db = 0;
  Tcl_WideInt iOff = 0;
  const unsigned char *aData = 0;
  int nData = 0;
  sqlite3_file *pFile = 0;
  int rc;

  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB OFFSET DATA");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  if( Tcl_GetWideIntFromObj(interp, objv[2], &iOff) ) return TCL_ERROR;
  aData = Tcl_GetByteArrayFromObj(objv[3], &nData);

  sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFile);
  rc = pFile->pMethods->xWrite(pFile, aData, nData, iOff);

  Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  return TCL_OK;
}

/*
** Usage:  sqlite3_register_cksumvfs
**
*/
static int SQLITE_TCLAPI test_register_cksumvfs(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }else{
    extern int sqlite3_register_cksumvfs(const char*);
    int rc = sqlite3_register_cksumvfs(0);
    Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  }
  return TCL_OK;
}

/*
** Usage:  sqlite3_unregister_cksumvfs
**
*/
static int SQLITE_TCLAPI test_unregister_cksumvfs(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }else{
    extern int sqlite3_unregister_cksumvfs(void);
    int rc = sqlite3_unregister_cksumvfs();
    Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  }
  return TCL_OK;
}

/*
** Usage:  decode_hexdb TEXT
**
** Example:   db deserialize [decode_hexdb $output_of_dbtotxt]
**
** This routine returns a byte-array for an SQLite database file that
** is constructed from a text input which is the output of the "dbtotxt"
8146
8147
8148
8149
8150
8151
8152
8153

8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190


8191
8192
8193
8194
8195
8196

8197
8198
8199
8200
8201
8202
8203
8204
7695
7696
7697
7698
7699
7700
7701

7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716





7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733

7734
7735
7736
7737
7738
7739
7740

7741

7742
7743
7744
7745
7746
7747
7748







-
+














-
-
-
-
-

















-
+
+





-
+
-







  unsigned char *a = 0;
  int n = 0;
  int lineno = 0;
  int i, iNext;
  int iOffset = 0;
  int j, k;
  int rc;
  unsigned int x[16];
  unsigned char x[16];
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "HEXDB");
    return TCL_ERROR;
  }
  zIn = Tcl_GetString(objv[1]);
  for(i=0; zIn[i]; i=iNext){
    lineno++;
    for(iNext=i; zIn[iNext] && zIn[iNext]!='\n'; iNext++){}
    if( zIn[iNext]=='\n' ) iNext++;
    while( zIn[i]==' ' || zIn[i]=='\t' ){ i++; }
    if( a==0 ){
      int pgsz;
      rc = sscanf(zIn+i, "| size %d pagesize %d", &n, &pgsz);
      if( rc!=2 ) continue;
      if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ){
        Tcl_AppendResult(interp, "bad 'pagesize' field", (void*)0);
        return TCL_ERROR;
      }
      n = (n+pgsz-1)&~(pgsz-1);  /* Round n up to the next multiple of pgsz */
      if( n<512 ){
        Tcl_AppendResult(interp, "bad 'size' field", (void*)0);
        return TCL_ERROR;
      }
      a = malloc( n );
      if( a==0 ){
        Tcl_AppendResult(interp, "out of memory", (void*)0);
        return TCL_ERROR;
      }
      memset(a, 0, n);
      continue;
    }
    rc = sscanf(zIn+i, "| page %d offset %d", &j, &k);
    if( rc==2 ){
      iOffset = k;
      continue;
    }
    rc = sscanf(zIn+i,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
    rc = sscanf(zIn+i,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
                      "  %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
                &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
                &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
    if( rc==17 ){
      k = iOffset+j;
      if( k+16<=n ){
        int ii;
        memcpy(a+k, x, 16);
        for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
      }
      continue;
    }
  }
  Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(a, n));
  free(a);
  return TCL_OK;
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
7792
7793
7794
7795
7796
7797
7798

7799
7800
7801
7802
7803
7804
7805







-







#ifndef SQLITE_OMIT_GET_TABLE
     { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
#endif
     { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
     { "sqlite3_close_v2",              (Tcl_CmdProc*)sqlite_test_close_v2  },
     { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
     { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
     { "sqlite3_drop_modules",          (Tcl_CmdProc*)test_drop_modules     },
     { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
     { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
     { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
     { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
     { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
     { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
     { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
7814
7815
7816
7817
7818
7819
7820

7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836



7837
7838
7839
7840
7841
7842
7843







-
















-
-
-







  };
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
     void *clientData;
  } aObjCmd[] = {
     { "sqlite3_db_config",             test_sqlite3_db_config, 0 },
     { "sqlite3_txn_state",             test_sqlite3_txn_state, 0 },
     { "bad_behavior",                  test_bad_behavior,  (void*)&iZero },
     { "register_dbstat_vtab",          test_register_dbstat_vtab  },
     { "sqlite3_connection_pointer",    get_sqlite_pointer, 0 },
     { "intarray_addr",                 test_intarray_addr, 0 },
     { "int64array_addr",               test_int64array_addr, 0 },
     { "doublearray_addr",              test_doublearray_addr, 0 },
     { "textarray_addr",                test_textarray_addr, 0 },
     { "sqlite3_bind_int",              test_bind_int,      0 },
     { "sqlite3_bind_zeroblob",         test_bind_zeroblob, 0 },
     { "sqlite3_bind_zeroblob64",       test_bind_zeroblob64, 0 },
     { "sqlite3_bind_int64",            test_bind_int64,    0 },
     { "sqlite3_bind_double",           test_bind_double,   0 },
     { "sqlite3_bind_null",             test_bind_null     ,0 },
     { "sqlite3_bind_text",             test_bind_text     ,0 },
     { "sqlite3_bind_text16",           test_bind_text16   ,0 },
     { "sqlite3_bind_blob",             test_bind_blob     ,0 },
#ifndef SQLITE_OMIT_VIRTUALTABLE
     { "sqlite3_carray_bind",           test_carray_bind   ,0 },
#endif
     { "sqlite3_bind_parameter_count",  test_bind_parameter_count, 0},
     { "sqlite3_bind_parameter_name",   test_bind_parameter_name,  0},
     { "sqlite3_bind_parameter_index",  test_bind_parameter_index, 0},
     { "sqlite3_clear_bindings",        test_clear_bindings, 0},
     { "sqlite3_sleep",                 test_sleep,          0},
     { "sqlite3_errcode",               test_errcode       ,0 },
     { "sqlite3_extended_errcode",      test_ex_errcode    ,0 },
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
7876
7877
7878
7879
7880
7881
7882


7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894


7895
7896
7897
7898
7899
7900
7901







-
-












-
-







     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_db_release_memory",     test_db_release_memory,  0},
     { "sqlite3_db_cacheflush",         test_db_cacheflush,      0},
     { "sqlite3_system_errno",          test_system_errno,       0},
     { "sqlite3_db_filename",           test_db_filename,        0},
     { "sqlite3_db_readonly",           test_db_readonly,        0},
     { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
     { "sqlite3_soft_heap_limit64",     test_soft_heap_limit,    0},
     { "sqlite3_hard_heap_limit64",     test_hard_heap_limit,    0},
     { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
     { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},

     { "sqlite3_load_extension",        test_load_extension,     0},
     { "sqlite3_enable_load_extension", test_enable_load,        0},
     { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
     { "sqlite3_limit",                 test_limit,                 0},
     { "dbconfig_maindbname_icecube",   test_dbconfig_maindbname_icecube },

     { "save_prng_state",               save_prng_state,    0 },
     { "restore_prng_state",            restore_prng_state, 0 },
     { "reset_prng_state",              reset_prng_state,   0 },
     { "prng_seed",                     prng_seed,          0 },
     { "extra_schema_checks",           extra_schema_checks,    0},
     { "database_never_corrupt",        database_never_corrupt, 0},
     { "database_may_be_corrupt",       database_may_be_corrupt, 0},
     { "optimization_control",          optimization_control,0},
#if SQLITE_OS_WIN
     { "lock_win32_file",               win32_file_lock,    0 },
     { "exists_win32_path",             win32_exists_path,  0 },
     { "find_win32_file",               win32_find_file,    0 },
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
7957
7958
7959
7960
7961
7962
7963

7964
7965
7966
7967
7968
7969
7970







-







     { "file_control_win32_av_retry", file_control_win32_av_retry,  0   },
     { "file_control_win32_get_handle", file_control_win32_get_handle, 0  },
     { "file_control_win32_set_handle", file_control_win32_set_handle, 0  },
#endif
     { "file_control_persist_wal",    file_control_persist_wal,     0   },
     { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
     { "file_control_vfsname",        file_control_vfsname,         0   },
     { "file_control_reservebytes",   file_control_reservebytes,    0   },
     { "file_control_tempfilename",   file_control_tempfilename,    0   },
     { "sqlite3_vfs_list",           vfs_list,     0   },
     { "sqlite3_create_function_v2", test_create_function_v2, 0 },

     /* Functions from os.h */
#ifndef SQLITE_OMIT_UTF16
     { "add_test_collate",        test_collate, 0            },
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517

8518
8519
8520
8521
8522
8523
8524



8525
8526
8527
8528
8529
8530
8531
8026
8027
8028
8029
8030
8031
8032



8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047

8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065







-
-
-















-
+







+
+
+







     { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 },
#endif
     { "sqlite3_delete_database", test_delete_database,    0 },
     { "atomic_batch_write",      test_atomic_batch_write, 0 },
     { "sqlite3_mmap_warm",       test_mmap_warm,          0 },
     { "sqlite3_config_sorterref", test_config_sorterref,   0 },
     { "decode_hexdb",             test_decode_hexdb,       0 },
     { "test_write_db",            test_write_db,           0 },
     { "sqlite3_register_cksumvfs", test_register_cksumvfs,  0 },
     { "sqlite3_unregister_cksumvfs", test_unregister_cksumvfs,  0 },
  };
  static int bitmask_size = sizeof(Bitmask)*8;
  static int longdouble_size = sizeof(LONGDOUBLE_TYPE);
  int i;
  extern int sqlite3_sync_count, sqlite3_fullsync_count;
  extern int sqlite3_opentemp_count;
  extern int sqlite3_like_count;
  extern int sqlite3_xferopt_count;
  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 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 int sqlite3SelectTrace;
#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, 
8605
8606
8607
8608
8609
8610
8611
8612

8613
8614
8615
8616
8617
8618
8619
8620
8139
8140
8141
8142
8143
8144
8145

8146
8147
8148
8149
8150
8151
8152
8153
8154







-
+








  Tcl_LinkVar(interp, "longdouble_size",
      (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",
  Tcl_LinkVar(interp, "sqlite3SelectTrace",
      (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/test4.c.

28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+








-
+








/*
** Each thread is controlled by an instance of the following
** structure.
*/
typedef struct Thread Thread;
struct Thread {
  /* The first group of fields are writable by the leader and read-only
  /* The first group of fields are writable by the master and read-only
  ** to the thread. */
  char *zFilename;       /* Name of database file */
  void (*xOp)(Thread*);  /* next operation to do */
  char *zArg;            /* argument usable by xOp */
  int opnum;             /* Operation number */
  int busy;              /* True if this thread is in use */

  /* The next group of fields are writable by the thread but read-only to the
  ** leader. */
  ** master. */
  int completed;        /* Number of operations completed */
  sqlite3 *db;           /* Open database */
  sqlite3_stmt *pStmt;     /* Pending operation */
  char *zErr;           /* operation error */
  char *zStaticErr;     /* Static error message */
  int rc;               /* operation return code */
  int argc;             /* number of columns in result */

Changes to src/test6.c.

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







-
+
-


-
+
-


-
+
-








-
+
-







  return g.iDeviceCharacteristics;
}

/*
** Pass-throughs for WAL support.
*/
static int cfShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
  sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
  return sqlite3OsShmLock(((CrashFile*)pFile)->pRealFile, ofst, n, flags);
  return pReal->pMethods->xShmLock(pReal, ofst, n, flags);
}
static void cfShmBarrier(sqlite3_file *pFile){
  sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
  sqlite3OsShmBarrier(((CrashFile*)pFile)->pRealFile);
  pReal->pMethods->xShmBarrier(pReal);
}
static int cfShmUnmap(sqlite3_file *pFile, int delFlag){
  sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
  return sqlite3OsShmUnmap(((CrashFile*)pFile)->pRealFile, delFlag);
  return pReal->pMethods->xShmUnmap(pReal, delFlag);
}
static int cfShmMap(
  sqlite3_file *pFile,            /* Handle open on database file */
  int iRegion,                    /* Region to retrieve */
  int sz,                         /* Size of regions */
  int w,                          /* True to extend file if necessary */
  void volatile **pp              /* OUT: Mapped memory */
){
  sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
  return sqlite3OsShmMap(((CrashFile*)pFile)->pRealFile, iRegion, sz, w, pp);
  return pReal->pMethods->xShmMap(pReal, iRegion, sz, w, pp);
}

static const sqlite3_io_methods CrashFileVtab = {
  2,                            /* iVersion */
  cfClose,                      /* xClose */
  cfRead,                       /* xRead */
  cfWrite,                      /* xWrite */

Changes to src/test8.c.

337
338
339
340
341
342
343
344

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

344
345
346
347
348
349
350
351







-
+







  sqlite3 *db 
){
  int rc = SQLITE_OK;

  if( pVtab->zTableName ){
    sqlite3_stmt *pStmt = 0;
    rc = sqlite3_prepare(db, 
        "SELECT sql FROM sqlite_schema WHERE type = 'table' AND name = ?",
        "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?",
        -1, &pStmt, 0);
    if( rc==SQLITE_OK ){
      sqlite3_bind_text(pStmt, 1, pVtab->zTableName, -1, 0);
      if( sqlite3_step(pStmt)==SQLITE_ROW ){
        int rc2;
        const char *zCreateTable = (const char *)sqlite3_column_text(pStmt, 0);
        rc = sqlite3_declare_vtab(db, zCreateTable);

Changes to src/test_config.c.

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






157
158
159
160
161
162
163







-
-
-
-
-
-








#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

#ifdef SQLITE_ENABLE_MEMSYS5
228
229
230
231
232
233
234



235

236
237
238
239
240
241
242
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240







+
+
+

+








#ifdef SQLITE_ENABLE_JSON1
  Tcl_SetVar2(interp, "sqlite_options", "json1", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_HAS_CODEC
  Tcl_SetVar2(interp, "sqlite_options", "has_codec", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "has_codec", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
  Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "1", TCL_GLOBAL_ONLY);
#endif

583
584
585
586
587
588
589






590
591
592
593
594
595
596
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600







+
+
+
+
+
+







#endif

#ifdef SQLITE_ENABLE_STAT4
  Tcl_SetVar2(interp, "sqlite_options", "stat4", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "stat4", "0", TCL_GLOBAL_ONLY);
#endif
#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
  Tcl_SetVar2(interp, "sqlite_options", "stat3", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "stat3", "0", TCL_GLOBAL_ONLY);
#endif

#if defined(SQLITE_ENABLE_STMTVTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
  Tcl_SetVar2(interp, "sqlite_options", "stmtvtab", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "stmtvtab", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS

Changes to src/test_demovfs.c.

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
236
237
238
239
240
241
242



243
244
245
246
247
248
249







-
-
-







    return SQLITE_IOERR_READ;
  }
  nRead = read(p->fd, zBuf, iAmt);

  if( nRead==iAmt ){
    return SQLITE_OK;
  }else if( nRead>=0 ){
    if( nRead<iAmt ){
      memset(&((char*)zBuf)[nRead], 0, iAmt-nRead);
    }
    return SQLITE_IOERR_SHORT_READ;
  }

  return SQLITE_IOERR_READ;
}

/*
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379







-
+







  return SQLITE_OK;
}

/*
** No xFileControl() verbs are implemented by this VFS.
*/
static int demoFileControl(sqlite3_file *pFile, int op, void *pArg){
  return SQLITE_NOTFOUND;
  return SQLITE_OK;
}

/*
** The xSectorSize() and xDeviceCharacteristics() methods. These two
** may return special values allowing SQLite to optimize file-system 
** access to some extent. But it is also safe to simply return 0.
*/

Changes to src/test_devsym.c.

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







-
+









-
+



-
+



-
+







}

/*
** Shared-memory methods are all pass-thrus.
*/
static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
  devsym_file *p = (devsym_file *)pFile;
  return p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
  return sqlite3OsShmLock(p->pReal, ofst, n, flags);
}
static int devsymShmMap(
  sqlite3_file *pFile, 
  int iRegion, 
  int szRegion, 
  int isWrite, 
  void volatile **pp
){
  devsym_file *p = (devsym_file *)pFile;
  return p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
  return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
}
static void devsymShmBarrier(sqlite3_file *pFile){
  devsym_file *p = (devsym_file *)pFile;
  p->pReal->pMethods->xShmBarrier(p->pReal);
  sqlite3OsShmBarrier(p->pReal);
}
static int devsymShmUnmap(sqlite3_file *pFile, int delFlag){
  devsym_file *p = (devsym_file *)pFile;
  return p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
  return sqlite3OsShmUnmap(p->pReal, delFlag);
}



/*
** Open an devsym file handle.
*/
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
501
502
503
504
505
506
507

508
509
510
511
512
513
514







-







  }else{
    g.iSectorSize = 512;
  }
}

void devsym_unregister(){
  sqlite3_vfs_unregister(&devsym_vfs);
  sqlite3_vfs_unregister(&writecrash_vfs);
  g.pVfs = 0;
  g.iDeviceChar = 0;
  g.iSectorSize = 0;
}

void devsym_crash_on_write(int nWrite){
  if( g.pVfs==0 ){

Changes to src/test_hexio.c.

164
165
166
167
168
169
170
171

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

171
172
173
174
175
176
177
178







-
+







  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET HEXDATA");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR;
  zFile = Tcl_GetString(objv[1]);
  zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn);
  aOut = sqlite3_malloc( 1 + nIn/2 );
  aOut = sqlite3_malloc( nIn/2 );
  if( aOut==0 ){
    return TCL_ERROR;
  }
  nOut = sqlite3TestHexToBin(zIn, nIn, aOut);
  out = fopen(zFile, "r+b");
  if( out==0 ){
    out = fopen(zFile, "r+");
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223







-
+







  unsigned char aNum[4];

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA");
    return TCL_ERROR;
  }
  zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn);
  aOut = sqlite3_malloc( 1 + nIn/2 );
  aOut = sqlite3_malloc( nIn/2 );
  if( aOut==0 ){
    return TCL_ERROR;
  }
  nOut = sqlite3TestHexToBin(zIn, nIn, aOut);
  if( nOut>=4 ){
    memcpy(aNum, aOut, 4);
  }else{
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319







-
+







  const unsigned char *zOrig;
  unsigned char *z;
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "HEX");
    return TCL_ERROR;
  }
  zOrig = (unsigned char *)Tcl_GetStringFromObj(objv[1], &n);
  z = sqlite3_malloc( n+4 );
  z = sqlite3_malloc( n+3 );
  n = sqlite3TestHexToBin(zOrig, n, z);
  z[n] = 0;
  nOut = sqlite3Utf8To8(z);
  sqlite3TestBinToHex(z,nOut);
  Tcl_AppendResult(interp, (char*)z, 0);
  sqlite3_free(z);
  return TCL_OK;
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
333
334
335
336
337
338
339











340
341
342
343
344
345
346







-
-
-
-
-
-
-
-
-
-
-







    y <<= 7;
  }
  x += y * (*q++);
  *v = (sqlite_int64) x;
  return (int) (q - (unsigned char *)p);
}

static int putFts3Varint(char *p, sqlite_int64 v){
  unsigned char *q = (unsigned char *) p;
  sqlite_uint64 vu = v;
  do{
    *q++ = (unsigned char) ((vu & 0x7f) | 0x80);
    vu >>= 7;
  }while( vu!=0 );
  q[-1] &= 0x7f;  /* turn off high bit in final byte */
  assert( q - (unsigned char *)p <= 10 );
  return (int) (q - (unsigned char *)p);
}

/*
** USAGE:  read_fts3varint BLOB VARNAME
**
** Read a varint from the start of BLOB. Set variable VARNAME to contain
** the interpreted value. Return the number of bytes of BLOB consumed.
*/
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
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







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
















-








  nVal = getFts3Varint((char*)zBlob, (sqlite3_int64 *)(&iVal));
  Tcl_ObjSetVar2(interp, objv[2], 0, Tcl_NewWideIntObj(iVal), 0);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(nVal));
  return TCL_OK;
}

/*
** USAGE:  make_fts3record ARGLIST
*/
static int SQLITE_TCLAPI make_fts3record(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  Tcl_Obj **aArg = 0;
  int nArg = 0;
  unsigned char *aOut = 0;
  int nOut = 0;
  int nAlloc = 0;
  int i;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "LIST");
    return TCL_ERROR;
  }
  if( Tcl_ListObjGetElements(interp, objv[1], &nArg, &aArg) ){
    return TCL_ERROR;
  }

  for(i=0; i<nArg; i++){
    sqlite3_int64 iVal;
    if( TCL_OK==Tcl_GetWideIntFromObj(0, aArg[i], &iVal) ){
      if( nOut+10>nAlloc ){
        int nNew = nAlloc?nAlloc*2:128;
        unsigned char *aNew = sqlite3_realloc(aOut, nNew);
        if( aNew==0 ){
          sqlite3_free(aOut);
          return TCL_ERROR;
        }
        aOut = aNew;
        nAlloc = nNew;
      }
      nOut += putFts3Varint((char*)&aOut[nOut], iVal);
    }else{
      int nVal = 0;
      char *zVal = Tcl_GetStringFromObj(aArg[i], &nVal);
      while( (nOut + nVal)>nAlloc ){
        int nNew = nAlloc?nAlloc*2:128;
        unsigned char *aNew = sqlite3_realloc(aOut, nNew);
        if( aNew==0 ){
          sqlite3_free(aOut);
          return TCL_ERROR;
        }
        aOut = aNew;
        nAlloc = nNew;
      }
      memcpy(&aOut[nOut], zVal, nVal);
      nOut += nVal;
    }
  }

  Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aOut, nOut));
  sqlite3_free(aOut);
  return TCL_OK;
}


/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest_hexio_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
  } aObjCmd[] = {
     { "hexio_read",                   hexio_read            },
     { "hexio_write",                  hexio_write           },
     { "hexio_get_int",                hexio_get_int         },
     { "hexio_render_int16",           hexio_render_int16    },
     { "hexio_render_int32",           hexio_render_int32    },
     { "utf8_to_utf8",                 utf8_to_utf8          },
     { "read_fts3varint",              read_fts3varint       },
     { "make_fts3record",              make_fts3record       },
  };
  int i;
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
  }
  return TCL_OK;
}

Changes to src/test_malloc.c.

107
108
109
110
111
112
113


























114
115
116
117
118
119
120
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







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







static void *faultsimRealloc(void *pOld, int n){
  void *p = 0;
  if( !faultsimStep() ){
    p = memfault.m.xRealloc(pOld, n);
  }
  return p;
}

/* 
** The following method calls are passed directly through to the underlying
** malloc system:
**
**     xFree
**     xSize
**     xRoundup
**     xInit
**     xShutdown
*/
static void faultsimFree(void *p){
  memfault.m.xFree(p);
}
static int faultsimSize(void *p){
  return memfault.m.xSize(p);
}
static int faultsimRoundup(int n){
  return memfault.m.xRoundup(n);
}
static int faultsimInit(void *p){
  return memfault.m.xInit(memfault.m.pAppData);
}
static void faultsimShutdown(void *p){
  memfault.m.xShutdown(memfault.m.pAppData);
}

/*
** This routine configures the malloc failure simulation.  After
** calling this routine, the next nDelay mallocs will succeed, followed
** by a block of nRepeat failures, after which malloc() calls will begin
** to succeed again.
*/
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
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







+
+
+
+
+
+
+
+
+
+













-
-
-







}

/*
** Add or remove the fault-simulation layer using sqlite3_config(). If
** the argument is non-zero, the 
*/
static int faultsimInstall(int install){
  static struct sqlite3_mem_methods m = {
    faultsimMalloc,                   /* xMalloc */
    faultsimFree,                     /* xFree */
    faultsimRealloc,                  /* xRealloc */
    faultsimSize,                     /* xSize */
    faultsimRoundup,                  /* xRoundup */
    faultsimInit,                     /* xInit */
    faultsimShutdown,                 /* xShutdown */
    0                                 /* pAppData */
  };
  int rc;

  install = (install ? 1 : 0);
  assert(memfault.isInstalled==1 || memfault.isInstalled==0);

  if( install==memfault.isInstalled ){
    return SQLITE_ERROR;
  }

  if( install ){
    rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);
    assert(memfault.m.xMalloc);
    if( rc==SQLITE_OK ){
      sqlite3_mem_methods m = memfault.m;
      m.xMalloc = faultsimMalloc;
      m.xRealloc = faultsimRealloc;
      rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
    }
    sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 
        faultsimBeginBenign, faultsimEndBenign
    );
  }else{
    sqlite3_mem_methods m2;

Changes to src/test_multiplex.c.

263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
263
264
265
266
267
268
269

270
271
272
273
274



275
276
277
278
279
280
281







-
+




-
-
-







    memset(&p[pGroup->nReal], 0, sizeof(p[0])*(iChunk+1-pGroup->nReal));
    pGroup->aReal = p;
    pGroup->nReal = iChunk+1;
  }
  if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){
    char *z;
    int n = pGroup->nName;
    z = sqlite3_malloc64( n+5 );
    pGroup->aReal[iChunk].z = z = sqlite3_malloc64( n+5 );
    if( z==0 ){
      return SQLITE_NOMEM;
    }
    multiplexFilename(pGroup->zName, pGroup->nName, pGroup->flags, iChunk, z);
    pGroup->aReal[iChunk].z = sqlite3_create_filename(z,"","",0,0);
    sqlite3_free(z);
    if( pGroup->aReal[iChunk].z==0 ) return SQLITE_NOMEM;
  }
  return SQLITE_OK;
}

/* Translate an sqlite3_file* that is really a multiplexGroup* into
** the sqlite3_file* for the underlying original VFS.
**
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448







-
+







  if( pSubOpen ){
    pSubOpen->pMethods->xClose(pSubOpen);
    if( pOrigVfs && pGroup->aReal[iChunk].z ){
      pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0);
    }
    sqlite3_free(pGroup->aReal[iChunk].p);
  }
  sqlite3_free_filename(pGroup->aReal[iChunk].z);
  sqlite3_free(pGroup->aReal[iChunk].z);
  memset(&pGroup->aReal[iChunk], 0, sizeof(pGroup->aReal[iChunk]));
}

/*
** Deallocate memory held by a multiplexGroup
*/
static void multiplexFreeComponents(multiplexGroup *pGroup){
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
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







-
+











-
+







#else
      int sqlite3PendingByte = 0x40000000;
#endif
      while( (sqlite3PendingByte % pGroup->szChunk)>=(pGroup->szChunk-65536) ){
        pGroup->szChunk += 65536;
      }
    }
    pGroup->flags = (flags & ~SQLITE_OPEN_URI);
    pGroup->flags = flags;
    rc = multiplexSubFilename(pGroup, 1);
    if( rc==SQLITE_OK ){
      pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags, 0);
      if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN;
    }
    if( rc==SQLITE_OK ){
      sqlite3_int64 sz64;

      rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz64);
      if( rc==SQLITE_OK && zName ){
        int bExists;
        if( flags & SQLITE_OPEN_SUPER_JOURNAL ){
        if( flags & SQLITE_OPEN_MASTER_JOURNAL ){
          pGroup->bEnabled = 0;
        }else
        if( sz64==0 ){
          if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
            /* If opening a main journal file and the first chunk is zero
            ** bytes in size, delete any subsequent chunks from the 
            ** file-system. */
587
588
589
590
591
592
593
594

595
596

597
598
599
600
601
602
603
584
585
586
587
588
589
590

591
592

593
594
595
596
597
598
599
600







-
+

-
+







          }
        }
      }
    }

    if( rc==SQLITE_OK ){
      if( pSubOpen->pMethods->iVersion==1 ){
        pConn->pMethods = &gMultiplex.sIoMethodsV1;
        pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1;
      }else{
        pConn->pMethods = &gMultiplex.sIoMethodsV2;
        pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV2;
      }
    }else{
      multiplexFreeComponents(pGroup);
      sqlite3_free(pGroup);
    }
  }
  sqlite3_free(zToFree);

Changes to src/test_mutex.c.

26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







-
+







#define MAX_MUTEXES        (SQLITE_MUTEX_STATIC_VFS3+1)
#define STATIC_MUTEXES     (MAX_MUTEXES-(SQLITE_MUTEX_RECURSIVE+1))

/* defined in main.c */
extern const char *sqlite3ErrName(int);

static const char *aName[MAX_MUTEXES+1] = {
  "fast",        "recursive",   "static_main",   "static_mem",
  "fast",        "recursive",   "static_master", "static_mem",
  "static_open", "static_prng", "static_lru",    "static_pmem",
  "static_app1", "static_app2", "static_app3",   "static_vfs1",
  "static_vfs2", "static_vfs3", 0
};

/* A countable mutex */
struct sqlite3_mutex {

Changes to src/test_osinst.c.

736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750







-
+







  p->base.zName = &((char *)p->pLog)[pParent->szOsFile];
  p->base.szOsFile += pParent->szOsFile;
  memcpy((char *)p->base.zName, zVfs, nVfs);

  zFile = (char *)&p->base.zName[nVfs+1];
  pParent->xFullPathname(pParent, zLog, pParent->mxPathname, zFile);

  flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_SUPER_JOURNAL;
  flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MASTER_JOURNAL;
  pParent->xDelete(pParent, zFile, 0);
  rc = pParent->xOpen(pParent, zFile, p->pLog, flags, &flags);
  if( rc==SQLITE_OK ){
    memcpy(p->aBuf, "sqlite_ostrace1.....", 20);
    p->iOffset = 0;
    p->nBuf = 20;
    rc = sqlite3_vfs_register((sqlite3_vfs *)p, 1);
889
890
891
892
893
894
895
896

897
898
899
900
901
902
903
889
890
891
892
893
894
895

896
897
898
899
900
901
902
903







-
+







    sqlite3_free(p);
    return SQLITE_NOMEM;
  }
  dequote(zFile);
  pVfs->xFullPathname(pVfs, zFile, pVfs->mxPathname, p->zFile);
  sqlite3_free(zFile);

  flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_SUPER_JOURNAL;
  flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MASTER_JOURNAL;
  rc = pVfs->xOpen(pVfs, p->zFile, p->pFd, flags, &flags);

  if( rc==SQLITE_OK ){
    p->pFd->pMethods->xFileSize(p->pFd, &p->nByte);
    sqlite3_declare_vtab(db, 
        "CREATE TABLE xxx(event, file, click, rc, size, offset)"
    );

Changes to src/test_schema.c.

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







-
+





-
+




-
+







      assert(pCur->pDbList);
      while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){
        rc = finalize(&pCur->pDbList);
        goto next_exit;
      }

      /* Set zSql to the SQL to pull the list of tables from the 
      ** sqlite_schema (or sqlite_temp_schema) table of the database
      ** sqlite_master (or sqlite_temp_master) table of the database
      ** identified by the row pointed to by the SQL statement pCur->pDbList
      ** (iterating through a "PRAGMA database_list;" statement).
      */
      if( sqlite3_column_int(pCur->pDbList, 0)==1 ){
        zSql = sqlite3_mprintf(
            "SELECT name FROM sqlite_temp_schema WHERE type='table'"
            "SELECT name FROM sqlite_temp_master WHERE type='table'"
        );
      }else{
        sqlite3_stmt *pDbList = pCur->pDbList;
        zSql = sqlite3_mprintf(
            "SELECT name FROM %Q.sqlite_schema WHERE type='table'",
            "SELECT name FROM %Q.sqlite_master WHERE type='table'",
             sqlite3_column_text(pDbList, 1)
        );
      }
      if( !zSql ){
        rc = SQLITE_NOMEM;
        goto next_exit;
      }

Changes to src/test_sqllog.c.

114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128







-
+







  int iLog;                       /* First integer value used in file names */
  FILE *fd;                       /* File descriptor for log file */
};

/* This object is a singleton that keeps track of all data loggers.
*/
static struct SLGlobal {
  /* Protected by MUTEX_STATIC_MAIN */
  /* Protected by MUTEX_STATIC_MASTER */
  sqlite3_mutex *mutex;           /* Recursive mutex */
  int nConn;                      /* Size of aConn[] array */

  /* Protected by SLGlobal.mutex */
  int bConditional;               /* Only trace if *-sqllog file is present */
  int bReuse;                     /* True to avoid extra copies of db files */
  char zPrefix[SQLLOG_NAMESZ];    /* Prefix for all created files */
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
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







-
+






-
+



-
+




-
+




-
+


















-
+
















-
+







** The pCtx parameter is a copy of the pointer that was originally passed
** into the sqlite3_config(SQLITE_CONFIG_SQLLOG) statement.  In this
** particular implementation, pCtx is always a pointer to the 
** sqllogglobal global variable define above.
*/
static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){
  struct SLConn *p = 0;
  sqlite3_mutex *mainmtx = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MAIN);
  sqlite3_mutex *master = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);

  assert( eType==0 || eType==1 || eType==2 );
  assert( (eType==2)==(zSql==0) );

  /* This is a database open command. */
  if( eType==0 ){
    sqlite3_mutex_enter(mainmtx);
    sqlite3_mutex_enter(master);
    if( sqllogglobal.mutex==0 ){
      sqllogglobal.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
    }
    sqlite3_mutex_leave(mainmtx);
    sqlite3_mutex_leave(master);

    sqlite3_mutex_enter(sqllogglobal.mutex);
    if( sqllogglobal.bRec==0 && sqllogTraceDb(db) ){

      sqlite3_mutex_enter(mainmtx);
      sqlite3_mutex_enter(master);
      p = &sqllogglobal.aConn[sqllogglobal.nConn++];
      p->fd = 0;
      p->db = db;
      p->iLog = sqllogglobal.iNextLog++;
      sqlite3_mutex_leave(mainmtx);
      sqlite3_mutex_leave(master);

      /* Open the log and take a copy of the main database file */
      sqllogOpenlog(p);
      if( p->fd ) sqllogCopydb(p, "main", 0);
    }
    sqlite3_mutex_leave(sqllogglobal.mutex);
  }

  else{

    int i;
    for(i=0; i<sqllogglobal.nConn; i++){
      p = &sqllogglobal.aConn[i];
      if( p->db==db ) break;
    }

    /* A database handle close command */
    if( eType==2 ){
      sqlite3_mutex_enter(mainmtx);
      sqlite3_mutex_enter(master);
      if( i<sqllogglobal.nConn ){
        if( p->fd ) fclose(p->fd);
        p->db = 0;
        p->fd = 0;
        sqllogglobal.nConn--;
      }

      if( sqllogglobal.nConn==0 ){
        sqlite3_mutex_free(sqllogglobal.mutex);
        sqllogglobal.mutex = 0;
      }else if( i<sqllogglobal.nConn ){
        int nShift = &sqllogglobal.aConn[sqllogglobal.nConn] - p;
        if( nShift>0 ){
          memmove(p, &p[1], nShift*sizeof(struct SLConn));
        }
      }
      sqlite3_mutex_leave(mainmtx);
      sqlite3_mutex_leave(master);

    /* An ordinary SQL command. */
    }else if( i<sqllogglobal.nConn && p->fd ){
      sqlite3_mutex_enter(sqllogglobal.mutex);
      if( sqllogglobal.bRec==0 ){
        testSqllogStmt(p, zSql);
      }

Changes to src/test_thread.c.

283
284
285
286
287
288
289
















290
291
292
293
294
295
296
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







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







  extern int Md5_Register(sqlite3*,char**,const sqlite3_api_routines*);

  UNUSED_PARAMETER(clientData);
  UNUSED_PARAMETER(objc);

  zFilename = Tcl_GetString(objv[2]);
  sqlite3_open(zFilename, &db);
#ifdef SQLITE_HAS_CODEC
  if( db && objc>=4 ){
    const char *zKey;
    int nKey;
    int rc;
    zKey = Tcl_GetStringFromObj(objv[3], &nKey);
    rc = sqlite3_key(db, zKey, nKey);
    if( rc!=SQLITE_OK ){
      char *zErrMsg = sqlite3_mprintf("error %d: %s", rc, sqlite3_errmsg(db));
      sqlite3_close(db);
      Tcl_AppendResult(interp, zErrMsg, (char*)0);
      sqlite3_free(zErrMsg);
      return TCL_ERROR;
    }
  }
#endif
  Md5_Register(db, 0, 0);
  sqlite3_busy_handler(db, xBusy, 0);
  
  if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);

  return TCL_OK;

Changes to src/test_vfs.c.

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

238
239
240
241
242
243
244







-







    { SQLITE_OK,       "SQLITE_OK"     },
    { SQLITE_ERROR,    "SQLITE_ERROR"  },
    { SQLITE_IOERR,    "SQLITE_IOERR"  },
    { SQLITE_LOCKED,   "SQLITE_LOCKED" },
    { SQLITE_BUSY,     "SQLITE_BUSY"   },
    { SQLITE_READONLY, "SQLITE_READONLY"   },
    { SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT"   },
    { SQLITE_NOTFOUND, "SQLITE_NOTFOUND"   },
    { -1,              "SQLITE_OMIT"   },
  };

  const char *z;
  int i;

  z = Tcl_GetStringResult(p->interp);
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
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







-













-
+







  if( p->pScript && (p->mask&TESTVFS_FCNTL_MASK) ){
    struct Fcntl {
      int iFnctl;
      const char *zFnctl;
    } aF[] = {
      { SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, "BEGIN_ATOMIC_WRITE" },
      { SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, "COMMIT_ATOMIC_WRITE" },
      { SQLITE_FCNTL_ZIPVFS, "ZIPVFS" },
    };
    int i;
    for(i=0; i<sizeof(aF)/sizeof(aF[0]); i++){
      if( op==aF[i].iFnctl ) break;
    }
    if( i<sizeof(aF)/sizeof(aF[0]) ){
      int rc = 0;
      tvfsExecTcl(p, "xFileControl", 
          Tcl_NewStringObj(pFd->zFilename, -1), 
          Tcl_NewStringObj(aF[i].zFnctl, -1),
          0, 0
      );
      tvfsResultCode(p, &rc);
      if( rc ) return (rc<0 ? SQLITE_OK : rc);
      if( rc ) return rc;
    }
  }
  return sqlite3OsFileControl(pFd->pReal, op, pArg);
}

/*
** Return the sector-size in bytes for an tvfs-file.
891
892
893
894
895
896
897
898
899

900
901
902
903
904
905
906
889
890
891
892
893
894
895


896
897
898
899
900
901
902
903







-
-
+







  void volatile **pp              /* OUT: Mapped memory */
){
  int rc = SQLITE_OK;
  TestvfsFd *pFd = tvfsGetFd(pFile);
  Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);

  if( p->isFullshm ){
    sqlite3_file *pReal = pFd->pReal;
    return pReal->pMethods->xShmMap(pReal, iPage, pgsz, isWrite, pp);
    return sqlite3OsShmMap(pFd->pReal, iPage, pgsz, isWrite, pp);
  }

  if( 0==pFd->pShm ){
    rc = tvfsShmOpen(pFile);
    if( rc!=SQLITE_OK ){
      return rc;
    }
942
943
944
945
946
947
948
949
950

951
952
953
954
955
956
957
939
940
941
942
943
944
945


946
947
948
949
950
951
952
953







-
-
+







  int rc = SQLITE_OK;
  TestvfsFd *pFd = tvfsGetFd(pFile);
  Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
  int nLock;
  char zLock[80];

  if( p->isFullshm ){
    sqlite3_file *pReal = pFd->pReal;
    return pReal->pMethods->xShmLock(pReal, ofst, n, flags);
    return sqlite3OsShmLock(pFd->pReal, ofst, n, flags);
  }

  if( p->pScript && p->mask&TESTVFS_SHMLOCK_MASK ){
    sqlite3_snprintf(sizeof(zLock), zLock, "%d %d", ofst, n);
    nLock = (int)strlen(zLock);
    if( flags & SQLITE_SHM_LOCK ){
      strcpy(&zLock[nLock], " lock");
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
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







-
-
+















-
-
+








  if( p->pScript && p->mask&TESTVFS_SHMBARRIER_MASK ){
    const char *z = pFd->pShm ? pFd->pShm->zFile : "";
    tvfsExecTcl(p, "xShmBarrier", Tcl_NewStringObj(z, -1), pFd->pShmId, 0, 0);
  }

  if( p->isFullshm ){
    sqlite3_file *pReal = pFd->pReal;
    pReal->pMethods->xShmBarrier(pReal);
    sqlite3OsShmBarrier(pFd->pReal);
    return;
  }
}

static int tvfsShmUnmap(
  sqlite3_file *pFile,
  int deleteFlag
){
  int rc = SQLITE_OK;
  TestvfsFd *pFd = tvfsGetFd(pFile);
  Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
  TestvfsBuffer *pBuffer = pFd->pShm;
  TestvfsFd **ppFd;

  if( p->isFullshm ){
    sqlite3_file *pReal = pFd->pReal;
    return pReal->pMethods->xShmUnmap(pReal, deleteFlag);
    return sqlite3OsShmUnmap(pFd->pReal, deleteFlag);
  }

  if( !pBuffer ) return SQLITE_OK;
  assert( pFd->pShmId && pFd->pShm );

  if( p->pScript && p->mask&TESTVFS_SHMCLOSE_MASK ){
    tvfsExecTcl(p, "xShmUnmap", 
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1384
1385
1386
1387
1388
1389
1390

1391

1392
1393
1394
1395
1396
1397
1398







-

-







  return TCL_OK;
}

static void SQLITE_TCLAPI testvfs_obj_del(ClientData cd){
  Testvfs *p = (Testvfs *)cd;
  if( p->pScript ) Tcl_DecrRefCount(p->pScript);
  sqlite3_vfs_unregister(p->pVfs);
  memset(p->pVfs, 0, sizeof(sqlite3_vfs));
  ckfree((char *)p->pVfs);
  memset(p, 0, sizeof(Testvfs));
  ckfree((char *)p);
}

/*
** Usage:  testvfs VFSNAME ?SWITCHES?
**
** Switches are:

Changes to src/tokenize.c.

23
24
25
26
27
28
29
30
31


32
33
34
35
36
37
38
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_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 */
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
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_ID        27    /* unicode characters usable in IDs */
#define CC_ILLEGAL   28    /* Illegal character */
#define CC_NUL       29    /* 0x00 */
#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 */   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,
/* 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,  2,  2,  9, 28, 28, 28,  2,
/* 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,  2,  2, 28, 10, 28, 25, 28,
/* 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 */   29, 28, 28, 28, 28,  7, 28, 28, 28, 28, 28, 28,  7,  7, 28, 28,
/* 1x */   28, 28, 28, 28, 28,  7, 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,
/* 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
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
418
419
420
421
422
423
424

425
426
427
428
429
430
431







-







#endif
      {
        *tokenType = TK_DOT;
        return 1;
      }
      /* If the next character is a digit, this is a floating point
      ** number that begins with ".".  Fall thru into the next case */
      /* no break */ deliberate_fall_through
    }
    case CC_DIGIT: {
      testcase( z[0]=='0' );  testcase( z[0]=='1' );  testcase( z[0]=='2' );
      testcase( z[0]=='3' );  testcase( z[0]=='4' );  testcase( z[0]=='5' );
      testcase( z[0]=='6' );  testcase( z[0]=='7' );  testcase( z[0]=='8' );
      testcase( z[0]=='9' );
      *tokenType = TK_INTEGER;
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
494
495
496
497
498
499
500

501
502
503
504
505
506
507
508







-
+







        }else{
          break;
        }
      }
      if( n==0 ) *tokenType = TK_ILLEGAL;
      return i;
    }
    case CC_KYWD0: {
    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;
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
522
523
524
525
526
527
528

529

530
531
532
533
534
535
536







-

-







        }
        if( z[i] ) i++;
        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;
568
569
570
571
572
573
574
575

576
577
578
579
580
581
582
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578







-
+







  yyParser sEngine;    /* Space to hold the Lemon-generated Parser object */
#endif
  VVA_ONLY( u8 startedWithOom = db->mallocFailed );

  assert( zSql!=0 );
  mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
  if( db->nVdbeActive==0 ){
    AtomicStore(&db->u1.isInterrupted, 0);
    db->u1.isInterrupted = 0;
  }
  pParse->rc = SQLITE_OK;
  pParse->zTail = zSql;
  assert( pzErrMsg!=0 );
#ifdef SQLITE_DEBUG
  if( db->flags & SQLITE_ParserTrace ){
    printf("parser: [[[%s]]]\n", zSql);
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
609
610
611
612
613
614
615

616
617
618
619
620
621
622
623







-
+







      assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
           || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW 
      );
#else
    if( tokenType>=TK_SPACE ){
      assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
#endif /* SQLITE_OMIT_WINDOWFUNC */
      if( AtomicLoad(&db->u1.isInterrupted) ){
      if( db->u1.isInterrupted ){
        pParse->rc = SQLITE_INTERRUPT;
        break;
      }
      if( tokenType==TK_SPACE ){
        zSql += n;
        continue;
      }
709
710
711
712
713
714
715


716










717
718
719
720
721
722
723
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







+
+

+
+
+
+
+
+
+
+
+
+







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


745
746
747
748
749
750
751
752

753
754
755
756
757
758
759
753
754
755
756
757
758
759

760
761
762
763
764
765
766
767







-
+







  int i;             /* Next unread byte of zSql[] */
  int n;             /* length of current token */
  int tokenType;     /* type of current token */
  int prevType = 0;  /* Previous non-whitespace token */
  int nParen;        /* Number of nested levels of parentheses */
  int iStartIN;      /* Start of RHS of IN operator in z[] */
  int nParenAtIN;    /* Value of nParent at start of RHS of IN operator */
  u32 j;             /* Bytes of normalized SQL generated so far */
  int j;             /* Bytes of normalized SQL generated so far */
  sqlite3_str *pStr; /* The normalized SQL string under construction */

  db = sqlite3VdbeDb(pVdbe);
  tokenType = -1;
  nParen = iStartIN = nParenAtIN = 0;
  pStr = sqlite3_str_new(db);
  assert( pStr!=0 );  /* sqlite3_str_new() never returns NULL */
789
790
791
792
793
794
795
796

797
798
799
800
801
802
803
797
798
799
800
801
802
803

804
805
806
807
808
809
810
811







-
+







          nParenAtIN = nParen;
        }
        sqlite3_str_append(pStr, "(", 1);
        break;
      }
      case TK_RP: {
        if( iStartIN>0 && nParen==nParenAtIN ){
          assert( pStr->nChar>=(u32)iStartIN );
          assert( pStr->nChar>=iStartIN );
          pStr->nChar = iStartIN+1;
          sqlite3_str_append(pStr, "?,?,?", 5);
          iStartIN = 0;
        }
        nParen--;
        sqlite3_str_append(pStr, ")", 1);
        break;

Changes to src/treeview.c.

62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76







-
+







    }
    sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
  }
  if( zFormat!=0 ){
    va_start(ap, zFormat);
    sqlite3_str_vappendf(&acc, zFormat, ap);
    va_end(ap);
    assert( acc.nChar>0 || acc.accError );
    assert( acc.nChar>0 );
    sqlite3_str_append(&acc, "\n", 1);
  }
  sqlite3StrAccumFinish(&acc);
  fprintf(stdout,"%s", zBuf);
  fflush(stdout);
}

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







-
+




-
-
+
-
-















-
+



-
+






-
-
+
+







-
-
-
-
-
-







      const struct Cte *pCte = &pWith->a[i];
      sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
      sqlite3_str_appendf(&x, "%s", pCte->zName);
      if( pCte->pCols && pCte->pCols->nExpr>0 ){
        char cSep = '(';
        int j;
        for(j=0; j<pCte->pCols->nExpr; j++){
          sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName);
          sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
          cSep = ',';
        }
        sqlite3_str_appendf(&x, ")");
      }
      if( pCte->pUse ){
        sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse,
      sqlite3_str_appendf(&x, " AS");
                 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];
    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);
    sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
    if( pItem->zDatabase ){
      sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
    }else if( pItem->zName ){
      sqlite3_str_appendf(&x, " %s", pItem->zName);
    }
    if( pItem->pTab ){
      sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
           pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
      sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
           pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
    }
    if( pItem->zAlias ){
      sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
    }
    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:");
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
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







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
















-
-
+
-
-







  pView = sqlite3TreeViewPush(pView, moreToFollow);
  if( p->pWith ){
    sqlite3TreeViewWith(pView, p->pWith, 1);
    cnt = 1;
    sqlite3TreeViewPush(pView, 1);
  }
  do{
    if( p->selFlags & SF_WhereBegin ){
      sqlite3TreeViewLine(pView, "sqlite3WhereBegin()");
    }else{
      sqlite3TreeViewLine(pView,
        "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
        ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
        ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
        p->selId, p, p->selFlags,
        (int)p->nSelectRow
      );
    sqlite3TreeViewLine(pView,
      "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
      ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
      ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
      p->selId, p, p->selFlags,
      (int)p->nSelectRow
    );
    }
    if( cnt++ ) sqlite3TreeViewPop(pView);
    if( p->pPrior ){
      n = 1000;
    }else{
      n = 0;
      if( p->pSrc && p->pSrc->nSrc ) n++;
      if( p->pWhere ) n++;
      if( p->pGroupBy ) n++;
      if( p->pHaving ) n++;
      if( p->pOrderBy ) n++;
      if( p->pLimit ) n++;
#ifndef SQLITE_OMIT_WINDOWFUNC
      if( p->pWin ) n++;
      if( p->pWinDefn ) n++;
#endif
    }
    if( p->pEList ){
      sqlite3TreeViewExprList(pView, p->pEList, n>0, "result-set");
    sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
    }
    n--;
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( p->pWin ){
      Window *pX;
      pView = sqlite3TreeViewPush(pView, (n--)>0);
      sqlite3TreeViewLine(pView, "window-functions");
      for(pX=p->pWin; pX; pX=pX->pNextWin){
        sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
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
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







-
+






-
+
-
-
-
-

+
-
-
+
+
-
-
+

-
-
-
-












-
-
-
-
-
-
-
+
-

-
-
+
+
-








/*
** Generate a human-readable explanation of an expression tree.
*/
void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
  const char *zBinOp = 0;   /* Binary operator */
  const char *zUniOp = 0;   /* Unary operator */
  char zFlgs[200];
  char zFlgs[60];
  pView = sqlite3TreeViewPush(pView, moreToFollow);
  if( pExpr==0 ){
    sqlite3TreeViewLine(pView, "nil");
    sqlite3TreeViewPop(pView);
    return;
  }
  if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
  if( pExpr->flags ){
    StrAccum x;
    sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
    sqlite3_str_appendf(&x, " fg.af=%x.%c",
      pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
    if( ExprHasProperty(pExpr, EP_FromJoin) ){
      sqlite3_snprintf(sizeof(zFlgs),zFlgs,"  flags=0x%x iRJT=%d",
      sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
    }
                       pExpr->flags, pExpr->iRightJoinTable);
    }else{
    if( ExprHasProperty(pExpr, EP_FromDDL) ){
      sqlite3_str_appendf(&x, " DDL");
      sqlite3_snprintf(sizeof(zFlgs),zFlgs,"  flags=0x%x",pExpr->flags);
    }
    if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
      sqlite3_str_appendf(&x, " IMMUTABLE");
    }
    sqlite3StrAccumFinish(&x);
  }else{
    zFlgs[0] = 0;
  }
  switch( pExpr->op ){
    case TK_AGG_COLUMN: {
      sqlite3TreeViewLine(pView, "AGG{%d:%d}%s",
            pExpr->iTable, pExpr->iColumn, zFlgs);
      break;
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        char zOp2[16];
        if( pExpr->op2 ){
          sqlite3_snprintf(sizeof(zOp2),zOp2," op2=0x%02x",pExpr->op2);
        }else{
          zOp2[0] = 0;
        }
        sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s",
        sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs);
                                    pExpr->iColumn, zFlgs, zOp2);
      }else{
        sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s",
                        pExpr->iTable, pExpr->iColumn,
        sqlite3TreeViewLine(pView, "{%d:%d}%s",
                             pExpr->iTable, pExpr->iColumn, zFlgs);
                        pExpr->y.pTab, zFlgs);
      }
      if( ExprHasProperty(pExpr, EP_FixedCol) ){
        sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
      }
      break;
    }
    case TK_INTEGER: {
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592


593
594
595
596
597
598
599
600
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633
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







-















-
+












-
-
-
-
-
-
+
-
-














-
+





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

-
+


















-
+







    case TK_BITAND:  zBinOp = "BITAND"; break;
    case TK_BITOR:   zBinOp = "BITOR";  break;
    case TK_SLASH:   zBinOp = "DIV";    break;
    case TK_LSHIFT:  zBinOp = "LSHIFT"; break;
    case TK_RSHIFT:  zBinOp = "RSHIFT"; break;
    case TK_CONCAT:  zBinOp = "CONCAT"; break;
    case TK_DOT:     zBinOp = "DOT";    break;
    case TK_LIMIT:   zBinOp = "LIMIT";  break;

    case TK_UMINUS:  zUniOp = "UMINUS"; break;
    case TK_UPLUS:   zUniOp = "UPLUS";  break;
    case TK_BITNOT:  zUniOp = "BITNOT"; break;
    case TK_NOT:     zUniOp = "NOT";    break;
    case TK_ISNULL:  zUniOp = "ISNULL"; break;
    case TK_NOTNULL: zUniOp = "NOTNULL"; break;

    case TK_TRUTH: {
      int x;
      const char *azOp[] = {
         "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
      };
      assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
      assert( pExpr->pRight );
      assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE );
      assert( pExpr->pRight->op==TK_TRUEFALSE );
      x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
      zUniOp = azOp[x];
      break;
    }

    case TK_SPAN: {
      sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
      break;
    }

    case TK_COLLATE: {
      /* COLLATE operators without the EP_Collate flag are intended to
      ** emulate collation associated with a table column.  These show
      ** up in the treeview output as "SOFT-COLLATE".  Explicit COLLATE
      ** operators that appear in the original SQL always have the
      ** EP_Collate bit set and appear in treeview output as just "COLLATE" */
      sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s",
      sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
        !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "",
        pExpr->u.zToken, zFlgs);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
      break;
    }

    case TK_AGG_FUNCTION:
    case TK_FUNCTION: {
      ExprList *pFarg;       /* List of function arguments */
      Window *pWin;
      if( ExprHasProperty(pExpr, EP_TokenOnly) ){
        pFarg = 0;
        pWin = 0;
      }else{
        pFarg = pExpr->x.pList;
#ifndef SQLITE_OMIT_WINDOWFUNC
        pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0;
        pWin = pExpr->y.pWin;
#else
        pWin = 0;
#endif 
      }
      if( pExpr->op==TK_AGG_FUNCTION ){
        sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p",
                             pExpr->op2, pExpr->u.zToken, zFlgs,
        sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
                             pExpr->op2, pExpr->u.zToken);
                             pExpr->pAggInfo ? pExpr->pAggInfo->selId : 0,
                             pExpr->iAgg, pExpr->pAggInfo);
      }else if( pExpr->op2!=0 ){
        const char *zOp2;
        char zBuf[8];
        sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2);
        zOp2 = zBuf;
        if( pExpr->op2==NC_IsCheck ) zOp2 = "NC_IsCheck";
        if( pExpr->op2==NC_IdxExpr ) zOp2 = "NC_IdxExpr";
        if( pExpr->op2==NC_PartIdx ) zOp2 = "NC_PartIdx";
        if( pExpr->op2==NC_GenCol ) zOp2 = "NC_GenCol";
        sqlite3TreeViewLine(pView, "FUNCTION %Q%s op2=%s",
                            pExpr->u.zToken, zFlgs, zOp2);
      }else{
        sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs);
        sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
      }
      if( pFarg ){
        sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0);
      }
#ifndef SQLITE_OMIT_WINDOWFUNC
      if( pWin ){
        sqlite3TreeViewWindow(pView, pWin, 0);
      }
#endif
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS: {
      sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags);
      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
      break;
    }
    case TK_SELECT: {
      sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags);
      sqlite3TreeViewLine(pView, "SELECT-expr flags=0x%x", pExpr->flags);
      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
      break;
    }
    case TK_IN: {
      sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
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
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







-
+
















-
-
+
-







      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
      sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      const char *zType = "unk";
      switch( pExpr->affExpr ){
      switch( pExpr->affinity ){
        case OE_Rollback:   zType = "rollback";  break;
        case OE_Abort:      zType = "abort";     break;
        case OE_Fail:       zType = "fail";      break;
        case OE_Ignore:     zType = "ignore";    break;
      }
      sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
      break;
    }
#endif
    case TK_MATCH: {
      sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s",
                          pExpr->iTable, pExpr->iColumn, zFlgs);
      sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
      break;
    }
    case TK_VECTOR: {
      char *z = sqlite3_mprintf("VECTOR%s",zFlgs);
      sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z);
      sqlite3TreeViewBareExprList(pView, pExpr->x.pList, "VECTOR");
      sqlite3_free(z);
      break;
    }
    case TK_SELECT_COLUMN: {
      sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn);
      sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
      break;
    }
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
665
666
667
668
669
670
671

672
673
674
675
676
677
678
679







-
+







  }
  if( zBinOp ){
    sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs);
    sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
    sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
  }else if( zUniOp ){
    sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
   sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
    sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
  }
  sqlite3TreeViewPop(pView);
}


/*
** Generate a human-readable explanation of an expression list.
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
757
758
687
688
689
690
691
692
693

694
695

696
697
698
699
700
701
702







-
+

-







  if( pList==0 ){
    sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
  }else{
    int i;
    sqlite3TreeViewLine(pView, "%s", zLabel);
    for(i=0; i<pList->nExpr; i++){
      int j = pList->a[i].u.x.iOrderByCol;
      char *zName = pList->a[i].zEName;
      char *zName = pList->a[i].zName;
      int moreToFollow = i<pList->nExpr - 1;
      if( pList->a[i].eEName!=ENAME_NAME ) zName = 0;
      if( j || zName ){
        sqlite3TreeViewPush(pView, moreToFollow);
        moreToFollow = 0;
        sqlite3TreeViewLine(pView, 0);
        if( zName ){
          fprintf(stdout, "AS %s ", zName);
        }

Changes to src/trigger.c.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
22
23
24
25
26
27
28

29
30
31
32
33
34
35







-







    pTriggerStep = pTriggerStep->pNext;

    sqlite3ExprDelete(db, pTmp->pWhere);
    sqlite3ExprListDelete(db, pTmp->pExprList);
    sqlite3SelectDelete(db, pTmp->pSelect);
    sqlite3IdListDelete(db, pTmp->pIdList);
    sqlite3UpsertDelete(db, pTmp->pUpsert);
    sqlite3SrcListDelete(db, pTmp->pFrom);
    sqlite3DbFree(db, pTmp->zSpan);

    sqlite3DbFree(db, pTmp);
  }
}

/*
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
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







-
-
+
+
-




-
-
-
-
-
+
-

-
+
+
+


-
+

-
+

-
-
-
-
-
-
-
-
+
-


+
-
+







** 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 */
  Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
  Trigger *pList = 0;                  /* 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 ){
    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)
       && 0==sqlite3StrICmp(pTrig->table, pTab->zName) 
      ){
        pTrig->pNext = pList;
        pTrig->pNext = (pList ? pList : pTab->pTrigger);
        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;  
  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
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138







-
+








  /* A long-standing parser bug is that this syntax was allowed:
  **
  **    CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab ....
  **                                                 ^^^^^^^^
  **
  ** To maintain backwards compatibility, ignore the database
  ** name on pTableName if we are reparsing out of the schema table
  ** name on pTableName if we are reparsing out of SQLITE_MASTER.
  */
  if( db->init.busy && iDb!=1 ){
    sqlite3DbFree(db, pTableName->a[0].zDatabase);
    pTableName->a[0].zDatabase = 0;
  }

  /* If the trigger name was unqualified, and the table is a temp table,
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
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







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



-
+





-
-
-
-
-
+







  sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName);
  if( sqlite3FixSrcList(&sFix, pTableName) ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( !pTab ){
    /* The table does not exist. */
    if( db->init.iDb==1 ){
      /* Ticket #3810.
      ** Normally, whenever a table is dropped, all associated triggers are
      ** dropped too.  But if a TEMP trigger is created on a non-TEMP table
      ** and the table is dropped by a different database connection, the
      ** trigger is not visible to the database connection that does the
      ** drop so the trigger cannot be dropped.  This results in an
      ** "orphaned trigger" - a trigger whose associated table is missing.
      */
      db->init.orphanTrigger = 1;
    }
    goto trigger_orphan_error;
    goto trigger_cleanup;
  }
  if( IsVirtual(pTab) ){
    sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables");
    goto trigger_orphan_error;
    goto trigger_cleanup;
  }

  /* Check that the trigger name is not reserved and that no trigger of the
  ** specified name exists */
  zName = sqlite3NameFromToken(db, pName);
  if( zName==0 ){
    assert( db->mallocFailed );
    goto trigger_cleanup;
  }
  if( sqlite3CheckObjectName(pParse, zName, "trigger", pTab->zName) ){
  if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto trigger_cleanup;
  }
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  if( !IN_RENAME_OBJECT ){
    if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
      if( !noErr ){
        sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
206
207
208
209
210
211
212
213

214
215
216
217
218

219
220
221
222
223
224
225
201
202
203
204
205
206
207

208
209
210
211
212

213
214
215
216
217
218
219
220







-
+




-
+








  /* INSTEAD of triggers are only for views and views only support INSTEAD
  ** of triggers.
  */
  if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
    sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", 
        (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
    goto trigger_orphan_error;
    goto trigger_cleanup;
  }
  if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
    sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
        " trigger on table: %S", pTableName, 0);
    goto trigger_orphan_error;
    goto trigger_cleanup;
  }

#ifndef SQLITE_OMIT_AUTHORIZATION
  if( !IN_RENAME_OBJECT ){
    int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    int code = SQLITE_CREATE_TRIGGER;
    const char *zDb = db->aDb[iTabDb].zDbSName;
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
266
267
268
269
270
271
272

















273
274
275
276
277
278
279







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







  sqlite3IdListDelete(db, pColumns);
  sqlite3ExprDelete(db, pWhen);
  if( !pParse->pNewTrigger ){
    sqlite3DeleteTrigger(db, pTrigger);
  }else{
    assert( pParse->pNewTrigger==pTrigger );
  }
  return;

trigger_orphan_error:
  if( db->init.iDb==1 ){
    /* Ticket #3810.
    ** Normally, whenever a table is dropped, all associated triggers are
    ** dropped too.  But if a TEMP trigger is created on a non-TEMP table
    ** and the table is dropped by a different database connection, the
    ** trigger is not visible to the database connection that does the
    ** drop so the trigger cannot be dropped.  This results in an
    ** "orphaned trigger" - a trigger whose associated table is missing.
    **
    ** 2020-11-05 see also https://sqlite.org/forum/forumpost/157dc791df
    */
    db->init.orphanTrigger = 1;
  }
  goto trigger_cleanup;
}

/*
** This routine is called after all of the trigger actions have been parsed
** in order to complete the process of building the trigger.
*/
void sqlite3FinishTrigger(
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
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







-
+





-
+






-
-
-
+
+




-
+






-







    assert( !db->init.busy );
    pParse->pNewTrigger = pTrig;
    pTrig = 0;
  }else
#endif

  /* if we are not initializing,
  ** build the sqlite_schema entry
  ** build the sqlite_master entry
  */
  if( !db->init.busy ){
    Vdbe *v;
    char *z;

    /* Make an entry in the sqlite_schema table */
    /* Make an entry in the sqlite_master table */
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
    testcase( z==0 );
    sqlite3NestedParse(pParse,
       "INSERT INTO %Q." DFLT_SCHEMA_TABLE
       " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
       db->aDb[iDb].zDbSName, zName,
       "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
       db->aDb[iDb].zDbSName, MASTER_NAME, zName,
       pTrig->table, z);
    sqlite3DbFree(db, z);
    sqlite3ChangeCookie(pParse, iDb);
    sqlite3VdbeAddParseSchemaOp(v, iDb,
        sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName), 0);
        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 );
    pTrig = sqlite3HashInsert(pHash, zName, pTrig);
    if( pTrig ){
      sqlite3OomFault(db);
    }else if( pLink->pSchema==pLink->pTabSchema ){
      Table *pTab;
      pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table);
      assert( pTab!=0 );
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
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







-
-
-



















-














-


-



-





-







      pSelect = 0;
    }else{
      pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
    }
    pTriggerStep->pIdList = pColumn;
    pTriggerStep->pUpsert = pUpsert;
    pTriggerStep->orconf = orconf;
    if( pUpsert ){
      sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget);
    }
  }else{
    testcase( pColumn );
    sqlite3IdListDelete(db, pColumn);
    testcase( pUpsert );
    sqlite3UpsertDelete(db, pUpsert);
  }
  sqlite3SelectDelete(db, pSelect);

  return pTriggerStep;
}

/*
** Construct a trigger step that implements an UPDATE statement and return
** a pointer to that trigger step.  The parser calls this routine when it
** sees an UPDATE statement inside the body of a CREATE TRIGGER.
*/
TriggerStep *sqlite3TriggerUpdateStep(
  Parse *pParse,          /* Parser */
  Token *pTableName,   /* Name of the table to be updated */
  SrcList *pFrom,
  ExprList *pEList,    /* The SET clause: list of column and new values */
  Expr *pWhere,        /* The WHERE clause */
  u8 orconf,           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
  const char *zStart,  /* Start of SQL text */
  const char *zEnd     /* End of SQL text */
){
  sqlite3 *db = pParse->db;
  TriggerStep *pTriggerStep;

  pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd);
  if( pTriggerStep ){
    if( IN_RENAME_OBJECT ){
      pTriggerStep->pExprList = pEList;
      pTriggerStep->pWhere = pWhere;
      pTriggerStep->pFrom = pFrom;
      pEList = 0;
      pWhere = 0;
      pFrom = 0;
    }else{
      pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
      pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
      pTriggerStep->pFrom = sqlite3SrcListDup(db, pFrom, EXPRDUP_REDUCE);
    }
    pTriggerStep->orconf = orconf;
  }
  sqlite3ExprListDelete(db, pEList);
  sqlite3ExprDelete(db, pWhere);
  sqlite3SrcListDelete(db, pFrom);
  return pTriggerStep;
}

/*
** Construct a trigger step that implements a DELETE statement and return
** a pointer to that trigger step.  The parser calls this routine when it
** sees a DELETE statement inside the body of a CREATE TRIGGER.
565
566
567
568
569
570
571
572

573
574
575
576
577
578
579
533
534
535
536
537
538
539

540
541
542
543
544
545
546
547







-
+







  return pTriggerStep;
}

/* 
** Recursively delete a Trigger structure
*/
void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
  if( pTrigger==0 || pTrigger->bReturning ) return;
  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);
}
600
601
602
603
604
605
606
607

608
609
610
611
612
613
614
568
569
570
571
572
573
574

575
576
577
578
579
580
581
582







-
+








  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;
  assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
  for(i=OMIT_TEMPDB; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
    if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue;
    assert( sqlite3SchemaMutexHeld(db, j, 0) );
    pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    if( !noErr ){
      sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
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
609
610
611
612
613
614
615
616

617
618

619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635


636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656



657
658


659




660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
686







+
-
+

-
+













+


-
-
+
+



















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



















-
+







  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
  assert( iDb>=0 && iDb<db->nDb );
  pTable = tableOfTrigger(pTrigger);
  assert( pTable );
  assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 );
  assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( pTable ){
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[iDb].zDbSName;
    const char *zTab = SCHEMA_TABLE(iDb);
    if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
      sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      return;
    }
  }
#endif

  /* Generate code to destroy the database record of the trigger.
  */
  assert( pTable!=0 );
  if( (v = sqlite3GetVdbe(pParse))!=0 ){
    sqlite3NestedParse(pParse,
       "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
       db->aDb[iDb].zDbSName, pTrigger->zName
       "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
       db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName
    );
    sqlite3ChangeCookie(pParse, iDb);
    sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
  }
}

/*
** Remove a trigger from the hash tables of the sqlite* pointer.
*/
void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
  Trigger *pTrigger;
  Hash *pHash;

  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  pHash = &(db->aDb[iDb].pSchema->trigHash);
  pTrigger = sqlite3HashInsert(pHash, zName, 0);
  if( ALWAYS(pTrigger) ){
    if( pTrigger->pSchema==pTrigger->pTabSchema ){
      Table *pTab = tableOfTrigger(pTrigger);
      if( pTab ){
        Trigger **pp;
        for(pp=&pTab->pTrigger; *pp; pp=&((*pp)->pNext)){
      Trigger **pp;
      for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
          if( *pp==pTrigger ){
            *pp = (*pp)->pNext;
      *pp = (*pp)->pNext;
            break;
          }
        }
      }
    }
    sqlite3DeleteTrigger(db, pTrigger);
    db->mDbFlags |= DBFLAG_SchemaChange;
  }
}

/*
** pEList is the SET clause of an UPDATE statement.  Each entry
** in pEList is of the format <id>=<expr>.  If any of the entries
** in pEList have an <id> which matches an identifier in pIdList,
** then return TRUE.  If pIdList==NULL, then it is considered a
** wildcard that matches anything.  Likewise if pEList==NULL then
** it matches anything so always return true.  Return false only
** if there is no match.
*/
static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){
  int e;
  if( pIdList==0 || NEVER(pEList==0) ) return 1;
  for(e=0; e<pEList->nExpr; e++){
    if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1;
    if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
  }
  return 0; 
}

/*
** Return a list of all triggers on table pTab if there exists at least
** one trigger that must be fired when an operation of type 'op' is 
730
731
732
733
734
735
736
737
738
739
740
741
742

743
744
745
746
747
748
749

750
751

752
753


754
755
756
757
758


759
760
761
762
763
764
765
766
767
768
769

770
771
772
773

774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800

801
802
803
804

805
806


807
808
809
810


811

812
813
814


815
816
817



818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
694
695
696
697
698
699
700






701







702


703


704
705





706
707











708




709










710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

726
727
728
729
730
731


732
733
734


735
736
737

738



739
740



741
742
743

744


745
746
747





























































































































748
749
750
751
752
753
754







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
















-
+




+
-
-
+
+

-
-

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

-
-



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







  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
  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;
    pList = sqlite3TriggerList(pParse, pTab);
        goto exit_triggers_exist;
      }
  }
      while( ALWAYS(p->pNext) && p->pNext!=pTab->pTrigger ) p = p->pNext;
      p->pNext = 0;
  assert( pList==0 || IsVirtual(pTab)==0 );
  for(p=pList; p; p=p->pNext){
      p = pList;
    }
    do{
      if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
        mask |= p->tr_tm;
    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);
}

/*
** Convert the pStep->zTarget string into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
** forming the SrcList.  This prevents a trigger in one database from
** referring to a target in another database.  An exception is when the
** trigger is in TEMP in which case it can refer to any other database it
** wants.
*/
SrcList *sqlite3TriggerStepSrc(
static SrcList *targetSrcList(
  Parse *pParse,       /* The parsing context */
  TriggerStep *pStep   /* The trigger containing the target token */
){
  sqlite3 *db = pParse->db;
  int iDb;             /* Index of the database to use */
  SrcList *pSrc;                  /* SrcList to be returned */
  char *zName = sqlite3DbStrDup(db, pStep->zTarget);
  SrcList *pSrc;       /* SrcList to be returned */

  pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
  assert( pSrc==0 || pSrc->nSrc==1 );
  assert( zName || pSrc==0 );
  if( pSrc ){
    assert( pSrc->nSrc>0 );
    pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
    Schema *pSchema = pStep->pTrig->pSchema;
    iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
    pSrc->a[0].zName = zName;
    if( pSchema!=db->aDb[1].pSchema ){
      pSrc->a[0].pSchema = pSchema;
    if( iDb==0 || iDb>=2 ){
      const char *zDb;
    }
    if( pStep->pFrom ){
      SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
      assert( iDb<db->nDb );
      zDb = db->aDb[iDb].zDbSName;
      pSrc->a[pSrc->nSrc-1].zDatabase =  sqlite3DbStrDup(db, zDb);
      pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup);
    }
  }else{
    sqlite3DbFree(db, zName);
  }
  return pSrc;
}

/*
** Return true if the pExpr term from the RETURNING clause argument
** list is of the form "*".  Raise an error if the terms if of the
** form "table.*".
*/
static int isAsteriskTerm(
  Parse *pParse,      /* Parsing context */
  Expr *pTerm         /* A term in the RETURNING clause */
){
  assert( pTerm!=0 );
  if( pTerm->op==TK_ASTERISK ) return 1;
  if( pTerm->op!=TK_DOT ) return 0;
  assert( pTerm->pRight!=0 );
  assert( pTerm->pLeft!=0 );
  if( pTerm->pRight->op!=TK_ASTERISK ) return 0;
  sqlite3ErrorMsg(pParse, "RETURNING may not use \"TABLE.*\" wildcards");
  return 1;
}

/* 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( NEVER(pOldExpr==0) ) continue;
    if( isAsteriskTerm(pParse, pOldExpr) ){
      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 */
988
989
990
991
992
993
994
995

996
997
998
999
1000
1001
1002
1003
1004
1005

1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016

1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030



1031
1032
1033
1034
1035
1036
1037
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







-
+




-




-
+





-




-
+


-











+
+
+







                        P4_DYNAMIC);
    }
#endif

    switch( pStep->op ){
      case TK_UPDATE: {
        sqlite3Update(pParse, 
          sqlite3TriggerStepSrc(pParse, pStep),
          targetSrcList(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),
          targetSrcList(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),
          targetSrcList(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;
      }
    } 
    if( pStep->op!=TK_SELECT ){
      sqlite3VdbeAddOp0(v, OP_ResetCount);
    }
  }

  return 0;
}

#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
1170
1171
1172
1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982







+







    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;
}
    
1271
1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283
1284
1285
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
1084







-
+







**   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+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
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
1115
1116
1117
1118
1119
1120
1121

1122





1123
1124
1125
1126


1127



1128
1129
1130
1131
1132
1133
1134







-
+
-
-
-
-
-
+



-
-
+
-
-
-







    ** 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:
    /* Determine whether we should code this trigger */
    **   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))
    if( p->op==op 
     && p->tr_tm==tr_tm 
     && checkColumnOverlap(p->pColumns, pChanges)
    ){
      if( !p->bReturning ){
        sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump);
      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 
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
1165
1166
1167
1168
1169
1170
1171

1172

1173
1174







1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
1186







-
+
-


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








){
  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
    if( p->op==op && (tr_tm&p->tr_tm)
     && (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];
      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.

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







-
+






-
-
-
-
+
+
+
+
















-
+







** If the former, then all row-records are guaranteed to include a value
** for the column and the P4 value is not required.
**
** Column definitions created by an ALTER TABLE command may only have 
** literal default values specified: a number, null or a string. (If a more
** complicated default expression value was provided, it is evaluated 
** when the ALTER TABLE is executed and one of the literal values written
** into the sqlite_schema table.)
** into the sqlite_master table.)
**
** Therefore, the P4 parameter is only required if the default value for
** the column is a literal number, string or null. The sqlite3ValueFromExpr()
** function is capable of transforming these types of expressions into
** sqlite3_value objects.
**
** If column as REAL affinity and the table is an ordinary b-tree table
** (not a virtual table) then the value might have been stored as an
** integer.  In that case, add an OP_RealAffinity opcode to make sure
** it has been converted into REAL.
** If parameter iReg is not negative, code an OP_RealAffinity instruction
** on register iReg. This is used when an equivalent integer value is 
** stored in place of an 8-byte floating point value in order to save 
** space.
*/
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
  assert( pTab!=0 );
  if( !pTab->pSelect ){
    sqlite3_value *pValue = 0;
    u8 enc = ENC(sqlite3VdbeDb(v));
    Column *pCol = &pTab->aCol[i];
    VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
    assert( i<pTab->nCol );
    sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, 
                         pCol->affinity, &pValue);
    if( pValue ){
      sqlite3VdbeAppendP4(v, pValue, P4_MEM);
    }
  }
#ifndef SQLITE_OMIT_FLOATING_POINT
  if( pTab->aCol[i].affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){
  if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
    sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
  }
#endif
}

/*
** Check to see if column iCol of index pIdx references any of the
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
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








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


-
-
+
+
-
-
-
+











-
+


-
+




-




-
+








-







  int chngRowid     /* true if the rowid is being updated */
){
  if( pIdx->pPartIdxWhere==0 ) return 0;
  return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
                                            aXRef, chngRowid);
}

/*
** Allocate and return a pointer to an expression of type TK_ROW with
** Expr.iColumn set to value (iCol+1). The resolver will modify the
** expression to be a TK_COLUMN reading column iCol of the first
** table in the source-list (pSrc->a[0]).
*/
static Expr *exprRowColumn(Parse *pParse, int iCol){
  Expr *pRet = sqlite3PExpr(pParse, TK_ROW, 0, 0);
  if( pRet ) pRet->iColumn = iCol+1;
  return pRet;
}

/*
** Assuming both the pLimit and pOrderBy parameters are NULL, this function
** generates VM code to run the query:
**
**   SELECT <other-columns>, pChanges FROM pTabList WHERE pWhere 
**
** and write the results to the ephemeral table already opened as cursor 
** iEph. None of pChanges, pTabList or pWhere are modified or consumed by 
** this function, they must be deleted by the caller.
**
** Or, if pLimit and pOrderBy are not NULL, and pTab is not a view:
**
**   SELECT <other-columns>, pChanges FROM pTabList 
**   WHERE pWhere
**   GROUP BY <other-columns> 
**   ORDER BY pOrderBy LIMIT pLimit
**
** If pTab is a view, the GROUP BY clause is omitted.
**
** Exactly how results are written to table iEph, and exactly what
** the <other-columns> in the query above are is determined by the type
** of table pTabList->a[0].pTab.
**
** If the table is a WITHOUT ROWID table, then argument pPk must be its
** PRIMARY KEY. In this case <other-columns> are the primary key columns
** of the table, in order. The results of the query are written to ephemeral
** table iEph as index keys, using OP_IdxInsert.
**
** If the table is actually a view, then <other-columns> are all columns of
** the view. The results are written to the ephemeral table iEph as records
** with automatically assigned integer keys.
**
** If the table is a virtual or ordinary intkey table, then <other-columns> 
** is its rowid. For a virtual table, the results are written to iEph as
** records with automatically assigned integer keys For intkey tables, the
** rowid value in <other-columns> is used as the integer key, and the 
** remaining fields make up the table record. 
*/
static void updateFromSelect(
  Parse *pParse,                  /* Parse context */
  int iEph,                       /* Cursor for open eph. table */
  Index *pPk,                     /* PK if table 0 is WITHOUT ROWID */
  ExprList *pChanges,             /* List of expressions to return */
  SrcList *pTabList,              /* List of tables to select from */
  Expr *pWhere,                   /* WHERE clause for query */
  ExprList *pOrderBy,             /* ORDER BY clause */
  Expr *pLimit                    /* LIMIT clause */
){
  int i;
  SelectDest dest;
  Select *pSelect = 0;
  ExprList *pList = 0;
  ExprList *pGrp = 0;
  Expr *pLimit2 = 0;
  ExprList *pOrderBy2 = 0;
  sqlite3 *db = pParse->db;
  Table *pTab = pTabList->a[0].pTab;
  SrcList *pSrc;
  Expr *pWhere2;
  int eDest;

#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( pOrderBy && pLimit==0 ) {
    sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on UPDATE");
    return;
  }
  pOrderBy2 = sqlite3ExprListDup(db, pOrderBy, 0);
  pLimit2 = sqlite3ExprDup(db, pLimit, 0);
#else
  UNUSED_PARAMETER(pOrderBy);
  UNUSED_PARAMETER(pLimit);
#endif

  pSrc = sqlite3SrcListDup(db, pTabList, 0);
  pWhere2 = sqlite3ExprDup(db, pWhere, 0);

  assert( pTabList->nSrc>1 );
  if( pSrc ){
    pSrc->a[0].iCursor = -1;
    pSrc->a[0].pTab->nTabRef--;
    pSrc->a[0].pTab = 0;
  }
  if( pPk ){
    for(i=0; i<pPk->nKeyCol; i++){
      Expr *pNew = exprRowColumn(pParse, pPk->aiColumn[i]);
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
      if( pLimit ){
        pGrp = sqlite3ExprListAppend(pParse, pGrp, sqlite3ExprDup(db, pNew, 0));
      }
#endif
      pList = sqlite3ExprListAppend(pParse, pList, pNew);
    }
    eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom;
  }else if( pTab->pSelect ){
    for(i=0; i<pTab->nCol; i++){
      pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i));
    }
    eDest = SRT_Table;
  }else{
    eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom;
    pList = sqlite3ExprListAppend(pParse, 0, sqlite3PExpr(pParse,TK_ROW,0,0));
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
    if( pLimit ){
      pGrp = sqlite3ExprListAppend(pParse, 0, sqlite3PExpr(pParse,TK_ROW,0,0));
    }
#endif
  }
  if( ALWAYS(pChanges) ){
    for(i=0; i<pChanges->nExpr; i++){
      pList = sqlite3ExprListAppend(pParse, pList, 
          sqlite3ExprDup(db, pChanges->a[i].pExpr, 0)
      );
    }
  }
  pSelect = sqlite3SelectNew(pParse, pList, 
      pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UpdateFrom|SF_IncludeHidden, pLimit2
  );
  sqlite3SelectDestInit(&dest, eDest, iEph);
  dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1);
  sqlite3Select(pParse, pSelect, &dest);
  sqlite3SelectDelete(db, pSelect);
}

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE tbl SET a=b, c=d FROM tbl2... WHERE e<5 AND f NOT NULL;
**          \_______/ \_/     \______/      \_____/       \________________/
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
**          \_______/ \________/     \______/       \________________/
**           onError   |      pChanges         |                pWhere
**                     \_______________________/
**                               pTabList
*            onError   pTabList      pChanges             pWhere
*/
void sqlite3Update(
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table in which we should change things */
  ExprList *pChanges,    /* Things to be changed */
  Expr *pWhere,          /* The WHERE clause.  May be null */
  int onError,           /* How to handle constraint errors */
  ExprList *pOrderBy,    /* ORDER BY clause. May be null */
  Expr *pLimit,          /* LIMIT clause. May be null */
  Upsert *pUpsert        /* ON CONFLICT clause, or null */
){
  int i, j, k;           /* Loop counters */
  int i, j;              /* Loop counters */
  Table *pTab;           /* The table to be updated */
  int addrTop = 0;       /* VDBE instruction address of the start of the loop */
  WhereInfo *pWInfo = 0; /* Information about the WHERE clause */
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Vdbe *v;               /* The virtual database engine */
  Index *pIdx;           /* For looping over indices */
  Index *pPk;            /* The PRIMARY KEY index for WITHOUT ROWID tables */
  int nIdx;              /* Number of indices that need updating */
  int nAllIdx;           /* Total number of indexes */
  int iBaseCur;          /* Base cursor number */
  int iDataCur;          /* Cursor for the canonical data btree */
  int iIdxCur;           /* Cursor for the first index */
  sqlite3 *db;           /* The database structure */
  int *aRegIdx = 0;      /* Registers for to each index and the main table */
  int *aRegIdx = 0;      /* First register in array assigned to each index */
  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                         ** an expression for the i-th column of the table.
                         ** aXRef[i]==-1 if the i-th column is not changed. */
  u8 *aToOpen;           /* 1 for tables and indices to be opened */
  u8 chngPk;             /* PRIMARY KEY changed in a WITHOUT ROWID table */
  u8 chngRowid;          /* Rowid changed in a normal table */
  u8 chngKey;            /* Either chngPk or chngRowid */
  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
  int iRowidExpr = -1;   /* Index of "rowid=" (or IPK) assignment in pChanges */
  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */
  int iDb;               /* Database containing the table being updated */
  int eOnePass;          /* ONEPASS_XXX value from where.c */
  int hasFK;             /* True if foreign key processing is required */
  int labelBreak;        /* Jump here to break out of UPDATE loop */
  int labelContinue;     /* Jump here to continue next step of UPDATE loop */
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
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







-
-















+







  int iEph = 0;          /* Ephemeral table holding all primary key values */
  int nKey = 0;          /* Number of elements in regKey for WITHOUT ROWID */
  int aiCurOnePass[2];   /* The write cursors opened by WHERE_ONEPASS */
  int addrOpen = 0;      /* Address of OP_OpenEphemeral */
  int iPk = 0;           /* First of nPk cells holding PRIMARY KEY value */
  i16 nPk = 0;           /* Number of components of the PRIMARY KEY */
  int bReplace = 0;      /* True if REPLACE conflict resolution might happen */
  int bFinishSeek = 1;   /* The OP_FinishSeek opcode is needed */
  int nChangeFrom = 0;   /* If there is a FROM, pChanges->nExpr, else 0 */

  /* Register Allocations */
  int regRowCount = 0;   /* A count of rows changed */
  int regOldRowid = 0;   /* The old rowid */
  int regNewRowid = 0;   /* The new rowid */
  int regNew = 0;        /* Content of the NEW.* table in triggers */
  int regOld = 0;        /* Content of OLD.* table in triggers */
  int regRowSet = 0;     /* Rowset of rows to be updated */
  int regKey = 0;        /* composite PRIMARY KEY value */

  memset(&sContext, 0, sizeof(sContext));
  db = pParse->db;
  if( pParse->nErr || db->mallocFailed ){
    goto update_cleanup;
  }
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to update. 
  */
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ) goto update_cleanup;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
226
227
228
229
230
231
232







233

234
235
236
237
238
239
240
241







-
-
-
-
-
-
-

-
+







# define tmask 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  /* If there was a FROM clause, set nChangeFrom to the number of expressions
  ** in the change-list. Otherwise, set it to 0. There cannot be a FROM
  ** clause if this function is being called to generate code for part of
  ** an UPSERT statement.  */
  nChangeFrom = (pTabList->nSrc>1) ? pChanges->nExpr : 0;
  assert( nChangeFrom==0 || pUpsert==0 );

#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( !isView && nChangeFrom==0 ){
  if( !isView ){
    pWhere = sqlite3LimitWhere(
        pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE"
    );
    pOrderBy = 0;
    pLimit = 0;
  }
#endif
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
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







-
+


-
+











-
-
-
-








-
-
-
+



-
+



-



-
-
-
-
-
-
-
-
-
-





-
+



-

-
+







    pParse->nTab = iBaseCur;
  }
  pTabList->a[0].iCursor = iDataCur;

  /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].  
  ** Initialize aXRef[] and aToOpen[] to their default values.
  */
  aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 );
  aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
  if( aXRef==0 ) goto update_cleanup;
  aRegIdx = aXRef+pTab->nCol;
  aToOpen = (u8*)(aRegIdx+nIdx+1);
  aToOpen = (u8*)(aRegIdx+nIdx);
  memset(aToOpen, 1, nIdx+1);
  aToOpen[nIdx+1] = 0;
  for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;

  /* Initialize the name-context */
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pParse;
  sNC.pSrcList = pTabList;
  sNC.uNC.pUpsert = pUpsert;
  sNC.ncFlags = NC_UUpsert;

  /* Begin generating code. */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto update_cleanup;

  /* Resolve the column names in all the expressions of the
  ** of the UPDATE statement.  Also find the column index
  ** for each column to be updated in the pChanges array.  For each
  ** column to be updated, make sure we have authorization to change
  ** that column.
  */
  chngRowid = chngPk = 0;
  for(i=0; i<pChanges->nExpr; i++){
    /* If this is an UPDATE with a FROM clause, do not resolve expressions
    ** here. The call to sqlite3Select() below will do that. */
    if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
    if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
      goto update_cleanup;
    }
    for(j=0; j<pTab->nCol; j++){
      if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zEName)==0 ){
      if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
        if( j==pTab->iPKey ){
          chngRowid = 1;
          pRowidExpr = pChanges->a[i].pExpr;
          iRowidExpr = i;
        }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){
          chngPk = 1;
        }
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
        else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){
          testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL );
          testcase( pTab->aCol[j].colFlags & COLFLAG_STORED );
          sqlite3ErrorMsg(pParse, 
             "cannot UPDATE generated column \"%s\"",
             pTab->aCol[j].zName);
          goto update_cleanup;
        }
#endif
        aXRef[j] = i;
        break;
      }
    }
    if( j>=pTab->nCol ){
      if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zEName) ){
      if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){
        j = -1;
        chngRowid = 1;
        pRowidExpr = pChanges->a[i].pExpr;
        iRowidExpr = i;
      }else{
        sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zEName);
        sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
        pParse->checkSchema = 1;
        goto update_cleanup;
      }
    }
#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      int rc;
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
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







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














-
+



















-
-
+
+

-






+
+
+





-
-
-
-
-
-
-
+







#endif
  }
  assert( (chngRowid & chngPk)==0 );
  assert( chngRowid==0 || chngRowid==1 );
  assert( chngPk==0 || chngPk==1 );
  chngKey = chngRowid + chngPk;

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  /* Mark generated columns as changing if their generator expressions
  ** reference any changing column.  The actual aXRef[] value for 
  ** generated expressions is not used, other than to check to see that it
  ** is non-negative, so the value of aXRef[] for generated columns can be
  ** set to any non-negative number.  We use 99999 so that the value is
  ** obvious when looking at aXRef[] in a symbolic debugger. 
  */
  if( pTab->tabFlags & TF_HasGenerated ){
    int bProgress;
    testcase( pTab->tabFlags & TF_HasVirtual );
    testcase( pTab->tabFlags & TF_HasStored );
    do{
      bProgress = 0;
      for(i=0; i<pTab->nCol; i++){
        if( aXRef[i]>=0 ) continue;
        if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ) continue;
        if( sqlite3ExprReferencesUpdatedColumn(pTab->aCol[i].pDflt,
                                               aXRef, chngRowid) ){
          aXRef[i] = 99999;
          bProgress = 1;
        }
      }
    }while( bProgress );
  }
#endif

  /* The SET expressions are not actually used inside the WHERE loop.  
  ** So reset the colUsed mask. Unless this is a virtual table. In that
  ** case, set all bits of the colUsed mask (to ensure that the virtual
  ** table implementation makes all columns available).
  */
  pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0;

  hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);

  /* There is one entry in the aRegIdx[] array for each index on the table
  ** being updated.  Fill in aRegIdx[] with a register number that will hold
  ** the key for accessing each index.
  */
  if( onError==OE_Replace ) bReplace = 1;
  for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
  for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    int reg;
    if( chngKey || hasFK>1 || pIdx==pPk
     || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
    ){
      reg = ++pParse->nMem;
      pParse->nMem += pIdx->nColumn;
    }else{
      reg = 0;
      for(i=0; i<pIdx->nKeyCol; i++){
        if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
          reg = ++pParse->nMem;
          pParse->nMem += pIdx->nColumn;
          if( onError==OE_Default && pIdx->onError==OE_Replace ){
            bReplace = 1;
          }
          break;
        }
      }
    }
    if( reg==0 ) aToOpen[nAllIdx+1] = 0;
    aRegIdx[nAllIdx] = reg;
    if( reg==0 ) aToOpen[j+1] = 0;
    aRegIdx[j] = reg;
  }
  aRegIdx[nAllIdx] = ++pParse->nMem;  /* Register storing the table record */
  if( bReplace ){
    /* If REPLACE conflict resolution might be invoked, open cursors on all 
    ** indexes in case they are needed to delete records.  */
    memset(aToOpen, 1, nIdx+1);
  }

  /* Begin generating code. */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto update_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);

  /* Allocate required registers. */
  if( !IsVirtual(pTab) ){
    /* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
    ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
    ** reallocated.  aRegIdx[nAllIdx] is the register in which the main
    ** table record is written.  regRowSet holds the RowSet for the
    ** two-pass update algorithm. */
    assert( aRegIdx[nAllIdx]==pParse->nMem );
    regRowSet = aRegIdx[nAllIdx];
    regRowSet = ++pParse->nMem;
    regOldRowid = regNewRowid = ++pParse->nMem;
    if( chngPk || pTrigger || hasFK ){
      regOld = pParse->nMem + 1;
      pParse->nMem += pTab->nCol;
    }
    if( chngKey || pTrigger || hasFK ){
      regNewRowid = ++pParse->nMem;
606
607
608
609
610
611
612
613

614
615
616
617
618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653

654
655
656
657
658
659


660
661
662
663
664
665
666
667
668


669
670

671
672
673
674
675


676
677
678
679
680
681
682
683

684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701









702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728


























729
730
731
732
733
734
735
736
737
738
739
740











741
742
743
744
745
746
747






748
749

750
751
752
753
754
755
756
757
758
759
760
761










762
763
764
765
766
767
768
769
770
771
772
773
774












775
776
777

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

796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836



837
838
839
840
841


842
843
844
845
846
847
848
849
850
851
852
853
854
855
856

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

876
877
878

879
880

881
882
883
884
885
886
887
410
411
412
413
414
415
416

417
418
419
420
421
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452
453
454
455

456
457


458


459
460
461
462

463
464

465


466
467


468





469
470








471


















472
473
474
475
476
477
478
479
480



























481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506












507
508
509
510
511
512
513
514
515
516
517
518






519
520
521
522
523
524


525












526
527
528
529
530
531
532
533
534
535













536
537
538
539
540
541
542
543
544
545
546
547

548

549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

567


568
569
570
571
572
573
574
575
576
577
578
579
580
581
582

583
584
585





















586
587
588

589



590
591
592
593
594
595
596
597
598
599
600
601
602
603



604



605
606
607
608
609
610
611
612
613
614
615


616
617

618
619
620

621
622

623
624
625
626
627
628
629
630







-
+











-
+




















-






-
+

-
-

-
-
+
+


-


-

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

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

-
+

















-
+
-
-















-
+


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

-
-
-
+
+












-
-
-
+
-
-
-











-
-


-
+


-
+

-
+







    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
  }

  /* If we are trying to update a view, realize that view into
  ** an ephemeral table.
  */
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
  if( nChangeFrom==0 && isView ){
  if( isView ){
    sqlite3MaterializeView(pParse, pTab, 
        pWhere, pOrderBy, pLimit, iDataCur
    );
    pOrderBy = 0;
    pLimit = 0;
  }
#endif

  /* Resolve the column names in all the expressions in the
  ** WHERE clause.
  */
  if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pWhere) ){
  if( sqlite3ResolveExprNames(&sNC, pWhere) ){
    goto update_cleanup;
  }

#ifndef SQLITE_OMIT_VIRTUALTABLE
  /* Virtual tables must be handled separately */
  if( IsVirtual(pTab) ){
    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
                       pWhere, onError);
    goto update_cleanup;
  }
#endif

  /* Jump to labelBreak to abandon further processing of this UPDATE */
  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) ){
  if( HasRowid(pTab) ){
    sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
    iEph = pParse->nTab++;
    addrOpen = sqlite3VdbeAddOp3(v, OP_OpenEphemeral, iEph, 0, regRowSet);
  }else{
    assert( pPk!=0 || HasRowid(pTab) );
    nPk = pPk ? pPk->nKeyCol : 0;
    assert( pPk!=0 );
    nPk = pPk->nKeyCol;
    iPk = pParse->nMem+1;
    pParse->nMem += nPk;
    pParse->nMem += nChangeFrom;
    regKey = ++pParse->nMem;
    if( pUpsert==0 ){
      int nEphCol = nPk + nChangeFrom + (isView ? pTab->nCol : 0);
      iEph = pParse->nTab++;
      if( pPk ) sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1);
      addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nEphCol);
        sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1);
      addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
      if( pPk ){
        KeyInfo *pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pPk);
      sqlite3VdbeSetP4KeyInfo(pParse, pPk);
        if( pKeyInfo ){
          pKeyInfo->nAllField = nEphCol;
          sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
        }
      }
    }
  }
      if( nChangeFrom ){
        updateFromSelect(
            pParse, iEph, pPk, pChanges, pTabList, pWhere, pOrderBy, pLimit
        );
#ifndef SQLITE_OMIT_SUBQUERY
        if( isView ) iDataCur = iEph;
#endif
      }
  
    }
  }
  
  if( nChangeFrom ){
    sqlite3MultiWrite(pParse);
    eOnePass = ONEPASS_OFF;
    nKey = nPk;
    regKey = iPk;
  }else{
    if( pUpsert ){
      /* If this is an UPSERT, then all cursors have already been opened by
      ** the outer INSERT and the data cursor should be pointing at the row
      ** that is to be updated.  So bypass the code that searches for the
      ** row(s) to be updated.
      */
      pWInfo = 0;
      eOnePass = ONEPASS_SINGLE;
      sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL);
  if( pUpsert ){
    /* If this is an UPSERT, then all cursors have already been opened by
    ** the outer INSERT and the data cursor should be pointing at the row
    ** that is to be updated.  So bypass the code that searches for the
    ** row(s) to be updated.
    */
    pWInfo = 0;
    eOnePass = ONEPASS_SINGLE;
    sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL);
      bFinishSeek = 0;
    }else{
      /* Begin the database scan. 
      **
      ** Do not consider a single-pass strategy for a multi-row update if
      ** there are any triggers or foreign keys to process, or rows may
      ** be deleted as a result of REPLACE conflict handling. Any of these
      ** things might disturb a cursor being used to scan through the table
      ** or index, causing a single-pass approach to malfunction.  */
      flags = WHERE_ONEPASS_DESIRED;
      if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
        flags |= WHERE_ONEPASS_MULTIROW;
      }
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags,iIdxCur);
      if( pWInfo==0 ) goto update_cleanup;

      /* A one-pass strategy that might update more than one row may not
      ** be used if any column of the index used for the scan is being
      ** updated. Otherwise, if there is an index on "b", statements like
      ** the following could create an infinite loop:
      **
      **   UPDATE t1 SET b=b+1 WHERE b>?
      **
      ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
      ** strategy that uses an index for which one or more columns are being
      ** updated.  */
      eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
  }else{
    /* Begin the database scan. 
    **
    ** Do not consider a single-pass strategy for a multi-row update if
    ** there are any triggers or foreign keys to process, or rows may
    ** be deleted as a result of REPLACE conflict handling. Any of these
    ** things might disturb a cursor being used to scan through the table
    ** or index, causing a single-pass approach to malfunction.  */
    flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
    if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
      flags |= WHERE_ONEPASS_MULTIROW;
    }
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
    if( pWInfo==0 ) goto update_cleanup;
  
    /* A one-pass strategy that might update more than one row may not
    ** be used if any column of the index used for the scan is being
    ** updated. Otherwise, if there is an index on "b", statements like
    ** the following could create an infinite loop:
    **
    **   UPDATE t1 SET b=b+1 WHERE b>?
    **
    ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
    ** strategy that uses an index for which one or more columns are being
    ** updated.  */
    eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
      bFinishSeek = sqlite3WhereUsesDeferredSeek(pWInfo);
      if( eOnePass!=ONEPASS_SINGLE ){
        sqlite3MultiWrite(pParse);
        if( eOnePass==ONEPASS_MULTI ){
          int iCur = aiCurOnePass[1];
          if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
            eOnePass = ONEPASS_OFF;
          }
          assert( iCur!=iDataCur || !HasRowid(pTab) );
        }
      }
    }
    if( eOnePass!=ONEPASS_SINGLE ){
      sqlite3MultiWrite(pParse);
      if( eOnePass==ONEPASS_MULTI ){
        int iCur = aiCurOnePass[1];
        if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
          eOnePass = ONEPASS_OFF;
        }
        assert( iCur!=iDataCur || !HasRowid(pTab) );
      }
    }
  }

    if( HasRowid(pTab) ){
      /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
      ** mode, write the rowid into the FIFO. In either of the one-pass modes,
      ** leave it in register regOldRowid.  */
      sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
      if( eOnePass==ONEPASS_OFF ){
  if( HasRowid(pTab) ){
    /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
    ** mode, write the rowid into the FIFO. In either of the one-pass modes,
    ** leave it in register regOldRowid.  */
    sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
    if( eOnePass==ONEPASS_OFF ){
        aRegIdx[nAllIdx] = ++pParse->nMem;
        sqlite3VdbeAddOp3(v, OP_Insert, iEph, regRowSet, regOldRowid);
      sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
      }else{
        if( ALWAYS(addrOpen) ) sqlite3VdbeChangeToNoop(v, addrOpen);
      }
    }else{
      /* Read the PK of the current row into an array of registers. In
      ** ONEPASS_OFF mode, serialize the array into a record and store it in
      ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change
      ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table 
      ** is not required) and leave the PK fields in the array of registers.  */
      for(i=0; i<nPk; i++){
        assert( pPk->aiColumn[i]>=0 );
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,
    }
  }else{
    /* Read the PK of the current row into an array of registers. In
    ** ONEPASS_OFF mode, serialize the array into a record and store it in
    ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change
    ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table 
    ** is not required) and leave the PK fields in the array of registers.  */
    for(i=0; i<nPk; i++){
      assert( pPk->aiColumn[i]>=0 );
      sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i);
                                        pPk->aiColumn[i], iPk+i);
      }
      if( eOnePass ){
        if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen);
        nKey = nPk;
        regKey = iPk;
      }else{
        sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
                          sqlite3IndexAffinityStr(db, pPk), nPk);
        sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk);
      }
    }
  }
    }
    if( eOnePass ){
      if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen);
      nKey = nPk;
      regKey = iPk;
    }else{
      sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
                        sqlite3IndexAffinityStr(db, pPk), nPk);
      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk);
    }
  }


  if( pUpsert==0 ){
    if( nChangeFrom==0 && eOnePass!=ONEPASS_MULTI ){
    if( eOnePass!=ONEPASS_MULTI ){
      sqlite3WhereEnd(pWInfo);
    }
  
    if( !isView ){
      int addrOnce = 0;
  
      /* Open every index that needs updating. */
      if( eOnePass!=ONEPASS_OFF ){
        if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
        if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
      }
  
      if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
        addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
      }
      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur,
                                 aToOpen, 0, 0);
      if( addrOnce ){
      if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
        sqlite3VdbeJumpHereOrPopInst(v, addrOnce);
      }
    }
  
    /* Top of the update loop */
    if( eOnePass!=ONEPASS_OFF ){
      if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
        assert( pPk );
        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey);
        VdbeCoverage(v);
      }
      if( eOnePass!=ONEPASS_SINGLE ){
        labelContinue = sqlite3VdbeMakeLabel(pParse);
      }
      sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
      VdbeCoverageIf(v, pPk==0);
      VdbeCoverageIf(v, pPk!=0);
    }else if( pPk || nChangeFrom ){
    }else if( pPk ){
      labelContinue = sqlite3VdbeMakeLabel(pParse);
      sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
      addrTop = sqlite3VdbeCurrentAddr(v);
      if( nChangeFrom ){
        if( !isView ){
          if( pPk ){
            for(i=0; i<nPk; i++){
              sqlite3VdbeAddOp3(v, OP_Column, iEph, i, iPk+i);
            }
            sqlite3VdbeAddOp4Int(
                v, OP_NotFound, iDataCur, labelContinue, iPk, nPk
            ); VdbeCoverage(v);
          }else{
            sqlite3VdbeAddOp2(v, OP_Rowid, iEph, regOldRowid);
            sqlite3VdbeAddOp3(
                v, OP_NotExists, iDataCur, labelContinue, regOldRowid
            ); VdbeCoverage(v);
          }
        }
      }else{
        sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey,0);
        VdbeCoverage(v);
      addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
      VdbeCoverage(v);
      }
    }else{
      sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
      labelContinue = sqlite3VdbeMakeLabel(pParse);
      addrTop = sqlite3VdbeAddOp2(v, OP_Rowid, iEph, regOldRowid);
      labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak,
                               regOldRowid);
      VdbeCoverage(v);
      sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
      VdbeCoverage(v);
    }
  }

  /* If the rowid value will change, set register regNewRowid to
  ** contain the new value. If the rowid is not being modified,
  ** then regNewRowid is the same register as regOldRowid, which is
  ** already populated.  */
  assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
  if( chngRowid ){
    assert( iRowidExpr>=0 );
    if( nChangeFrom==0 ){
      sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
    sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
    }else{
      sqlite3VdbeAddOp3(v, OP_Column, iEph, iRowidExpr, regNewRowid);
    }
    sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v);
  }

  /* Compute the old pre-UPDATE content of the row being changed, if that
  ** information is needed */
  if( chngPk || hasFK || pTrigger ){
    u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0);
    oldmask |= sqlite3TriggerColmask(pParse, 
        pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
    );
    for(i=0; i<pTab->nCol; i++){
      u32 colFlags = pTab->aCol[i].colFlags;
      k = sqlite3TableColumnToStorage(pTab, i) + regOld;
      if( oldmask==0xffffffff
       || (i<32 && (oldmask & MASKBIT32(i))!=0)
       || (colFlags & COLFLAG_PRIMKEY)!=0
       || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
      ){
        testcase(  oldmask!=0xffffffff && i==31 );
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k);
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, k);
        sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
      }
    }
    if( chngRowid==0 && pPk==0 ){
      sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
    }
  }

897
898
899
900
901
902
903
904

905
906

907
908
909
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925
926
927

928
929
930

931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963













964
965
966
967
968
969
970
971
972
973
974










975
976
977
978
979
980




981
982
983
984
985
986

987
988

989
990
991


992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015


1016
1017




1018
1019
1020
1021
1022
1023
1024

1025

1026
1027
1028
1029
1030
1031
1032
640
641
642
643
644
645
646

647
648

649


650
651
652






653

654
655
656
657
658
659
660
661

662

663

664
665
666
667







668
669
670
671
672
673
674
675
676














677
678
679
680
681
682
683
684
685
686
687
688
689
690










691
692
693
694
695
696
697
698
699
700






701
702
703
704






705


706


707
708
709
710
711
712
713
714
715












716
717
718
719
720
721
722
723


724
725
726
727







728
729
730
731
732
733
734
735
736
737







-
+

-
+
-
-



-
-
-
-
-
-
+
-








-
+
-

-
+



-
-
-
-
-
-
-









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

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

+
+






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






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

+







  ** the database after the BEFORE triggers are fired anyway (as the trigger 
  ** may have modified them). So not loading those that are not going to
  ** be used eliminates some redundant opcodes.
  */
  newmask = sqlite3TriggerColmask(
      pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
  );
  for(i=0, k=regNew; i<pTab->nCol; i++, k++){
  for(i=0; i<pTab->nCol; i++){
    if( i==pTab->iPKey ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, k);
      sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
    }else if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)!=0 ){
      if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--;
    }else{
      j = aXRef[i];
      if( j>=0 ){
        if( nChangeFrom ){
          int nOff = (isView ? pTab->nCol : nPk);
          assert( eOnePass==ONEPASS_OFF );
          sqlite3VdbeAddOp3(v, OP_Column, iEph, nOff+j, k);
        }else{
          sqlite3ExprCode(pParse, pChanges->a[j].pExpr, k);
        sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
        }
      }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){
        /* This branch loads the value of a column that will not be changed 
        ** into a register. This is done if there are no BEFORE triggers, or
        ** if there are one or more BEFORE triggers that use this value via
        ** a new.* reference in a trigger program.
        */
        testcase( i==31 );
        testcase( i==32 );
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k);
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
        bFinishSeek = 0;
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, k);
        sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
      }
    }
  }
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  if( pTab->tabFlags & TF_HasGenerated ){
    testcase( pTab->tabFlags & TF_HasVirtual );
    testcase( pTab->tabFlags & TF_HasStored );
    sqlite3ComputeGeneratedColumns(pParse, regNew, pTab);
  }
#endif

  /* Fire any BEFORE UPDATE triggers. This happens before constraints are
  ** verified. One could argue that this is wrong.
  */
  if( tmask&TRIGGER_BEFORE ){
    sqlite3TableAffinity(v, pTab, regNew);
    sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
        TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue);

    if( !isView ){
      /* The row-trigger may have deleted the row being updated. In this
      ** case, jump to the next row. No updates or AFTER triggers are 
      ** required. This behavior - what happens when the row being updated
      ** is deleted or renamed by a BEFORE trigger - is left undefined in the
      ** documentation.
      */
      if( pPk ){
        sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey);
        VdbeCoverage(v);
      }else{
        sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
        VdbeCoverage(v);
      }
    /* The row-trigger may have deleted the row being updated. In this
    ** case, jump to the next row. No updates or AFTER triggers are 
    ** required. This behavior - what happens when the row being updated
    ** is deleted or renamed by a BEFORE trigger - is left undefined in the
    ** documentation.
    */
    if( pPk ){
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
      VdbeCoverage(v);
    }else{
      sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
      VdbeCoverage(v);
    }

      /* After-BEFORE-trigger-reload-loop:
      ** If it did not delete it, the BEFORE trigger may still have modified 
      ** some of the columns of the row being updated. Load the values for 
      ** all columns not modified by the update statement into their registers
      ** in case this has happened. Only unmodified columns are reloaded.
      ** The values computed for modified columns use the values before the
      ** BEFORE trigger runs.  See test case trigger1-18.0 (added 2018-04-26)
      ** for an example.
      */
      for(i=0, k=regNew; i<pTab->nCol; i++, k++){
    /* After-BEFORE-trigger-reload-loop:
    ** If it did not delete it, the BEFORE trigger may still have modified 
    ** some of the columns of the row being updated. Load the values for 
    ** all columns not modified by the update statement into their registers
    ** in case this has happened. Only unmodified columns are reloaded.
    ** The values computed for modified columns use the values before the
    ** BEFORE trigger runs.  See test case trigger1-18.0 (added 2018-04-26)
    ** for an example.
    */
    for(i=0; i<pTab->nCol; i++){
        if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){
          if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--;
        }else if( aXRef[i]<0 && i!=pTab->iPKey ){
          sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k);
        }
      }
      if( aXRef[i]<0 && i!=pTab->iPKey ){
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
      }
    }
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
      if( pTab->tabFlags & TF_HasGenerated ){
        testcase( pTab->tabFlags & TF_HasVirtual );
        testcase( pTab->tabFlags & TF_HasStored );
        sqlite3ComputeGeneratedColumns(pParse, regNew, pTab);
      }
  }
#endif 
    }

  }

  if( !isView ){
    int addr1 = 0;        /* Address of jump instruction */

    /* Do constraint checks. */
    assert( regOldRowid>0 );
    sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
        regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
        aXRef, 0);

    /* If REPLACE conflict handling may have been used, or if the PK of the
    ** row is changing, then the GenerateConstraintChecks() above may have
    ** moved cursor iDataCur. Reseek it. */
    if( bReplace || chngKey ){
      if( pPk ){
        sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey);
      }else{
        sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
      }
      VdbeCoverageNeverTaken(v);
    }

    /* Do FK constraint checks. */
    if( hasFK ){
      sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
    }

    /* Delete the index entries associated with the current record.  */
    if( bReplace || chngKey ){
      if( pPk ){
    sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);

        addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
      }else{
        addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
      }
    /* We must run the OP_FinishSeek opcode to resolve a prior
    ** OP_DeferredSeek if there is any possibility that there have been
    ** no OP_Column opcodes since the OP_DeferredSeek was issued.  But
    ** we want to avoid the OP_FinishSeek if possible, as running it
    ** costs CPU cycles. */
    if( bFinishSeek ){
      sqlite3VdbeAddOp1(v, OP_FinishSeek, iDataCur);
      VdbeCoverageNeverTaken(v);
    }
    sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);

    /* If changing the rowid value, or if there are foreign key constraints
    ** to process, delete the old record. Otherwise, add a noop OP_Delete
    ** to invoke the pre-update hook.
    **
    ** That (regNew==regnewRowid+1) is true is also important for the 
    ** pre-update hook. If the caller invokes preupdate_new(), the returned
1047
1048
1049
1050
1051
1052
1053



1054
1055
1056
1057
1058
1059
1060
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768







+
+
+







      sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
    }
#else
    if( hasFK>1 || chngKey ){
      sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
    }
#endif
    if( bReplace || chngKey ){
      sqlite3VdbeJumpHere(v, addr1);
    }

    if( hasFK ){
      sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);
    }
  
    /* Insert the new index entries and the new record. */
    sqlite3CompleteInsertion(
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
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







-
+


+
+
















-
+







  ** all record selected by the WHERE clause have been updated.
  */
  if( eOnePass==ONEPASS_SINGLE ){
    /* Nothing to do at end-of-loop for a single-pass */
  }else if( eOnePass==ONEPASS_MULTI ){
    sqlite3VdbeResolveLabel(v, labelContinue);
    sqlite3WhereEnd(pWInfo);
  }else{
  }else if( pPk ){
    sqlite3VdbeResolveLabel(v, labelContinue);
    sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
  }else{
    sqlite3VdbeGoto(v, labelContinue);
  }
  sqlite3VdbeResolveLabel(v, labelBreak);

  /* 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 && pUpsert==0 ){
    sqlite3AutoincrementEnd(pParse);
  }

  /*
  ** Return the number of rows that were changed, if we are tracking
  ** that information.
  */
  if( regRowCount ){
    sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1);
    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[] */
1167
1168
1169
1170
1171
1172
1173
1174

1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231


1232
1233
1234
1235



1236
1237
1238


1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
























1264
1265

1266
1267
1268


1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283














1284
1285
1286


1287
1288
1289
1290
1291
1292
1293
1294

1295
1296
1297
1298
1299
1300
1301
1302
877
878
879
880
881
882
883

884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901








































902
903
904



905
906
907
908


909
910

























911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935

936
937


938
939
940














941
942
943
944
945
946
947
948
949
950
951
952
953
954
955


956
957

958
959
960
961
962


963

964
965
966
967
968
969
970







-
+

















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

-
-
-
+
+
+

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

-
+

-
-
+
+

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

-
-
+
+
-





-
-
+
-







  int onError          /* ON CONFLICT strategy */
){
  Vdbe *v = pParse->pVdbe;  /* Virtual machine under construction */
  int ephemTab;             /* Table holding the result of the SELECT */
  int i;                    /* Loop counter */
  sqlite3 *db = pParse->db; /* Database connection */
  const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
  WhereInfo *pWInfo = 0;
  WhereInfo *pWInfo;
  int nArg = 2 + pTab->nCol;      /* Number of arguments to VUpdate */
  int regArg;                     /* First register in VUpdate arg array */
  int regRec;                     /* Register in which to assemble record */
  int regRowid;                   /* Register for ephem table rowid */
  int iCsr = pSrc->a[0].iCursor;  /* Cursor used for virtual table scan */
  int aDummy[2];                  /* Unused arg for sqlite3WhereOkOnePass() */
  int eOnePass;                   /* True to use onepass strategy */
  int addr;                       /* Address of OP_OpenEphemeral */

  /* Allocate nArg registers in which to gather the arguments for VUpdate. Then
  ** create and open the ephemeral table in which the records created from
  ** these arguments will be temporarily stored. */
  assert( v );
  ephemTab = pParse->nTab++;
  addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg);
  regArg = pParse->nMem + 1;
  pParse->nMem += nArg;
  if( pSrc->nSrc>1 ){
    Index *pPk = 0;
    Expr *pRow;
    ExprList *pList;
    if( HasRowid(pTab) ){
      if( pRowid ){
        pRow = sqlite3ExprDup(db, pRowid, 0);
      }else{
        pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0);
      }
    }else{
      i16 iPk;      /* PRIMARY KEY column */
      pPk = sqlite3PrimaryKeyIndex(pTab);
      assert( pPk!=0 );
      assert( pPk->nKeyCol==1 );
      iPk = pPk->aiColumn[0];
      if( aXRef[iPk]>=0 ){
        pRow = sqlite3ExprDup(db, pChanges->a[aXRef[iPk]].pExpr, 0);
      }else{
        pRow = exprRowColumn(pParse, iPk);
      }
    }
    pList = sqlite3ExprListAppend(pParse, 0, pRow);

    for(i=0; i<pTab->nCol; i++){
      if( aXRef[i]>=0 ){
        pList = sqlite3ExprListAppend(pParse, pList,
          sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0)
        );
      }else{
        pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i));
      }
    }

    updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0);
    sqlite3ExprListDelete(db, pList);
    eOnePass = ONEPASS_OFF;
  }else{
    regRec = ++pParse->nMem;
    regRowid = ++pParse->nMem;
  regRec = ++pParse->nMem;
  regRowid = ++pParse->nMem;

    /* Start scanning the virtual table */
    pWInfo = sqlite3WhereBegin(pParse, pSrc,pWhere,0,0,WHERE_ONEPASS_DESIRED,0);
    if( pWInfo==0 ) return;
  /* Start scanning the virtual table */
  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0);
  if( pWInfo==0 ) return;

    /* Populate the argument registers. */
    for(i=0; i<pTab->nCol; i++){
  /* Populate the argument registers. */
  for(i=0; i<pTab->nCol; i++){
      assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 );
      if( aXRef[i]>=0 ){
        sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
      }else{
        sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
        sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* For sqlite3_vtab_nochange() */
      }
    }
    if( HasRowid(pTab) ){
      sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
      if( pRowid ){
        sqlite3ExprCode(pParse, pRowid, regArg+1);
      }else{
        sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
      }
    }else{
      Index *pPk;   /* PRIMARY KEY index */
      i16 iPk;      /* PRIMARY KEY column */
      pPk = sqlite3PrimaryKeyIndex(pTab);
      assert( pPk!=0 );
      assert( pPk->nKeyCol==1 );
      iPk = pPk->aiColumn[0];
      sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg);
      sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1);
    }
    if( aXRef[i]>=0 ){
      sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
    }else{
      sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
      sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
    }
  }
  if( HasRowid(pTab) ){
    sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
    if( pRowid ){
      sqlite3ExprCode(pParse, pRowid, regArg+1);
    }else{
      sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
    }
  }else{
    Index *pPk;   /* PRIMARY KEY index */
    i16 iPk;      /* PRIMARY KEY column */
    pPk = sqlite3PrimaryKeyIndex(pTab);
    assert( pPk!=0 );
    assert( pPk->nKeyCol==1 );
    iPk = pPk->aiColumn[0];
    sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg);
    sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1);
  }

    eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
  eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);

    /* There is no ONEPASS_MULTI on virtual tables */
    assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
  /* There is no ONEPASS_MULTI on virtual tables */
  assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );

    if( eOnePass ){
      /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
      ** above. */
      sqlite3VdbeChangeToNoop(v, addr);
      sqlite3VdbeAddOp1(v, OP_Close, iCsr);
    }else{
      /* Create a record from the argument register contents and insert it into
      ** the ephemeral table. */
      sqlite3MultiWrite(pParse);
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
#if defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_NULL_TRIM)
      /* Signal an assert() within OP_MakeRecord that it is allowed to
      ** accept no-change records with serial_type 10 */
      sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC);
  if( eOnePass ){
    /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
    ** above. */
    sqlite3VdbeChangeToNoop(v, addr);
    sqlite3VdbeAddOp1(v, OP_Close, iCsr);
  }else{
    /* Create a record from the argument register contents and insert it into
    ** the ephemeral table. */
    sqlite3MultiWrite(pParse);
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
#ifdef SQLITE_DEBUG
    /* Signal an assert() within OP_MakeRecord that it is allowed to
    ** accept no-change records with serial_type 10 */
    sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC);
#endif
      sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
      sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
    sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
    sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
    }
  }


  if( eOnePass==ONEPASS_OFF ){
    /* End the virtual table scan */
    if( pSrc->nSrc==1 ){
      sqlite3WhereEnd(pWInfo);
    sqlite3WhereEnd(pWInfo);
    }

    /* Begin scannning through the ephemeral table. */
    addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v);

    /* Extract arguments from the current row of the ephemeral table and 
    ** invoke the VUpdate method.  */
    for(i=0; i<nArg; i++){

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
75
76
77
78

79
80
81
82
83
84
85
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
*/
static void SQLITE_NOINLINE upsertDelete(sqlite3 *db, Upsert *p){
void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){
  do{
    Upsert *pNext = p->pNextUpsert;
  if( p ){
    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),
           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 */
  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));
  pNew = sqlite3DbMallocRaw(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;
    pNew->pUpsertIdx = 0;
  }
  return pNew;
}

/*
** Analyze the ON CONFLICT clause described by pUpsert.  Resolve all
** symbols in the conflict-target.
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
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 */
  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 );
  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;
    }
    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;
  }
    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;
  sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any "
                          "PRIMARY KEY or UNIQUE constraint");
  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
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
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







-
-



-
-

+











+




-
+









-



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




  Index *pIdx,          /* The UNIQUE constraint that failed */
  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"));
  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);
    }else{
      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
      int nPk = pPk->nKeyCol;
      int iPk = pParse->nMem+1;
      int i;
      pParse->nMem += nPk;
      for(i=0; i<nPk; i++){
        int k;
        assert( pPk->aiColumn[i]>=0 );
        k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]);
        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
        sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i);
        VdbeComment((v, "%s.%s", pIdx->zName,
                    pTab->aCol[pPk->aiColumn[i]].zName));
      }
      sqlite3VdbeVerifyAbortable(v, OE_Abort);
      i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk);
      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);
  /* 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, pTop->regData+i);
    }
  }
  sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0),
      sqlite3ExprDup(db,pUpsert->pUpsertWhere,0), OE_Abort, 0, 0, pUpsert);
  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 */

Changes to src/utf.c.

100
101
102
103
104
105
106




















107
108
109
110
111
112
113
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







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







  }else{                                                            \
    *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));              \
    *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
    *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));                         \
    *zOut++ = (u8)(c&0x00FF);                                       \
  }                                                                 \
}

#define READ_UTF16LE(zIn, TERM, c){                                   \
  c = (*zIn++);                                                       \
  c += ((*zIn++)<<8);                                                 \
  if( c>=0xD800 && c<0xE000 && TERM ){                                \
    int c2 = (*zIn++);                                                \
    c2 += ((*zIn++)<<8);                                              \
    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
  }                                                                   \
}

#define READ_UTF16BE(zIn, TERM, c){                                   \
  c = ((*zIn++)<<8);                                                  \
  c += (*zIn++);                                                      \
  if( c>=0xD800 && c<0xE000 && TERM ){                                \
    int c2 = ((*zIn++)<<8);                                           \
    c2 += (*zIn++);                                                   \
    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
  }                                                                   \
}

/*
** Translate a single UTF-8 character.  Return the unicode value.
**
** During translation, assume that the byte that zTerm points
** is a 0x00.
**
191
192
193
194
195
196
197
198
199

200
201
202


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


218



219
220
221
222
223
224
225
226
227







-
-
+
-
-
-
+
+







  assert( pMem->flags&MEM_Str );
  assert( pMem->enc!=desiredEnc );
  assert( pMem->enc!=0 );
  assert( pMem->n>=0 );

#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
  {
    StrAccum acc;
    char zBuf[1000];
    char zBuf[100];
    sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);  
    sqlite3VdbeMemPrettyPrint(pMem, &acc);
    fprintf(stderr, "INPUT:  %s\n", sqlite3StrAccumFinish(&acc));
    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
    fprintf(stderr, "INPUT:  %s\n", zBuf);
  }
#endif

  /* If the translation is between UTF-16 little and big endian, then 
  ** all that is required is to swap the byte order. This case is handled
  ** differently from the others.
  */
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
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







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





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








-
+

-
+








-
-
+
-
-
-
+
+







    pMem->n = (int)(z - zOut);
    *z++ = 0;
  }else{
    assert( desiredEnc==SQLITE_UTF8 );
    if( pMem->enc==SQLITE_UTF16LE ){
      /* UTF-16 Little-endian -> UTF-8 */
      while( zIn<zTerm ){
        c = *(zIn++);
        c += (*(zIn++))<<8;
        if( c>=0xd800 && c<0xe000 ){
#ifdef SQLITE_REPLACE_INVALID_UTF
          if( c>=0xdc00 || zIn>=zTerm ){
            c = 0xfffd;
          }else{
            int c2 = *(zIn++);
            c2 += (*(zIn++))<<8;
            if( c2<0xdc00 || c2>=0xe000 ){
              zIn -= 2;
              c = 0xfffd;
            }else{
              c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
            }
          }
#else
          if( zIn<zTerm ){
        READ_UTF16LE(zIn, zIn<zTerm, c); 
            int c2 = (*zIn++);
            c2 += ((*zIn++)<<8);
            c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
          }
#endif
        }
        WRITE_UTF8(z, c);
      }
    }else{
      /* UTF-16 Big-endian -> UTF-8 */
      while( zIn<zTerm ){
        c = (*(zIn++))<<8;
        c += *(zIn++);
        if( c>=0xd800 && c<0xe000 ){
#ifdef SQLITE_REPLACE_INVALID_UTF
          if( c>=0xdc00 || zIn>=zTerm ){
            c = 0xfffd;
          }else{
            int c2 = (*(zIn++))<<8;
            c2 += *(zIn++);
            if( c2<0xdc00 || c2>=0xe000 ){
              zIn -= 2;
              c = 0xfffd;
            }else{
              c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
            }
          }
#else
          if( zIn<zTerm ){
        READ_UTF16BE(zIn, zIn<zTerm, c); 
            int c2 = ((*zIn++)<<8);
            c2 += (*zIn++);
            c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
          }
#endif
        }
        WRITE_UTF8(z, c);
      }
    }
    pMem->n = (int)(z - zOut);
  }
  *z = 0;
  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );

  c = MEM_Str|MEM_Term|(pMem->flags&(MEM_AffMask|MEM_Subtype));
  c = pMem->flags;
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = c;
  pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype));
  pMem->enc = desiredEnc;
  pMem->z = (char*)zOut;
  pMem->zMalloc = pMem->z;
  pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z);

translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
  {
    StrAccum acc;
    char zBuf[1000];
    char zBuf[100];
    sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);  
    sqlite3VdbeMemPrettyPrint(pMem, &acc);
    fprintf(stderr, "OUTPUT: %s\n", sqlite3StrAccumFinish(&acc));
    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
    fprintf(stderr, "OUTPUT: %s\n", zBuf);
  }
#endif
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */

#ifndef SQLITE_OMIT_UTF16
488
489
490
491
492
493
494
495
496
497
498




499
500
501
502








503
504
505
506
507
508
509
510
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







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







** in pZ.  nChar must be non-negative.
*/
int sqlite3Utf16ByteLen(const void *zIn, int nChar){
  int c;
  unsigned char const *z = zIn;
  int n = 0;
  
  if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++;
  while( n<nChar ){
    c = z[0];
    z += 2;
  if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
    while( n<nChar ){
      READ_UTF16BE(z, 1, c);
      n++;
    if( c>=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
    n++;
  }
  return (int)(z-(unsigned char const *)zIn) 
    }
  }else{
    while( n<nChar ){
      READ_UTF16LE(z, 1, c);
      n++;
    }
  }
  return (int)(z-(unsigned char const *)zIn);
              - (SQLITE_UTF16NATIVE==SQLITE_UTF16LE);
}

#if defined(SQLITE_TEST)
/*
** This routine is called from the TCL test function "translate_selftest".
** It checks that the primitives for serializing and deserializing
** characters in each encoding are inverses of each other.
525
526
527
528
529
530
531
























532
533
534
535
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







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




    z = zBuf;
    c = sqlite3Utf8Read((const u8**)&z);
    t = i;
    if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
    if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
    assert( c==t );
    assert( (z-zBuf)==n );
  }
  for(i=0; i<0x00110000; i++){
    if( i>=0xD800 && i<0xE000 ) continue;
    z = zBuf;
    WRITE_UTF16LE(z, i);
    n = (int)(z-zBuf);
    assert( n>0 && n<=4 );
    z[0] = 0;
    z = zBuf;
    READ_UTF16LE(z, 1, c);
    assert( c==i );
    assert( (z-zBuf)==n );
  }
  for(i=0; i<0x00110000; i++){
    if( i>=0xD800 && i<0xE000 ) continue;
    z = zBuf;
    WRITE_UTF16BE(z, i);
    n = (int)(z-zBuf);
    assert( n>0 && n<=4 );
    z[0] = 0;
    z = zBuf;
    READ_UTF16BE(z, 1, c);
    assert( c==i );
    assert( (z-zBuf)==n );
  }
}
#endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_UTF16 */

Changes to src/util.c.

13
14
15
16
17
18
19
20
21


22
23
24
25
26
27
28
13
14
15
16
17
18
19


20
21
22
23
24
25
26
27
28







-
-
+
+







**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
*/
#include "sqliteInt.h"
#include <stdarg.h>
#ifndef SQLITE_OMIT_FLOATING_POINT
#include <math.h>
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
# include <math.h>
#endif

/*
** Routine needed to support the testcase() macro.
*/
#ifdef SQLITE_COVERAGE_TEST
void sqlite3Coverage(int x){
56
57
58
59
60
61
62



63
64





























65
66
67







68
69
70
71
72
73
74
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







+
+
+


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







  return xCallback ? xCallback(iTest) : SQLITE_OK;
}
#endif

#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).
**
** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
** Otherwise, we have our own implementation that works on most systems.
*/
int sqlite3IsNaN(double x){
  int rc;   /* The value return */
#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
  /*
  ** Systems that support the isnan() library function should probably
  ** make use of it by compiling with -DSQLITE_HAVE_ISNAN.  But we have
  ** found that many systems do not have a working isnan() function so
  ** this implementation is provided as an alternative.
  **
  ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
  ** On the other hand, the use of -ffast-math comes with the following
  ** warning:
  **
  **      This option [-ffast-math] should never be turned on by any
  **      -O option since it can result in incorrect output for programs
  **      which depend on an exact implementation of IEEE or ISO 
  **      rules/specifications for math functions.
  **
  ** Under MSVC, this NaN test may fail if compiled with a floating-
  ** point precision mode other than /fp:precise.  From the MSDN 
  ** documentation:
  **
  **      The compiler [with /fp:precise] will properly handle comparisons 
  **      involving NaN. For example, x != x evaluates to true if x is NaN 
  **      ...
  */
#ifdef __FAST_MATH__
# error SQLite will not work correctly with the -ffast-math option of GCC.
#endif
  volatile double y = x;
  u64 y;
  memcpy(&y,&x,sizeof(y));
  return IsNaN(y);
  volatile double z = y;
  rc = (y!=z);
#else  /* if HAVE_ISNAN */
  rc = isnan(x);
#endif /* HAVE_ISNAN */
  testcase( rc );
  return rc;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */

/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
**
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
146
147
148
149
150
151
152










153
154
155
156
157
158
159







-
-
-
-
-
-
-
-
-
-







*/
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;
  rc &= 0xff;
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
226
227
228
229
230
231
232

233
234
235
236
237
238
239







-







  if( db->suppressErr ){
    sqlite3DbFree(db, zMsg);
  }else{
    pParse->nErr++;
    sqlite3DbFree(db, pParse->zErrMsg);
    pParse->zErrMsg = zMsg;
    pParse->rc = SQLITE_ERROR;
    pParse->pWith = 0;
  }
}

/*
** If database connection db is currently parsing SQL, then transfer
** error code errCode to that parser if the parser has not already
** encountered some other kind of error.
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
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







-
+



-
-
-
-
-
-
-
+
+
-


















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









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







  }else if( zRight==0 ){
    return 1;
  }
  return sqlite3StrICmp(zLeft, zRight);
}
int sqlite3StrICmp(const char *zLeft, const char *zRight){
  unsigned char *a, *b;
  int c, x;
  int c;
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  for(;;){
    c = *a;
    x = *b;
    if( c==x ){
      if( c==0 ) break;
    }else{
      c = (int)UpperToLower[c] - (int)UpperToLower[x];
      if( c ) break;
    c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
    if( c || *a==0 ) break;
    }
    a++;
    b++;
  }
  return c;
}
int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
  register unsigned char *a, *b;
  if( zLeft==0 ){
    return zRight ? -1 : 0;
  }else if( zRight==0 ){
    return 1;
  }
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}

/*
** Compute an 8-bit hash on a string that is insensitive to case differences
*/
u8 sqlite3StrIHash(const char *z){
  u8 h = 0;
  if( z==0 ) return 0;
  while( z[0] ){
    h += UpperToLower[(unsigned char)z[0]];
    z++;
  }
  return h;
}

/*
** Compute 10 to the E-th power.  Examples:  E==1 results in 10.
** E==2 results in 100.  E==50 results in 1.0e50.
**
** This routine only works for values of E between 1 and 341.
*/
static LONGDOUBLE_TYPE sqlite3Pow10(int E){
#if defined(_MSC_VER)
  static const LONGDOUBLE_TYPE x[] = {
    1.0e+001L,
    1.0e+002L,
    1.0e+004L,
    1.0e+008L,
    1.0e+016L,
    1.0e+032L,
    1.0e+064L,
    1.0e+128L,
    1.0e+256L
    1.0e+001,
    1.0e+002,
    1.0e+004,
    1.0e+008,
    1.0e+016,
    1.0e+032,
    1.0e+064,
    1.0e+128,
    1.0e+256
  };
  LONGDOUBLE_TYPE r = 1.0;
  int i;
  assert( E>=0 && E<=307 );
  for(i=0; E!=0; i++, E >>=1){
    if( E & 1 ) r *= x[i];
  }
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
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







-
+
-
-
-
-
-
-
-
-
+












-
-
-



-
+








-
-
+
+



-



-



-

-
-

-
+

















-
+

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





-






-

-
+








-







** The string z[] is an text representation of a real number.
** Convert this string to a double and write it into *pResult.
**
** The string z[] is length bytes in length (bytes, not characters) and
** uses the encoding enc.  The string is not necessarily zero-terminated.
**
** Return TRUE if the result is a valid real number (or integer) and FALSE
** if the string is empty or contains extraneous text.  More specifically
** if the string is empty or contains extraneous text.  Valid numbers
** return
**      1          =>  The input string is a pure integer
**      2 or more  =>  The input has a decimal point or eNNN clause
**      0 or less  =>  The input string is not a valid number
**     -1          =>  Not a valid number, but has a valid prefix which 
**                     includes a decimal point and/or an eNNN clause
**
** Valid numbers are in one of these formats:
** are in one of these formats:
**
**    [+-]digits[E[+-]digits]
**    [+-]digits.[digits][E[+-]digits]
**    [+-].digits[E[+-]digits]
**
** Leading and trailing whitespace is ignored for the purpose of determining
** validity.
**
** If some prefix of the input string is a valid number, this routine
** returns FALSE but it still converts the prefix and writes the result
** into *pResult.
*/
#if defined(_MSC_VER)
#pragma warning(disable : 4756)
#endif
int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
#ifndef SQLITE_OMIT_FLOATING_POINT
  int incr;
  const char *zEnd;
  const char *zEnd = z + length;
  /* sign * significand * (10 ^ (esign * exponent)) */
  int sign = 1;    /* sign of significand */
  i64 s = 0;       /* significand */
  int d = 0;       /* adjust exponent for shifting decimal point */
  int esign = 1;   /* sign of exponent */
  int e = 0;       /* exponent */
  int eValid = 1;  /* True exponent is either not used or is well-formed */
  double result;
  int nDigit = 0;  /* Number of digits processed */
  int eType = 1;   /* 1: pure integer,  2+: fractional  -1 or less: bad UTF16 */
  int nDigits = 0;
  int nonNum = 0;  /* True if input contains UTF16 with high byte non-zero */

  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
  *pResult = 0.0;   /* Default return value, in case of an error */
  if( length==0 ) return 0;

  if( enc==SQLITE_UTF8 ){
    incr = 1;
    zEnd = z + length;
  }else{
    int i;
    incr = 2;
    length &= ~1;
    assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
    testcase( enc==SQLITE_UTF16LE );
    testcase( enc==SQLITE_UTF16BE );
    for(i=3-enc; i<length && z[i]==0; i+=2){}
    if( i<length ) eType = -100;
    nonNum = i<length;
    zEnd = &z[i^1];
    z += (enc&1);
  }

  /* skip leading spaces */
  while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
  if( z>=zEnd ) return 0;

  /* get sign of significand */
  if( *z=='-' ){
    sign = -1;
    z+=incr;
  }else if( *z=='+' ){
    z+=incr;
  }

  /* copy max significant digits to significand */
  while( z<zEnd && sqlite3Isdigit(*z) ){
  while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
    s = s*10 + (*z - '0');
    z+=incr; nDigit++;
    if( s>=((LARGEST_INT64-9)/10) ){
      /* skip non-significant significand digits
      ** (increase exponent by d to shift decimal left) */
      while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; d++; }
    z+=incr; nDigits++;
  }

  /* skip non-significant significand digits
  ** (increase exponent by d to shift decimal left) */
  while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; }
    }
  }
  if( z>=zEnd ) goto do_atof_calc;

  /* if decimal point is present */
  if( *z=='.' ){
    z+=incr;
    eType++;
    /* copy digits from after decimal to significand
    ** (decrease exponent by d to shift decimal right) */
    while( z<zEnd && sqlite3Isdigit(*z) ){
      if( s<((LARGEST_INT64-9)/10) ){
        s = s*10 + (*z - '0');
        d--;
        nDigit++;
      }
      z+=incr;
      z+=incr; nDigits++;
    }
  }
  if( z>=zEnd ) goto do_atof_calc;

  /* if exponent is present */
  if( *z=='e' || *z=='E' ){
    z+=incr;
    eValid = 0;
    eType++;

    /* This branch is needed to avoid a (harmless) buffer overread.  The 
    ** special comment alerts the mutation tester that the correct answer
    ** is obtained even if the branch is omitted */
    if( z>=zEnd ) goto do_atof_calc;              /*PREVENTS-HARMLESS-OVERREAD*/

    /* get sign of exponent */
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
573
574
575
576
577
578
579

580






581
582
583
584



























585
586
587
588
589
590
591







-
+
-
-
-
-
-
-




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







    }
  }

  /* store the result */
  *pResult = result;

  /* return true if number and no extra non-whitespace chracters after */
  if( z==zEnd && nDigit>0 && eValid && eType>0 ){
  return z==zEnd && nDigits>0 && eValid && nonNum==0;
    return eType;
  }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){
    return -1;
  }else{
    return 0;
  }
#else
  return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
}
#if defined(_MSC_VER)
#pragma warning(default : 4756)
#endif

/*
** Render an signed 64-bit integer as text.  Store the result in zOut[].
**
** The caller must ensure that zOut[] is at least 21 bytes in size.
*/
void sqlite3Int64ToText(i64 v, char *zOut){
  int i;
  u64 x;
  char zTemp[22];
  if( v<0 ){
    x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v;
  }else{
    x = v;
  }
  i = sizeof(zTemp)-2;
  zTemp[sizeof(zTemp)-1] = 0;
  do{
    zTemp[i--] = (x%10) + '0';
    x = x/10;
  }while( x );
  if( v<0 ) zTemp[i--] = '-';
  memcpy(zOut, &zTemp[i+1], sizeof(zTemp)-1-i);
}

/*
** Compare the 19-character string zNum against the text representation
** value 2^63:  9223372036854775808.  Return negative, zero, or positive
** if zNum is less than, equal to, or greater than the string.
** Note that zNum must contain exactly 19 characters.
**
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
616
617
618
619
620
621
622

623
624
625
626
627
628
629







-








/*
** Convert zNum to a 64-bit signed integer.  zNum must be decimal. This
** routine does *not* accept hexadecimal notation.
**
** Returns:
**
**    -1    Not even a prefix of the input text looks like an integer
**     0    Successful transformation.  Fits in a 64-bit signed integer.
**     1    Excess non-space text after the integer value
**     2    Integer too large for a 64-bit signed integer or is malformed
**     3    Special case of 9223372036854775808
**
** length is the number of bytes in the string (bytes, not characters).
** The string is not necessarily zero-terminated.  The encoding is
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
640
641
642
643
644
645
646

647
648
649
650
651
652
653







-







  const char *zStart;
  const char *zEnd = zNum + length;
  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
  if( enc==SQLITE_UTF8 ){
    incr = 1;
  }else{
    incr = 2;
    length &= ~1;
    assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
    for(i=3-enc; i<length && zNum[i]==0; i+=2){}
    nonNum = i<length;
    zEnd = &zNum[i^1];
    zNum += (enc&1);
  }
  while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
723
724
725
726
727
728
729
730

731
732


733
734
735
736
737
738
739
675
676
677
678
679
680
681

682


683
684
685
686
687
688
689
690
691







-
+
-
-
+
+







    *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
  }else if( neg ){
    *pNum = -(i64)u;
  }else{
    *pNum = (i64)u;
  }
  rc = 0;
  if( i==0 && zStart==zNum ){    /* No digits */
  if( (i==0 && zStart==zNum)     /* No digits */
    rc = -1;
  }else if( nonNum ){            /* UTF16 with high-order bytes non-zero */
   || nonNum                     /* UTF16 with high-order bytes non-zero */
  ){
    rc = 1;
  }else if( &zNum[i]<zEnd ){     /* Extra bytes at the end */
    int jj = i;
    do{
      if( !sqlite3Isspace(zNum[jj]) ){
        rc = 1;          /* Extra non-space text after the integer */
        break;
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
818
819
820
821
822
823
824

825
826
827
828


















829
830
831
832
833
834
835







-
+



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








/*
** Return a 32-bit integer value extracted from a string.  If the
** string is not an integer, just return 0.
*/
int sqlite3Atoi(const char *z){
  int x = 0;
  sqlite3GetInt32(z, &x);
  if( z ) sqlite3GetInt32(z, &x);
  return x;
}

/*
** Try to convert z into an unsigned 32-bit integer.  Return true on
** success and false if there is an error.
**
** Only decimal notation is accepted.
*/
int sqlite3GetUInt32(const char *z, u32 *pI){
  u64 v = 0;
  int i;
  for(i=0; sqlite3Isdigit(z[i]); i++){
    v = v*10 + z[i] - '0';
    if( v>4294967296LL ){ *pI = 0; return 0; }
  }
  if( i==0 || z[i]!=0 ){ *pI = 0; return 0; }
  *pI = (u32)v;
  return 1;
}

/*
** The variable-length integer encoding is as follows:
**
** KEY:
**         A = 0xxxxxxx    7 bits of data and one flag bit
**         B = 1xxxxxxx    7 bits of data and one flag bit
**         C = xxxxxxxx    8 bits of data
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
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







-
-
+
+
+
+
+


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







-
-
+
+
-







/*
** Read a 64-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read.  The value is stored in *v.
*/
u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
  u32 a,b,s;

  if( ((signed char*)p)[0]>=0 ){
    *v = *p;
  a = *p;
  /* a: p0 (unmasked) */
  if (!(a&0x80))
  {
    *v = a;
    return 1;
  }
  if( ((signed char*)p)[1]>=0 ){
    *v = ((u32)(p[0]&0x7f)<<7) | p[1];

  p++;
  b = *p;
  /* b: p1 (unmasked) */
  if (!(b&0x80))
  {
    a &= 0x7f;
    a = a<<7;
    a |= b;
    *v = a;
    return 2;
  }

  /* Verify that constants are precomputed correctly */
  assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
  assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );

  a = ((u32)p[0])<<14;
  b = p[1];
  p++;
  a = a<<14;
  p += 2;
  a |= *p;
  /* a: p0<<14 | p2 (unmasked) */
  if (!(a&0x80))
  {
    a &= SLOT_2_0;
    b &= 0x7f;
    b = b<<7;
1190
1191
1192
1193
1194
1195
1196

1197

1198
1199
1200
1201
1202
1203
1204
1134
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1149







+
-
+







  ** routine.
  */
#if 1
  {
    u64 v64;
    u8 n;

    p -= 2;
    n = sqlite3GetVarint(p-2, &v64);
    n = sqlite3GetVarint(p, &v64);
    assert( n>3 && n<=9 );
    if( (v64 & SQLITE_MAX_U32)!=v64 ){
      *v = 0xffffffff;
    }else{
      *v = (u32)v64;
    }
    return n;
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
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







-
+




















-
+







#endif
#ifdef SQLITE_EBCDIC
  h += 9*(1&~(h>>4));
#endif
  return (u8)(h & 0xf);
}

#if !defined(SQLITE_OMIT_BLOB_LITERAL)
#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
/*
** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
** value.  Return a pointer to its binary value.  Space to hold the
** binary value has been obtained from malloc and must be freed by
** the calling routine.
*/
void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
  char *zBlob;
  int i;

  zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1);
  n--;
  if( zBlob ){
    for(i=0; i<n; i+=2){
      zBlob[i/2] = (sqlite3HexToInt(z[i])<<4) | sqlite3HexToInt(z[i+1]);
    }
    zBlob[i/2] = 0;
  }
  return zBlob;
}
#endif /* !SQLITE_OMIT_BLOB_LITERAL */
#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */

/*
** Log an error that is an API call on a connection pointer that should
** not have been used.  The "type" of connection pointer is given as the
** argument.  The zType is a word like "NULL" or "closed" or "invalid".
*/
static void logBadConnection(const char *zType){
1571
1572
1573
1574
1575
1576
1577
1578

1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596

1597
1598
1599
1600
1601
1602
1603
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







-
+

















-
+







  memcpy(&a, &x, 8);
  e = (a>>52) - 1022;
  return e*10;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
    defined(SQLITE_ENABLE_STAT4) || \
    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
/*
** Convert a LogEst into an integer.
**
** Note that this routine is only used when one or more of various
** non-standard compile-time options is enabled.
*/
u64 sqlite3LogEstToInt(LogEst x){
  u64 n;
  n = x%10;
  x /= 10;
  if( n>=5 ) n -= 2;
  else if( n>=1 ) n -= 1;
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
  if( x>60 ) return (u64)LARGEST_INT64;
#else
  /* If only SQLITE_ENABLE_STAT4 is on, then the largest input
  /* If only SQLITE_ENABLE_STAT3_OR_STAT4 is on, then the largest input
  ** possible to this routine is 310, resulting in a maximum x of 31 */
  assert( x<=60 );
#endif
  return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
}
#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */

Changes to src/vacuum.c.

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+







  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc!=SQLITE_OK ) return rc;
  while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
    const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
    assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
    /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX,
    ** or INSERT.  Historically there have been attacks that first
    ** corrupt the sqlite_schema.sql field with other kinds of statements
    ** corrupt the sqlite_master.sql field with other kinds of statements
    ** then run VACUUM to get those statements to execute at inappropriate
    ** times. */
    if( zSubSql
     && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0)
    ){
      rc = execSql(db, pzErrMsg, zSubSql);
      if( rc!=SQLITE_OK ) break;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
102
103
104
105
106
107
108

109
110
111
112
113
114
115







-







** transient would cause the database file to appear to be deleted
** following reboot.
*/
void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
  Vdbe *v = sqlite3GetVdbe(pParse);
  int iDb = 0;
  if( v==0 ) goto build_vacuum_end;
  if( pParse->nErr ) goto build_vacuum_end;
  if( pNm ){
#ifndef SQLITE_BUG_COMPATIBLE_20160819
    /* Default behavior:  Report an error if the argument to VACUUM is
    ** not recognized */
    iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
    if( iDb<0 ) goto build_vacuum_end;
#else
229
230
231
232
233
234
235
236












237
238
239
240
241
242
243
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







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







    if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
      rc = SQLITE_ERROR;
      sqlite3SetString(pzErrMsg, db, "output file already exists");
      goto end_of_vacuum;
    }
    db->mDbFlags |= DBFLAG_VacuumInto;
  }
  nRes = sqlite3BtreeGetRequestedReserve(pMain);
  nRes = sqlite3BtreeGetOptimalReserve(pMain);

  /* A VACUUM cannot change the pagesize of an encrypted database. */
#ifdef SQLITE_HAS_CODEC
  if( db->nextPagesize ){
    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
    int nKey;
    char *zKey;
    sqlite3CodecGetKey(db, iDb, (void**)&zKey, &nKey);
    if( nKey ) db->nextPagesize = 0;
  }
#endif

  sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
  sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
  sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);

  /* Begin a transaction and take an exclusive lock on the main database
  ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
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
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







-
+






-
+













-
+










-
+


-
-
+
+







#endif

  /* Query the schema of the main database. Create a mirror schema
  ** in the temporary database.
  */
  db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
  rc = execSqlF(db, pzErrMsg,
      "SELECT sql FROM \"%w\".sqlite_schema"
      "SELECT sql FROM \"%w\".sqlite_master"
      " WHERE type='table'AND name<>'sqlite_sequence'"
      " AND coalesce(rootpage,1)>0",
      zDbMain
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execSqlF(db, pzErrMsg,
      "SELECT sql FROM \"%w\".sqlite_schema"
      "SELECT sql FROM \"%w\".sqlite_master"
      " WHERE type='index'",
      zDbMain
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  db->init.iDb = 0;

  /* Loop through the tables in the main database. For each, do
  ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
  ** the contents to the temporary database.
  */
  rc = execSqlF(db, pzErrMsg,
      "SELECT'INSERT INTO vacuum_db.'||quote(name)"
      "||' SELECT*FROM\"%w\".'||quote(name)"
      "FROM vacuum_db.sqlite_schema "
      "FROM vacuum_db.sqlite_master "
      "WHERE type='table'AND coalesce(rootpage,1)>0",
      zDbMain
  );
  assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
  db->mDbFlags &= ~DBFLAG_Vacuum;
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Copy the triggers, views, and virtual tables from the main database
  ** over to the temporary database.  None of these objects has any
  ** associated storage, so all we have to do is copy their entries
  ** from the schema table.
  ** from the SQLITE_MASTER table.
  */
  rc = execSqlF(db, pzErrMsg,
      "INSERT INTO vacuum_db.sqlite_schema"
      " SELECT*FROM \"%w\".sqlite_schema"
      "INSERT INTO vacuum_db.sqlite_master"
      " SELECT*FROM \"%w\".sqlite_master"
      " WHERE type IN('view','trigger')"
      " OR(type='table'AND rootpage=0)",
      zDbMain
  );
  if( rc ) goto end_of_vacuum;

  /* At this point, there is a write transaction open on both the 
335
336
337
338
339
340
341
342
343


344
345
346
347
348
349
350
345
346
347
348
349
350
351


352
353
354
355
356
357
358
359
360







-
-
+
+







       BTREE_SCHEMA_VERSION,     1,  /* Add one to the old schema cookie */
       BTREE_DEFAULT_CACHE_SIZE, 0,  /* Preserve the default page cache size */
       BTREE_TEXT_ENCODING,      0,  /* Preserve the text encoding */
       BTREE_USER_VERSION,       0,  /* Preserve the user version */
       BTREE_APPLICATION_ID,     0,  /* Preserve the application id */
    };

    assert( SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pTemp) );
    assert( pOut!=0 || SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pMain) );
    assert( 1==sqlite3BtreeIsInTrans(pTemp) );
    assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) );

    /* Copy Btree meta values */
    for(i=0; i<ArraySize(aCopy); i+=2){
      /* GetMeta() and UpdateMeta() cannot fail in this context because
      ** we already have page 1 loaded into cache and marked dirty. */
      sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
      rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397







-
+







  /* Restore the original value of db->flags */
  db->init.iDb = 0;
  db->mDbFlags = saved_mDbFlags;
  db->flags = saved_flags;
  db->nChange = saved_nChange;
  db->nTotalChange = saved_nTotalChange;
  db->mTrace = saved_mTrace;
  sqlite3BtreeSetPageSize(pMain, -1, 0, 1);
  sqlite3BtreeSetPageSize(pMain, -1, -1, 1);

  /* Currently there is an SQL level transaction open on the vacuum
  ** database. No locks are held on any other files (since the main file
  ** was committed at the btree level). So it safe to end the transaction
  ** by manually setting the autoCommit flag to true and detaching the
  ** vacuum database. The vacuum_db journal file is deleted when the pager
  ** is closed by the DETACH.

Changes to src/vdbe.c.

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
113
114
115
116
117
118
119




















120
121
122
123
124
125
126







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







*/
#if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE)
# define UPDATE_MAX_BLOBSIZE(P)  updateMaxBlobsize(P)
#else
# define UPDATE_MAX_BLOBSIZE(P)
#endif

#ifdef SQLITE_DEBUG
/* This routine provides a convenient place to set a breakpoint during
** tracing with PRAGMA vdbe_trace=on.  The breakpoint fires right after
** each opcode is printed.  Variables "pc" (program counter) and pOp are
** available to add conditionals to the breakpoint.  GDB example:
**
**         break test_trace_breakpoint if pc=22
**
** Other useful labels for breakpoints include:
**   test_addop_breakpoint(pc,pOp)
**   sqlite3CorruptError(lineno)
**   sqlite3MisuseError(lineno)
**   sqlite3CantopenError(lineno)
*/
static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){
  static int n = 0;
  n++;
}
#endif

/*
** Invoke the VDBE coverage callback, if that callback is defined.  This
** feature is used for test suite validation only and does not appear an
** production builds.
**
** M is the type of branch.  I is the direction taken for this instance of
** the branch.
211
212
213
214
215
216
217








218
219
220
221
222
223
224
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212







+
+
+
+
+
+
+
+







      if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/
    }
    sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
                                    iSrcLine&0xffffff, I, M);
  }
#endif

/*
** Convert the given register into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
     { goto no_mem; }

/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
** is responsible for deallocating that string.  Because the register
** does not control the string, it might be deleted without the register
** knowing it.
**
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
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







+
+
+
+
+



















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

















+

-
-
-
-
-
+
+
+
+







  VdbeCursor *pCx = 0;
  nByte = 
      ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + 
      (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);

  assert( iCur>=0 && iCur<p->nCursor );
  if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
    /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
    ** is clear. Otherwise, if this is an ephemeral cursor created by 
    ** OP_OpenDup, the cursor will not be closed and will still be part
    ** of a BtShared.pCursor list.  */
    p->apCsr[iCur]->isEphemeral = 0;
    sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
    p->apCsr[iCur] = 0;
  }
  if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
    p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
    memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
    pCx->eCurType = eCurType;
    pCx->iDb = iDb;
    pCx->nField = nField;
    pCx->aOffset = &pCx->aType[nField];
    if( eCurType==CURTYPE_BTREE ){
      pCx->uc.pCursor = (BtCursor*)
          &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
      sqlite3BtreeCursorZero(pCx->uc.pCursor);
    }
  }
  return pCx;
}

/*
** The string in pRec is known to look like an integer and to have a
** floating point value of rValue.  Return true and set *piValue to the
** integer value if the string is in range to be an integer.  Otherwise,
** return false.
*/
static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){
  i64 iValue = (double)rValue;
  if( sqlite3RealSameAsInt(rValue,iValue) ){
    *piValue = iValue;
    return 1;
  }
  return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc);
}

/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information.  In other words, if the string
** looks like a number, convert it into a number.  If it does not
** look like a number, leave it alone.
**
** If the bTryForInt flag is true, then extra effort is made to give
** an integer representation.  Strings that look like floating point
** values but which have no fractional component (example: '48.00')
** will have a MEM_Int representation when bTryForInt is true.
**
** If bTryForInt is false, then if the input string contains a decimal
** point or exponential notation, the result is only MEM_Real, even
** if there is an exact integer representation of the quantity.
*/
static void applyNumericAffinity(Mem *pRec, int bTryForInt){
  double rValue;
  i64 iValue;
  u8 enc = pRec->enc;
  int rc;
  assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str );
  rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc);
  if( rc<=0 ) return;
  if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){
  assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
  if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
  if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
    pRec->u.i = iValue;
    pRec->flags |= MEM_Int;
  }else{
    pRec->u.r = rValue;
    pRec->flags |= MEM_Real;
    if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
  }
  /* TEXT->NUMERIC is many->one.  Hence, it is important to invalidate the
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
332
333
334
335
336
337
338

339
340
341
342
343
344
345







-







**    always preferred, even if the affinity is REAL, because
**    an integer representation is more space efficient on disk.
**
** SQLITE_AFF_TEXT:
**    Convert pRec to a text representation.
**
** SQLITE_AFF_BLOB:
** SQLITE_AFF_NONE:
**    No-op.  pRec is unchanged.
*/
static void applyAffinity(
  Mem *pRec,          /* The value to apply affinity to */
  char affinity,      /* The affinity to be applied */
  u8 enc              /* Use this text encoding */
){
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393

394
395
396
397
398
399
400
356
357
358
359
360
361
362

363



364
365
366

367
368
369
370
371
372
373
374







-
+
-
-
-



-
+







  }else if( affinity==SQLITE_AFF_TEXT ){
    /* Only attempt the conversion to TEXT if there is an integer or real
    ** representation (blob and NULL do not get converted) but no string
    ** representation.  It would be harmless to repeat the conversion if 
    ** there is already a string rep, but it is pointless to waste those
    ** CPU cycles. */
    if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
      if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
      if( (pRec->flags&(MEM_Real|MEM_Int)) ){
        testcase( pRec->flags & MEM_Int );
        testcase( pRec->flags & MEM_Real );
        testcase( pRec->flags & MEM_IntReal );
        sqlite3VdbeMemStringify(pRec, enc, 1);
      }
    }
    pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
    pRec->flags &= ~(MEM_Real|MEM_Int);
  }
}

/*
** Try to convert the type of a function argument or a result column
** into a numeric representation.  Use either INTEGER or REAL whichever
** is appropriate.  But only do the conversion if it is possible without
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
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







-
-
-
+


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













-
+
-
-
-
-
+


-
-










-
+
+

+

+















+
-
-
-
+
+
+
+
+

-
-
+

-
+
+

-
+

-
+
+

+

-
-
+
+

-
+


-
+


-
+


-
+

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















-
-




-
+




-
-
+
-
-
-
+
+




-
+

-
-
-




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







/*
** pMem currently only holds a string type (or maybe a BLOB that we can
** interpret as a string if we want to).  Compute its corresponding
** numeric type, if has one.  Set the pMem->u.r and pMem->u.i fields
** accordingly.
*/
static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
  int rc;
  sqlite3_int64 ix;
  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 );
  assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
  assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
  ExpandBlob(pMem);
  rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
  if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
  if( rc<=0 ){
    if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){
      pMem->u.i = ix;
      return MEM_Int;
    return 0;
    }else{
      return MEM_Real;
    }
  }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){
  }
  if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){
    pMem->u.i = ix;
    return MEM_Int;
  }
  return MEM_Real;
}

/*
** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or
** none.  
**
** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
** But it does set pMem->u.r and pMem->u.i appropriately.
*/
static u16 numericType(Mem *pMem){
  if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
  if( pMem->flags & (MEM_Int|MEM_Real) ){
    testcase( pMem->flags & MEM_Int );
    testcase( pMem->flags & MEM_Real );
    testcase( pMem->flags & MEM_IntReal );
    return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
    return pMem->flags & (MEM_Int|MEM_Real);
  }
  if( pMem->flags & (MEM_Str|MEM_Blob) ){
    testcase( pMem->flags & MEM_Str );
    testcase( pMem->flags & MEM_Blob );
    return computeNumericType(pMem);
  }
  return 0;
}

#ifdef SQLITE_DEBUG
/*
** Write a nice string representation of the contents of cell pMem
** into buffer zBuf, length nBuf.
*/
void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
  char *zCsr = zBuf;
  int f = pMem->flags;

  static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};

  if( f&MEM_Blob ){
    int i;
    char c;
    if( f & MEM_Dyn ){
      c = 'z';
      assert( (f & (MEM_Static|MEM_Ephem))==0 );
    }else if( f & MEM_Static ){
      c = 't';
      assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
    }else if( f & MEM_Ephem ){
      c = 'e';
      assert( (f & (MEM_Static|MEM_Dyn))==0 );
    }else{
      c = 's';
    }
    *(zCsr++) = c;
    sqlite3_str_appendf(pStr, "%cx[", c);
    for(i=0; i<25 && i<pMem->n; i++){
      sqlite3_str_appendf(pStr, "%02X", ((int)pMem->z[i] & 0xFF));
    sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
    zCsr += sqlite3Strlen30(zCsr);
    for(i=0; i<16 && i<pMem->n; i++){
      sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF));
      zCsr += sqlite3Strlen30(zCsr);
    }
    sqlite3_str_appendf(pStr, "|");
    for(i=0; i<25 && i<pMem->n; i++){
    for(i=0; i<16 && i<pMem->n; i++){
      char z = pMem->z[i];
      sqlite3_str_appendchar(pStr, 1, (z<32||z>126)?'.':z);
      if( z<32 || z>126 ) *zCsr++ = '.';
      else *zCsr++ = z;
    }
    sqlite3_str_appendf(pStr,"]");
    *(zCsr++) = ']';
    if( f & MEM_Zero ){
      sqlite3_str_appendf(pStr, "+%dz",pMem->u.nZero);
      sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
      zCsr += sqlite3Strlen30(zCsr);
    }
    *zCsr = '\0';
  }else if( f & MEM_Str ){
    int j;
    u8 c;
    int j, k;
    zBuf[0] = ' ';
    if( f & MEM_Dyn ){
      c = 'z';
      zBuf[1] = 'z';
      assert( (f & (MEM_Static|MEM_Ephem))==0 );
    }else if( f & MEM_Static ){
      c = 't';
      zBuf[1] = 't';
      assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
    }else if( f & MEM_Ephem ){
      c = 'e';
      zBuf[1] = 'e';
      assert( (f & (MEM_Static|MEM_Dyn))==0 );
    }else{
      c = 's';
      zBuf[1] = 's';
    }
    k = 2;
    sqlite3_str_appendf(pStr, " %c%d[", c, pMem->n);
    for(j=0; j<25 && j<pMem->n; j++){
      c = pMem->z[j];
      sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.');
    }
    sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]);
    sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n);
    k += sqlite3Strlen30(&zBuf[k]);
    zBuf[k++] = '[';
    for(j=0; j<15 && j<pMem->n; j++){
      u8 c = pMem->z[j];
      if( c>=0x20 && c<0x7f ){
        zBuf[k++] = c;
      }else{
        zBuf[k++] = '.';
      }
    }
    zBuf[k++] = ']';
    sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]);
    k += sqlite3Strlen30(&zBuf[k]);
    zBuf[k++] = 0;
  }
}
#endif

#ifdef SQLITE_DEBUG
/*
** Print the value of a register for tracing purposes:
*/
static void memTracePrint(Mem *p){
  if( p->flags & MEM_Undefined ){
    printf(" undefined");
  }else if( p->flags & MEM_Null ){
    printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
  }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
    printf(" si:%lld", p->u.i);
  }else if( (p->flags & (MEM_IntReal))!=0 ){
    printf(" ir:%lld", p->u.i);
  }else if( p->flags & MEM_Int ){
    printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
  }else if( p->flags & MEM_Real ){
    printf(" r:%.17g", p->u.r);
    printf(" r:%g", p->u.r);
#endif
  }else if( sqlite3VdbeMemIsRowSet(p) ){
    printf(" (rowset)");
  }else{
    StrAccum acc;
    char zBuf[1000];
    char zBuf[200];
    sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
    sqlite3VdbeMemPrettyPrint(p, &acc);
    printf(" %s", sqlite3StrAccumFinish(&acc));
    sqlite3VdbeMemPrettyPrint(p, zBuf);
    printf(" %s", zBuf);
  }
  if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
}
static void registerTrace(int iReg, Mem *p){
  printf("R[%d] = ", iReg);
  printf("REG[%d] = ", iReg);
  memTracePrint(p);
  if( p->pScopyFrom ){
    printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg]));
  }
  printf("\n");
  sqlite3VdbeCheckMemInvariants(p);
}
#endif

#ifdef SQLITE_DEBUG
/*
** Show the values of all registers in the virtual machine.  Used for
** interactive debugging.
*/
void sqlite3VdbeRegisterDump(Vdbe *v){
  int i;
  for(i=1; i<v->nMem; i++) registerTrace(i, v->aMem+i);
}
#endif /* SQLITE_DEBUG */


#ifdef SQLITE_DEBUG
#  define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M)
#else
#  define REGISTER_TRACE(R,M)
#endif

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







-
+

-
+











-
+







-
+








-
-





-
+







  int nExtraDelete = 0;      /* Verifies FORDELETE and AUXDELETE flags */
#endif
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
  u8 encoding = ENC(db);     /* The database encoding */
  int iCompare = 0;          /* Result of last comparison */
  u64 nVmStep = 0;           /* Number of virtual machine steps */
  unsigned nVmStep = 0;      /* Number of virtual machine steps */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  u64 nProgressLimit;        /* Invoke xProgress() when nVmStep reaches this */
  unsigned nProgressLimit;   /* Invoke xProgress() when nVmStep reaches this */
#endif
  Mem *aMem = p->aMem;       /* Copy of p->aMem */
  Mem *pIn1 = 0;             /* 1st input operand */
  Mem *pIn2 = 0;             /* 2nd input operand */
  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 */
  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{
    nProgressLimit = LARGEST_UINT64;
    nProgressLimit = 0xffffffff;
  }
#endif
  if( p->rc==SQLITE_NOMEM ){
    /* This happens if a malloc() inside a call to sqlite3_column_text() or
    ** sqlite3_column_text16() failed.  */
    goto no_mem;
  }
  assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
  testcase( p->rc!=SQLITE_OK );
  p->rc = SQLITE_OK;
  assert( p->bIsReader || p->readOnly!=0 );
  p->iCurrentTime = 0;
  assert( p->explain==0 );
  p->pResultSet = 0;
  db->busyHandler.nBusy = 0;
  if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
  if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
  sqlite3VdbeIOTraceSql(p);
#ifdef SQLITE_DEBUG
  sqlite3BeginBenignMalloc();
  if( p->pc==0
   && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0
  ){
    int i;
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
706
707
708
709
710
711
712

713
714
715
716
717
718
719







-







#endif

    /* Only allow tracing if SQLITE_DEBUG is defined.
    */
#ifdef SQLITE_DEBUG
    if( db->flags & SQLITE_VdbeTrace ){
      sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
      test_trace_breakpoint((int)(pOp - aOp),pOp,p);
    }
#endif
      

    /* Check to see if we need to simulate an interrupt.  This only happens
    ** if we have a special test build.
    */
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
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







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














-
+











-
+







**
** The P1 parameter is not actually used by this opcode.  However, it
** is sometimes set to 1 instead of 0 as a hint to the command-line shell
** that this Goto is the bottom of a loop and that the lines from P2 down
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: {             /* jump */

#ifdef SQLITE_DEBUG
  /* In debuggging mode, when the p5 flags is set on an OP_Goto, that
  ** means we should really jump back to the preceeding OP_ReleaseReg
  ** instruction. */
  if( pOp->p5 ){
    assert( pOp->p2 < (int)(pOp - aOp) );
    assert( pOp->p2 > 1 );
    pOp = &aOp[pOp->p2 - 2];
    assert( pOp[1].opcode==OP_ReleaseReg );
    goto check_for_interrupt;
  }
#endif

jump_to_p2_and_check_for_interrupt:
  pOp = &aOp[pOp->p2 - 1];

  /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
  ** OP_VNext, or OP_SorterNext) all jump here upon
  ** completion.  Check to see if sqlite3_interrupt() has been called
  ** or if the progress callback needs to be invoked. 
  **
  ** This code uses unstructured "goto" statements and does not look clean.
  ** But that is not due to sloppy coding habits. The code is written this
  ** way for performance, to avoid having to run the interrupt and progress
  ** checks on every opcode.  This helps sqlite3_step() to run about 1.5%
  ** faster according to "valgrind --tool=cachegrind" */
check_for_interrupt:
  if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
  if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  /* Call the progress callback if it is configured and the required number
  ** of VDBE ops have been executed (either since this invocation of
  ** sqlite3VdbeExec() or since last time the progress callback was called).
  ** If the progress callback returns non-zero, exit the virtual machine with
  ** a return code SQLITE_ABORT.
  */
  while( nVmStep>=nProgressLimit && db->xProgress!=0 ){
    assert( db->nProgressOps!=0 );
    nProgressLimit += db->nProgressOps;
    if( db->xProgress(db->pProgressArg) ){
      nProgressLimit = LARGEST_UINT64;
      nProgressLimit = 0xffffffff;
      rc = SQLITE_INTERRUPT;
      goto abort_due_to_error;
    }
  }
#endif
  
  break;
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
967
968
969
970
971
972
973

974
975
976
977
978
979
980







-







case OP_HaltIfNull: {      /* in3 */
  pIn3 = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
  if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
#endif
  if( (pIn3->flags & MEM_Null)==0 ) break;
  /* Fall through into OP_Halt */
  /* no break */ deliberate_fall_through
}

/* Opcode:  Halt P1 P2 * P4 P5
**
** Exit immediately.  All open cursors, etc are closed
** automatically.
**
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125







+







** into a String opcode before it is executed for the first time.  During
** this transformation, the length of string P4 is computed and stored
** as the P1 parameter.
*/
case OP_String8: {         /* same as TK_STRING, out2 */
  assert( pOp->p4.z!=0 );
  pOut = out2Prerelease(p, pOp);
  pOp->opcode = OP_String;
  pOp->p1 = sqlite3Strlen30(pOp->p4.z);

#ifndef SQLITE_OMIT_UTF16
  if( encoding!=SQLITE_UTF8 ){
    rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
    assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG );
    if( rc ) goto too_big;
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1135
1136
1137
1138
1139
1140
1141

1142
1143

1144
1145
1146
1147
1148
1149
1150







-


-







    pOp->p4.z = pOut->z;
    pOp->p1 = pOut->n;
  }
#endif
  if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }
  pOp->opcode = OP_String;
  assert( rc==SQLITE_OK );
  /* Fall through to the next case, OP_String */
  /* no break */ deliberate_fall_through
}
  
/* Opcode: String P1 P2 P3 P4 P5
** Synopsis: r[P2]='P4' (len=P1)
**
** The string value P4 of length P1 (bytes) is stored in register P2.
**
1348
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359

1360
1361
1362
1363
1364
1365
1366
1367
1368
1289
1290
1291
1292
1293
1294
1295

1296




1297


1298
1299
1300
1301
1302
1303
1304







-
+
-
-
-
-
+
-
-







  do{
    assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] );
    assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] );
    assert( memIsValid(pIn1) );
    memAboutToChange(p, pOut);
    sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
    pIn1->pScopyFrom = 0;
    if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
    { int i;
      for(i=1; i<p->nMem; i++){
        if( aMem[i].pScopyFrom==pIn1 ){
          aMem[i].pScopyFrom = pOut;
      pOut->pScopyFrom += pOp->p2 - p1;
        }
      }
    }
#endif
    Deephemeralize(pOut);
    REGISTER_TRACE(p2++, pOut);
    pIn1++;
    pOut++;
  }while( --n );
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477




























1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506

1507
1508
1509
1510
1511
1512
1513
1514
1515
1372
1373
1374
1375
1376
1377
1378




















1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437








1438
1439
1440
1441

1442
1443

1444
1445
1446
1447
1448
1449
1450







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















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
















-
-
-
-
-
-
-
-




-
+

-







  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 );

  /* 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.
  */
  pMem = p->pResultSet = &aMem[pOp->p1];
  for(i=0; i<pOp->p2; i++){
    assert( memIsValid(&pMem[i]) );
    Deephemeralize(&pMem[i]);
    assert( (pMem[i].flags & MEM_Ephem)==0
            || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
    sqlite3VdbeMemNulTerminate(&pMem[i]);
    REGISTER_TRACE(pOp->p1+i, &pMem[i]);
#ifdef SQLITE_DEBUG
    /* The registers in the result will not be used again when the
    ** prepared statement restarts.  This is because sqlite3_column()
    ** APIs might have caused type conversions of made other changes to
    ** the register values.  Therefore, we can go ahead and break any
    ** OP_SCopy dependencies. */
    pMem[i].pScopyFrom = 0;
#endif
  }
  if( db->mallocFailed ) goto no_mem;

  if( db->mTrace & SQLITE_TRACE_ROW ){
    db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
    db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
  }


  /* Return SQLITE_ROW
  */
  p->pc = (int)(pOp - aOp) + 1;
  rc = SQLITE_ROW;
  goto vdbe_return;
}
1524
1525
1526
1527
1528
1529
1530
1531

1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543

1544
1545
1546
1547
1548
1549
1550
1551
1552


1553
1554
1555
1556

1557
1558
1559
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1459
1460
1461
1462
1463
1464
1465

1466


1467
1468
1469
1470

1471




1472
1473
1474
1475






1476
1477




1478





1479
1480
1481
1482

1483
1484
1485
1486
1487
1488


1489
1490


1491
1492

1493
1494
1495
1496
1497
1498
1499







-
+
-
-




-

-
-
-
-
+



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




-
+





-
-


-
-


-







**   P3 = P2 || P1
**
** It is illegal for P1 and P3 to be the same register. Sometimes,
** if P3 is the same register as P2, the implementation is able
** to avoid a memcpy().
*/
case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */
  i64 nByte;          /* Total size of the output string or blob */
  i64 nByte;
  u16 flags1;         /* Initial flags for P1 */
  u16 flags2;         /* Initial flags for P2 */

  pIn1 = &aMem[pOp->p1];
  pIn2 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  testcase( pOut==pIn2 );
  assert( pIn1!=pOut );
  flags1 = pIn1->flags;
  testcase( flags1 & MEM_Null );
  testcase( pIn2->flags & MEM_Null );
  if( (flags1 | pIn2->flags) & MEM_Null ){
  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
    sqlite3VdbeMemSetNull(pOut);
    break;
  }
  if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
    if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
    flags1 = pIn1->flags & ~MEM_Str;
  }else if( (flags1 & MEM_Zero)!=0 ){
    if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
    flags1 = pIn1->flags & ~MEM_Str;
  if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
  Stringify(pIn1, encoding);
  }
  flags2 = pIn2->flags;
  if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
    if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
  Stringify(pIn2, encoding);
    flags2 = pIn2->flags & ~MEM_Str;
  }else if( (flags2 & MEM_Zero)!=0 ){
    if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
    flags2 = pIn2->flags & ~MEM_Str;
  }
  nByte = pIn1->n + pIn2->n;
  if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }
  if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){
  if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
    goto no_mem;
  }
  MemSetTypeFlag(pOut, MEM_Str);
  if( pOut!=pIn2 ){
    memcpy(pOut->z, pIn2->z, pIn2->n);
    assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
    pIn2->flags = flags2;
  }
  memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
  assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
  pIn1->flags = flags1;
  pOut->z[nByte]=0;
  pOut->z[nByte+1] = 0;
  pOut->z[nByte+2] = 0;
  pOut->flags |= MEM_Term;
  pOut->n = (int)nByte;
  pOut->enc = encoding;
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

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
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568







+

















+







** If either operand is NULL, the result is NULL.
*/
case OP_Add:                   /* same as TK_PLUS, in1, in2, out3 */
case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
  char bIntint;   /* Started out as two integer operands */
  u16 flags;      /* Combined MEM_* flags from both inputs */
  u16 type1;      /* Numeric type of left operand */
  u16 type2;      /* Numeric type of right operand */
  i64 iA;         /* Integer value of left operand */
  i64 iB;         /* Integer value of right operand */
  double rA;      /* Real value of left operand */
  double rB;      /* Real value of right operand */

  pIn1 = &aMem[pOp->p1];
  type1 = numericType(pIn1);
  pIn2 = &aMem[pOp->p2];
  type2 = numericType(pIn2);
  pOut = &aMem[pOp->p3];
  flags = pIn1->flags | pIn2->flags;
  if( (type1 & type2 & MEM_Int)!=0 ){
    iA = pIn1->u.i;
    iB = pIn2->u.i;
    bIntint = 1;
    switch( pOp->opcode ){
      case OP_Add:       if( sqlite3AddInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Subtract:  if( sqlite3SubInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Multiply:  if( sqlite3MulInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Divide: {
        if( iA==0 ) goto arithmetic_result_is_null;
        if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math;
1663
1664
1665
1666
1667
1668
1669

1670
1671
1672
1673
1674
1675
1676
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591







+







      }
    }
    pOut->u.i = iB;
    MemSetTypeFlag(pOut, MEM_Int);
  }else if( (flags & MEM_Null)!=0 ){
    goto arithmetic_result_is_null;
  }else{
    bIntint = 0;
fp_math:
    rA = sqlite3VdbeRealValue(pIn1);
    rB = sqlite3VdbeRealValue(pIn2);
    switch( pOp->opcode ){
      case OP_Add:         rB += rA;       break;
      case OP_Subtract:    rB -= rA;       break;
      case OP_Multiply:    rB *= rA;       break;
1694
1695
1696
1697
1698
1699
1700



1701
1702
1703
1704
1705
1706
1707
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625







+
+
+







    MemSetTypeFlag(pOut, MEM_Int);
#else
    if( sqlite3IsNaN(rB) ){
      goto arithmetic_result_is_null;
    }
    pOut->u.r = rB;
    MemSetTypeFlag(pOut, MEM_Real);
    if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
      sqlite3VdbeIntegerAffinity(pOut);
    }
#endif
  }
  break;

arithmetic_result_is_null:
  sqlite3VdbeMemSetNull(pOut);
  break;
1862
1863
1864
1865
1866
1867
1868
1869
1870

1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1780
1781
1782
1783
1784
1785
1786


1787

1788

1789
1790
1791
1792
1793
1794
1795







-
-
+
-

-







** This opcode is used when extracting information from a column that
** has REAL affinity.  Such column values may still be stored as
** integers, for space efficiency, but after extraction we want them
** to have only a real value.
*/
case OP_RealAffinity: {                  /* in1 */
  pIn1 = &aMem[pOp->p1];
  if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
    testcase( pIn1->flags & MEM_Int );
  if( pIn1->flags & MEM_Int ){
    testcase( pIn1->flags & MEM_IntReal );
    sqlite3VdbeMemRealify(pIn1);
    REGISTER_TRACE(pOp->p1, pIn1);
  }
  break;
}
#endif

#ifndef SQLITE_OMIT_CAST
/* Opcode: Cast P1 P2 * * *
1898
1899
1900
1901
1902
1903
1904
1905
1906

1907
1908
1909

1910
1911
1912
1913
1914
1915
1916
1813
1814
1815
1816
1817
1818
1819


1820

1821

1822
1823
1824
1825
1826
1827
1828
1829







-
-
+
-

-
+







  testcase( pOp->p2==SQLITE_AFF_BLOB );
  testcase( pOp->p2==SQLITE_AFF_NUMERIC );
  testcase( pOp->p2==SQLITE_AFF_INTEGER );
  testcase( pOp->p2==SQLITE_AFF_REAL );
  pIn1 = &aMem[pOp->p1];
  memAboutToChange(p, pIn1);
  rc = ExpandBlob(pIn1);
  if( rc ) goto abort_due_to_error;
  rc = sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
  sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
  if( rc ) goto abort_due_to_error;
  UPDATE_MAX_BLOBSIZE(pIn1);
  REGISTER_TRACE(pOp->p1, pIn1);
  if( rc ) goto abort_due_to_error;
  break;
}
#endif /* SQLITE_OMIT_CAST */

/* Opcode: Eq P1 P2 P3 P4 P5
** Synopsis: IF r[P3]==r[P1]
**
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
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







-
+

-
+
+
+
+
+
+


-
+












-
+


-



-
+

-
+


-







      break;
    }
  }else{
    /* Neither operand is NULL.  Do a comparison. */
    affinity = pOp->p5 & SQLITE_AFF_MASK;
    if( affinity>=SQLITE_AFF_NUMERIC ){
      if( (flags1 | flags3)&MEM_Str ){
        if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
        if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
          applyNumericAffinity(pIn1,0);
          testcase( flags3==pIn3->flags );
          assert( flags3==pIn3->flags );
          /* testcase( flags3!=pIn3->flags );
          ** this used to be possible with pIn1==pIn3, but not since
          ** the column cache was removed.  The following assignment
          ** is essentially a no-op.  But, it provides defense-in-depth
          ** in case our analysis is incorrect, so it is left in. */
          flags3 = pIn3->flags;
        }
        if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
        if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
          applyNumericAffinity(pIn3,0);
        }
      }
      /* Handle the common case of integer comparison here, as an
      ** optimization, to avoid a call to sqlite3MemCompare() */
      if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){
        if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; }
        if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
        res = 0;
        goto compare_op;
      }
    }else if( affinity==SQLITE_AFF_TEXT ){
      if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
      if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
        testcase( pIn1->flags & MEM_Int );
        testcase( pIn1->flags & MEM_Real );
        testcase( pIn1->flags & MEM_IntReal );
        sqlite3VdbeMemStringify(pIn1, encoding, 1);
        testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
        flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
        if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
        assert( pIn1!=pIn3 );
      }
      if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
      if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
        testcase( pIn3->flags & MEM_Int );
        testcase( pIn3->flags & MEM_Real );
        testcase( pIn3->flags & MEM_IntReal );
        sqlite3VdbeMemStringify(pIn3, encoding, 1);
        testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
        flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
      }
    }
    assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
    res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129




2130
2131
2132
2133
2134
2135
2136
2035
2036
2037
2038
2039
2040
2041




2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052







-
-
-
-
+
+
+
+







    res2 = aEQb[pOp->opcode - OP_Ne];
  }else{
    static const unsigned char aGTb[] = { 1,  0,  1,  0,  0,  1 };
    res2 = aGTb[pOp->opcode - OP_Ne];
  }

  /* Undo any changes made by applyAffinity() to the input registers. */
  assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
  pIn3->flags = flags3;
  assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
  pIn1->flags = flags1;
  assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
  pIn1->flags = flags1;
  assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
  pIn3->flags = flags3;

  if( pOp->p5 & SQLITE_STOREP2 ){
    pOut = &aMem[pOp->p2];
    iCompare = res;
    if( (pOp->p5 & SQLITE_KEEPNULL)!=0 ){
      /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1
      ** and prevents OP_Ne from overwriting NULL with 0.  This flag
2158
2159
2160
2161
2162
2163
2164
2165

2166
2167
2168
2169
2170
2171
2172
2173
2174




2175
2176
2177

2178
2179
2180
2181
2182
2183
2184
2185
2186


2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2074
2075
2076
2077
2078
2079
2080

2081









2082
2083
2084
2085
2086
2087

2088









2089
2090



2091
2092
2093
2094
2095
2096
2097







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


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







    }
  }
  break;
}

/* Opcode: ElseNotEq * P2 * * *
**
** This opcode must follow an OP_Lt or OP_Gt comparison operator.  There
** This opcode must immediately follow an OP_Lt or OP_Gt comparison operator.
** can be zero or more OP_ReleaseReg opcodes intervening, but no other
** opcodes are allowed to occur between this instruction and the previous
** OP_Lt or OP_Gt.  Furthermore, the prior OP_Lt or OP_Gt must have the
** SQLITE_STOREP2 bit set in the P5 field.
**
** If result of an OP_Eq comparison on the same two operands as the
** prior OP_Lt or OP_Gt would have been NULL or false (0), then then
** jump to P2.  If the result of an OP_Eq comparison on the two previous
** operands would have been true (1), then fall through.
** If result of an OP_Eq comparison on the same two operands
** would have be NULL or false (0), then then jump to P2. 
** If the result of an OP_Eq comparison on the two previous operands
** would have been true (1), then fall through.
*/
case OP_ElseNotEq: {       /* same as TK_ESCAPE, jump */

  assert( pOp>aOp );
#ifdef SQLITE_DEBUG
  /* Verify the preconditions of this opcode - that it follows an OP_Lt or
  ** OP_Gt with the SQLITE_STOREP2 flag set, with zero or more intervening
  ** OP_ReleaseReg opcodes */
  int iAddr;
  for(iAddr = (int)(pOp - aOp) - 1; ALWAYS(iAddr>=0); iAddr--){
    if( aOp[iAddr].opcode==OP_ReleaseReg ) continue;
    assert( aOp[iAddr].opcode==OP_Lt || aOp[iAddr].opcode==OP_Gt );
    assert( aOp[iAddr].p5 & SQLITE_STOREP2 );
  assert( pOp[-1].opcode==OP_Lt || pOp[-1].opcode==OP_Gt );
  assert( pOp[-1].p5 & SQLITE_STOREP2 );
    break;
  }
#endif /* SQLITE_DEBUG */
  VdbeBranchTaken(iCompare!=0, 2);
  if( iCompare!=0 ) goto jump_to_p2;
  break;
}


/* Opcode: Permutation * * * P4 *
2235
2236
2237
2238
2239
2240
2241
2242

2243
2244
2245

2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265

2266
2267
2268
2269
2270
2271
2272
2273
2274

2275
2276
2277
2278
2279
2280
2281

2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2136
2137
2138
2139
2140
2141
2142

2143
2144
2145

2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165

2166
2167
2168
2169
2170
2171
2172
2173
2174

2175
2176
2177
2178
2179
2180
2181

2182
2183
2184





2185
2186
2187
2188
2189
2190
2191







-
+


-
+



















-
+








-
+






-
+


-
-
-
-
-







*/
case OP_Compare: {
  int n;
  int i;
  int p1;
  int p2;
  const KeyInfo *pKeyInfo;
  u32 idx;
  int idx;
  CollSeq *pColl;    /* Collating sequence to use on this term */
  int bRev;          /* True for DESCENDING sort order */
  u32 *aPermute;     /* The permutation */
  int *aPermute;     /* The permutation */

  if( (pOp->p5 & OPFLAG_PERMUTE)==0 ){
    aPermute = 0;
  }else{
    assert( pOp>aOp );
    assert( pOp[-1].opcode==OP_Permutation );
    assert( pOp[-1].p4type==P4_INTARRAY );
    aPermute = pOp[-1].p4.ai + 1;
    assert( aPermute!=0 );
  }
  n = pOp->p3;
  pKeyInfo = pOp->p4.pKeyInfo;
  assert( n>0 );
  assert( pKeyInfo!=0 );
  p1 = pOp->p1;
  p2 = pOp->p2;
#ifdef SQLITE_DEBUG
  if( aPermute ){
    int k, mx = 0;
    for(k=0; k<n; k++) if( aPermute[k]>(u32)mx ) mx = aPermute[k];
    for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
    assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 );
    assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 );
  }else{
    assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 );
    assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 );
  }
#endif /* SQLITE_DEBUG */
  for(i=0; i<n; i++){
    idx = aPermute ? aPermute[i] : (u32)i;
    idx = aPermute ? aPermute[i] : i;
    assert( memIsValid(&aMem[p1+idx]) );
    assert( memIsValid(&aMem[p2+idx]) );
    REGISTER_TRACE(p1+idx, &aMem[p1+idx]);
    REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
    assert( i<pKeyInfo->nKeyField );
    pColl = pKeyInfo->aColl[i];
    bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC);
    bRev = pKeyInfo->aSortOrder[i];
    iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
    if( iCompare ){
      if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) 
       && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null))
      ){
        iCompare = -iCompare;
      }
      if( bRev ) iCompare = -iCompare;
      break;
    }
  }
  break;
}

2571
2572
2573
2574
2575
2576
2577





2578
2579
2580
2581
2582
2583
2584
2585

2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603

2604
2605
2606
2607
2608
2609
2610
2611
2612
2613

2614
2615

2616
2617
2618
2619
2620
2621
2622
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485

2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500

2501


2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514

2515
2516
2517
2518
2519
2520
2521
2522







+
+
+
+
+







-
+














-

-
-
+










+

-
+







** values in the record, extract a NULL.
**
** The value extracted is stored in register P3.
**
** If the record contains fewer than P2 fields, then extract a NULL.  Or,
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.
**
** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
** then the cache of the cursor is reset prior to extracting the column.
** The first OP_Column against a pseudo-table after the value of the content
** register has changed should have this bit set.
**
** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then
** the result is guaranteed to only be used as the argument of a length()
** or typeof() function, respectively.  The loading of large blobs can be
** skipped for length() and all content loading can be skipped for typeof().
*/
case OP_Column: {
  u32 p2;            /* column number to retrieve */
  int p2;            /* column number to retrieve */
  VdbeCursor *pC;    /* The VDBE cursor */
  BtCursor *pCrsr;   /* The BTree cursor */
  u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  int len;           /* The length of the serialized data for the column */
  int i;             /* Loop counter */
  Mem *pDest;        /* Where to write the extracted value */
  Mem sMem;          /* For storing the record being decoded */
  const u8 *zData;   /* Part of the record being decoded */
  const u8 *zHdr;    /* Next unparsed byte of the header */
  const u8 *zEndHdr; /* Pointer to first byte after the header */
  u64 offset64;      /* 64-bit offset */
  u32 t;             /* A type code from the record header */
  Mem *pReg;         /* PseudoTable input register */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  p2 = (u32)pOp->p2;
  p2 = pOp->p2;

  /* If the cursor cache is stale (meaning it is not currently point at
  ** the correct row) then bring it up-to-date by doing the necessary 
  ** B-Tree seek. */
  rc = sqlite3VdbeCursorMoveto(&pC, &p2);
  if( rc ) goto abort_due_to_error;

  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  pDest = &aMem[pOp->p3];
  memAboutToChange(p, pDest);
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pC!=0 );
  assert( p2<(u32)pC->nField );
  assert( p2<pC->nField );
  aOffset = pC->aOffset;
  assert( pC->eCurType!=CURTYPE_VTAB );
  assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
  assert( pC->eCurType!=CURTYPE_SORTER );

  if( pC->cacheStatus!=p->cacheCtr ){                /*OPTIMIZATION-IF-FALSE*/
    if( pC->nullRow ){
2699
2700
2701
2702
2703
2704
2705
2706

2707
2708
2709
2710
2711
2712
2713
2599
2600
2601
2602
2603
2604
2605

2606
2607
2608
2609
2610
2611
2612
2613







-
+







    /* If there is more header available for parsing in the record, try
    ** to extract additional fields up through the p2+1-th field 
    */
    if( pC->iHdrOffset<aOffset[0] ){
      /* Make sure zData points to enough of the record to cover the header. */
      if( pC->aRow==0 ){
        memset(&sMem, 0, sizeof(sMem));
        rc = sqlite3VdbeMemFromBtreeZeroOffset(pC->uc.pCursor,aOffset[0],&sMem);
        rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        zData = (u8*)sMem.z;
      }else{
        zData = pC->aRow;
      }
  
      /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */
2723
2724
2725
2726
2727
2728
2729
2730

2731
2732
2733
2734
2735
2736
2737
2623
2624
2625
2626
2627
2628
2629

2630
2631
2632
2633
2634
2635
2636
2637







-
+







          offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
        }else{
          zHdr += sqlite3GetVarint32(zHdr, &t);
          pC->aType[i] = t;
          offset64 += sqlite3VdbeSerialTypeLen(t);
        }
        aOffset[++i] = (u32)(offset64 & 0xffffffff);
      }while( (u32)i<=p2 && zHdr<zEndHdr );
      }while( i<=p2 && zHdr<zEndHdr );

      /* The record is corrupt if any of the following are true:
      ** (1) the bytes of the header extend past the declared header size
      ** (2) the entire header was used but not all data was used
      ** (3) the end of the data extends beyond the end of the record.
      */
      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
2817
2818
2819
2820
2821
2822
2823
2824

2825
2826
2827

2828

2829
2830
2831
2832
2833
2834
2835
2717
2718
2719
2720
2721
2722
2723

2724


2725
2726

2727
2728
2729
2730
2731
2732
2733
2734







-
+
-
-

+
-
+







      **    2. the length(X) function if X is a blob, and
      **    3. if the content length is zero.
      ** So we might as well use bogus content rather than reading
      ** content from disk. 
      **
      ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the
      ** buffer passed to it, debugging function VdbeMemPrettyPrint() may
      ** read more.  Use the global constant sqlite3CtypeMap[] as the array,
      ** read up to 16. So 16 bytes of bogus content is supplied.
      ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
      ** and it begins with a bunch of zeros.
      */
      static u8 aZero[16];  /* This is the bogus content */
      sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
      sqlite3VdbeSerialGet(aZero, t, pDest);
    }else{
      rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
      pDest->flags &= ~MEM_Ephem;
    }
  }
2862
2863
2864
2865
2866
2867
2868
2869

2870
2871
2872


2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895

2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926

2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938


2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2761
2762
2763
2764
2765
2766
2767

2768
2769


2770
2771





















2772

2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791











2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809


2810
2811
2812
2813
2814
2815
2816







-
+

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

-
+


















-
-
-
-
-
-
-
-
-
-
-


+












+
+

-
-







  const char *zAffinity;   /* The affinity to be applied */

  zAffinity = pOp->p4.z;
  assert( zAffinity!=0 );
  assert( pOp->p2>0 );
  assert( zAffinity[pOp->p2]==0 );
  pIn1 = &aMem[pOp->p1];
  while( 1 /*exit-by-break*/ ){
  do{
    assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
    assert( zAffinity[0]==SQLITE_AFF_NONE || memIsValid(pIn1) );
    applyAffinity(pIn1, zAffinity[0], encoding);
    assert( memIsValid(pIn1) );
    applyAffinity(pIn1, *(zAffinity++), encoding);
    if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
      /* When applying REAL affinity, if the result is still an MEM_Int
      ** that will fit in 6 bytes, then change the type to MEM_IntReal
      ** so that we keep the high-resolution integer value but know that
      ** the type really wants to be REAL. */
      testcase( pIn1->u.i==140737488355328LL );
      testcase( pIn1->u.i==140737488355327LL );
      testcase( pIn1->u.i==-140737488355328LL );
      testcase( pIn1->u.i==-140737488355329LL );
      if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL ){
        pIn1->flags |= MEM_IntReal;
        pIn1->flags &= ~MEM_Int;
      }else{
        pIn1->u.r = (double)pIn1->u.i;
        pIn1->flags |= MEM_Real;
        pIn1->flags &= ~MEM_Int;
      }
    }
    REGISTER_TRACE((int)(pIn1-aMem), pIn1);
    zAffinity++;
    if( zAffinity[0]==0 ) break;
    pIn1++;
  }
  }while( zAffinity[0] );
  break;
}

/* Opcode: MakeRecord P1 P2 P3 P4 *
** Synopsis: r[P3]=mkrec(r[P1@P2])
**
** Convert P2 registers beginning with P1 into the [record format]
** use as a data record in a database table or as a key
** in an index.  The OP_Column opcode can decode the record later.
**
** P4 may be a string that is P2 characters long.  The N-th character of the
** string indicates the column affinity that should be used for the N-th
** field of the index key.
**
** The mapping from character to affinity is given by the SQLITE_AFF_
** macros defined in sqliteInt.h.
**
** If P4 is NULL then all index fields have the affinity BLOB.
**
** The meaning of P5 depends on whether or not the SQLITE_ENABLE_NULL_TRIM
** compile-time option is enabled:
**
**   * If SQLITE_ENABLE_NULL_TRIM is enabled, then the P5 is the index
**     of the right-most table that can be null-trimmed.
**
**   * If SQLITE_ENABLE_NULL_TRIM is omitted, then P5 has the value
**     OPFLAG_NOCHNG_MAGIC if the OP_MakeRecord opcode is allowed to
**     accept no-change records with serial_type 10.  This value is
**     only used inside an assert() and does not affect the end result.
*/
case OP_MakeRecord: {
  u8 *zNewRecord;        /* A buffer to hold the data for the new record */
  Mem *pRec;             /* The new record */
  u64 nData;             /* Number of bytes of data space */
  int nHdr;              /* Number of bytes of header space */
  i64 nByte;             /* Data space required for this record */
  i64 nZero;             /* Number of zero bytes at the end of the record */
  int nVarint;           /* Number of bytes in a varint */
  u32 serial_type;       /* Type field */
  Mem *pData0;           /* First field to be combined into the record */
  Mem *pLast;            /* Last field of the record */
  int nField;            /* Number of fields in the record */
  char *zAffinity;       /* The affinity string for the record */
  int file_format;       /* File format to use for encoding */
  int i;                 /* Space used in zNewRecord[] header */
  int j;                 /* Space used in zNewRecord[] content */
  u32 len;               /* Length of a field */
  u8 *zHdr;              /* Where to write next byte of the header */
  u8 *zPayload;          /* Where to write next byte of the payload */

  /* Assuming the record contains N fields, the record format looks
  ** like this:
  **
  ** ------------------------------------------------------------------------
  ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | 
  ** ------------------------------------------------------------------------
2973
2974
2975
2976
2977
2978
2979
2980

2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007

3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036



3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113



3114
3115
3116
3117
3118
3119
3120
3121










3122
3123
3124
3125
3126
3127
3128
3129
2841
2842
2843
2844
2845
2846
2847

2848







2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867

2868























2869
2870
2871
2872


2873
2874
2875
2876
2877
2878
2879
2880
2881

2882





































































2883
2884
2885








2886
2887
2888
2889
2890
2891
2892
2893
2894
2895

2896
2897
2898
2899
2900
2901
2902







-
+
-
-
-
-
-
-
-



















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




-
-
+
+
+






-

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








  /* Apply the requested affinity to all inputs
  */
  assert( pData0<=pLast );
  if( zAffinity ){
    pRec = pData0;
    do{
      applyAffinity(pRec, zAffinity[0], encoding);
      applyAffinity(pRec++, *(zAffinity++), encoding);
      if( zAffinity[0]==SQLITE_AFF_REAL && (pRec->flags & MEM_Int) ){
        pRec->flags |= MEM_IntReal;
        pRec->flags &= ~(MEM_Int);
      }
      REGISTER_TRACE((int)(pRec-aMem), pRec);
      zAffinity++;
      pRec++;
      assert( zAffinity[0]==0 || pRec<=pLast );
    }while( zAffinity[0] );
  }

#ifdef SQLITE_ENABLE_NULL_TRIM
  /* NULLs can be safely trimmed from the end of the record, as long as
  ** as the schema format is 2 or more and none of the omitted columns
  ** have a non-NULL default value.  Also, the record must be left with
  ** at least one field.  If P5>0 then it will be one more than the
  ** index of the right-most column with a non-NULL default value */
  if( pOp->p5 ){
    while( (pLast->flags & MEM_Null)!=0 && nField>pOp->p5 ){
      pLast--;
      nField--;
    }
  }
#endif

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.  After this loop,
  ** out how much space is required for the new record.
  ** the Mem.uTemp field of each term should hold the serial-type that will
  ** be used for that term in the generated record:
  **
  **   Mem.uTemp value    type
  **   ---------------    ---------------
  **      0               NULL
  **      1               1-byte signed integer
  **      2               2-byte signed integer
  **      3               3-byte signed integer
  **      4               4-byte signed integer
  **      5               6-byte signed integer
  **      6               8-byte signed integer
  **      7               IEEE float
  **      8               Integer constant 0
  **      9               Integer constant 1
  **     10,11            reserved for expansion
  **    N>=12 and even    BLOB
  **    N>=13 and odd     text
  **
  ** The following additional values are computed:
  **     nHdr        Number of bytes needed for the record header
  **     nData       Number of bytes of data space needed for the record
  **     nZero       Zero bytes at the end of the record
  */
  pRec = pLast;
  do{
    assert( memIsValid(pRec) );
    if( pRec->flags & MEM_Null ){
      if( pRec->flags & MEM_Zero ){
    serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
    if( pRec->flags & MEM_Zero ){
      if( serial_type==0 ){
        /* Values with MEM_Null and MEM_Zero are created by xColumn virtual
        ** table methods that never invoke sqlite3_result_xxxxx() while
        ** computing an unchanging column value in an UPDATE statement.
        ** Give such values a special internal-use-only serial-type of 10
        ** so that they can be passed through to xUpdate and have
        ** a true sqlite3_value_nochange(). */
#ifndef SQLITE_ENABLE_NULL_TRIM
        assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
#endif
        pRec->uTemp = 10;
      }else{
        pRec->uTemp = 0;
      }
      nHdr++;
    }else if( pRec->flags & (MEM_Int|MEM_IntReal) ){
      /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
      i64 i = pRec->u.i;
      u64 uu;
      testcase( pRec->flags & MEM_Int );
      testcase( pRec->flags & MEM_IntReal );
      if( i<0 ){
        uu = ~i;
      }else{
        uu = i;
      }
      nHdr++;
      testcase( uu==127 );               testcase( uu==128 );
      testcase( uu==32767 );             testcase( uu==32768 );
      testcase( uu==8388607 );           testcase( uu==8388608 );
      testcase( uu==2147483647 );        testcase( uu==2147483648 );
      testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
      if( uu<=127 ){
        if( (i&1)==i && file_format>=4 ){
          pRec->uTemp = 8+(u32)uu;
        }else{
          nData++;
          pRec->uTemp = 1;
        }
      }else if( uu<=32767 ){
        nData += 2;
        pRec->uTemp = 2;
      }else if( uu<=8388607 ){
        nData += 3;
        pRec->uTemp = 3;
      }else if( uu<=2147483647 ){
        nData += 4;
        pRec->uTemp = 4;
      }else if( uu<=140737488355327LL ){
        nData += 6;
        pRec->uTemp = 5;
      }else{
        nData += 8;
        if( pRec->flags & MEM_IntReal ){
          /* If the value is IntReal and is going to take up 8 bytes to store
          ** as an integer, then we might as well make it an 8-byte floating
          ** point value */
          pRec->u.r = (double)pRec->u.i;
          pRec->flags &= ~MEM_IntReal;
          pRec->flags |= MEM_Real;
          pRec->uTemp = 7;
        }else{
          pRec->uTemp = 6;
        }
      }
    }else if( pRec->flags & MEM_Real ){
      nHdr++;
      nData += 8;
      pRec->uTemp = 7;
    }else{
      assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) );
      assert( pRec->n>=0 );
      len = (u32)pRec->n;
      serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0);
      if( pRec->flags & MEM_Zero ){
        serial_type += pRec->u.nZero*2;
        if( nData ){
          if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
        serial_type = 10;
      }else if( nData ){
        if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
          len += pRec->u.nZero;
        }else{
          nZero += pRec->u.nZero;
        }
      }
      nData += len;
      nHdr += sqlite3VarintLen(serial_type);
      pRec->uTemp = serial_type;
      }else{
        nZero += pRec->u.nZero;
        len -= pRec->u.nZero;
      }
    }
    nData += len;
    testcase( serial_type==127 );
    testcase( serial_type==128 );
    nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
    pRec->uTemp = serial_type;
    }
    if( pRec==pData0 ) break;
    pRec--;
  }while(1);

  /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
  ** which determines the total number of bytes in the header. The varint
  ** value is the size of the header in bytes including the size varint
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170

3171
3172
3173
3174


3175
3176
3177
3178
3179
3180
3181

3182
3183
3184

3185
3186
3187


3188
3189






3190

3191
3192
3193
3194

3195
3196
3197
3198

3199
3200
3201
3202
3203

3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216



3217
3218
3219
3220

3221

3222
3223
3224
3225
3226

3227
3228

3229
3230
3231
3232
3233
3234
3235
2929
2930
2931
2932
2933
2934
2935








2936

2937
2938

2939
2940
2941
2942
2943
2944
2945
2946

2947
2948
2949

2950
2951


2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966

2967
2968
2969
2970

2971




2972
2973
2974
2975
2976
2977
2978
2979
2980






2981
2982
2983

2984
2985

2986
2987
2988
2989
2990
2991
2992

2993


2994
2995
2996
2997
2998
2999
3000
3001







-
-
-
-
-
-
-
-
+
-


-
+
+






-
+


-
+

-
-
+
+


+
+
+
+
+
+

+



-
+



-
+
-
-
-
-

+







-
-
-
-
-
-
+
+
+
-


-
+

+




-
+
-
-
+







    if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
    if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
      goto no_mem;
    }
  }
  pOut->n = (int)nByte;
  pOut->flags = MEM_Blob;
  if( nZero ){
    pOut->u.nZero = nZero;
    pOut->flags |= MEM_Zero;
  }
  UPDATE_MAX_BLOBSIZE(pOut);
  zHdr = (u8 *)pOut->z;
  zNewRecord = (u8 *)pOut->z;
  zPayload = zHdr + nHdr;

  /* Write the record */
  zHdr += putVarint32(zHdr, nHdr);
  i = putVarint32(zNewRecord, nHdr);
  j = nHdr;
  assert( pData0<=pLast );
  pRec = pData0;
  do{
    serial_type = pRec->uTemp;
    /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
    ** additional varints, one per column. */
    zHdr += putVarint32(zHdr, serial_type);            /* serial type */
    i += putVarint32(&zNewRecord[i], serial_type);            /* serial type */
    /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
    ** immediately follow the header. */
    zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
    j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
  }while( (++pRec)<=pLast );
  assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
  assert( nByte==(int)(zPayload - (u8*)pOut->z) );
  assert( i==nHdr );
  assert( j==nByte );

  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  pOut->n = (int)nByte;
  pOut->flags = MEM_Blob;
  if( nZero ){
    pOut->u.nZero = nZero;
    pOut->flags |= MEM_Zero;
  }
  REGISTER_TRACE(pOp->p3, pOut);
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Count P1 P2 p3 * *
/* Opcode: Count P1 P2 * * *
** Synopsis: r[P2]=count()
**
** Store the number of entries (an integer value) in the table or index 
** opened by cursor P1 in register P2.
** opened by cursor P1 in register P2
**
** If P3==0, then an exact count is obtained, which involves visiting
** every btree page of the table.  But if P3 is non-zero, an estimate
** is returned based on the current cursor position.  
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: {         /* out2 */
  i64 nEntry;
  BtCursor *pCrsr;

  assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
  pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
  assert( pCrsr );
  if( pOp->p3 ){
    nEntry = sqlite3BtreeRowCountEst(pCrsr);
  }else{
    nEntry = 0;  /* Not needed.  Only used to silence a warning. */
    rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
    if( rc ) goto abort_due_to_error;
  nEntry = 0;  /* Not needed.  Only used to silence a warning. */
  rc = sqlite3BtreeCount(pCrsr, &nEntry);
  if( rc ) goto abort_due_to_error;
  }
  pOut = out2Prerelease(p, pOp);
  pOut->u.i = nEntry;
  goto check_for_interrupt;
  break;
}
#endif

/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
*/
case OP_Savepoint: {
  int p1;                         /* Value of P1 operand */
  char *zName;                    /* Name of savepoint */
  int nName;
  Savepoint *pNew;
  Savepoint *pSavepoint;
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3055
3056
3057
3058
3059
3060
3061

3062
3063
3064
3065
3066
3067
3068







-







        pNew->pNext = db->pSavepoint;
        db->pSavepoint = pNew;
        pNew->nDeferredCons = db->nDeferredCons;
        pNew->nDeferredImmCons = db->nDeferredImmCons;
      }
    }
  }else{
    assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK );
    iSavepoint = 0;

    /* Find the named savepoint. If there is no such savepoint, then an
    ** an error is returned to the user.  */
    for(
      pSavepoint = db->pSavepoint; 
      pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName);
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340

3341

3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3094
3095
3096
3097
3098
3099
3100





3101

3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114

3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128

3129
3130
3131
3132
3133
3134
3135







-
-
-
-
-
+
-
+












-














-







        db->autoCommit = 1;
        if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
          p->pc = (int)(pOp - aOp);
          db->autoCommit = 0;
          p->rc = rc = SQLITE_BUSY;
          goto vdbe_return;
        }
        rc = p->rc;
        if( rc ){
          db->autoCommit = 0;
        }else{
          db->isTransactionSavepoint = 0;
        db->isTransactionSavepoint = 0;
        }
        rc = p->rc;
      }else{
        int isSchemaChange;
        iSavepoint = db->nSavepoint - iSavepoint - 1;
        if( p1==SAVEPOINT_ROLLBACK ){
          isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0;
          for(ii=0; ii<db->nDb; ii++){
            rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
                                       SQLITE_ABORT_ROLLBACK,
                                       isSchemaChange==0);
            if( rc!=SQLITE_OK ) goto abort_due_to_error;
          }
        }else{
          assert( p1==SAVEPOINT_RELEASE );
          isSchemaChange = 0;
        }
        for(ii=0; ii<db->nDb; ii++){
          rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
          if( rc!=SQLITE_OK ){
            goto abort_due_to_error;
          }
        }
        if( isSchemaChange ){
          sqlite3ExpirePreparedStatements(db, 0);
          sqlite3ResetAllSchemasOfConnection(db);
          db->mDbFlags |= DBFLAG_SchemaChange;
        }
      }
      if( rc ) goto abort_due_to_error;
  
      /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all 
      ** savepoints nested inside of the savepoint being operated on. */
      while( db->pSavepoint!=pSavepoint ){
        pTmp = db->pSavepoint;
        db->pSavepoint = pTmp->pNext;
        sqlite3DbFree(db, pTmp);
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3144
3145
3146
3147
3148
3149
3150

3151
3152
3153
3154
3155
3156
3157







-







        assert( pSavepoint==db->pSavepoint );
        db->pSavepoint = pSavepoint->pNext;
        sqlite3DbFree(db, pSavepoint);
        if( !isTransaction ){
          db->nSavepoint--;
        }
      }else{
        assert( p1==SAVEPOINT_ROLLBACK );
        db->nDeferredCons = pSavepoint->nDeferredCons;
        db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
      }

      if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
        rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
3445
3446
3447
3448
3449
3450
3451

3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468

3469
3470
3471
3472
3473
3474
3475
3476
3477

3478
3479
3480
3481
3482
3483
3484
3485
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226

3227
3228
3229
3230
3231
3232
3233
3234
3235

3236

3237
3238
3239
3240
3241
3242
3243







+
















-
+








-
+
-







    }
    if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
      p->pc = (int)(pOp - aOp);
      db->autoCommit = (u8)(1-desiredAutoCommit);
      p->rc = rc = SQLITE_BUSY;
      goto vdbe_return;
    }
    assert( db->nStatement==0 );
    sqlite3CloseSavepoints(db);
    if( p->rc==SQLITE_OK ){
      rc = SQLITE_DONE;
    }else{
      rc = SQLITE_ERROR;
    }
    goto vdbe_return;
  }else{
    sqlite3VdbeError(p,
        (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
        (iRollback)?"cannot rollback - no transaction is active":
                   "cannot commit - no transaction is active"));
         
    rc = SQLITE_ERROR;
    goto abort_due_to_error;
  }
  /*NOTREACHED*/ assert(0);
  break;
}

/* Opcode: Transaction P1 P2 P3 P4 P5
**
** Begin a transaction on database P1 if a transaction is not already
** active.
** If P2 is non-zero, then a write-transaction is started, or if a 
** read-transaction is already active, it is upgraded to a write-transaction.
** If P2 is zero, then a read-transaction is started.  If P2 is 2 or more
** If P2 is zero, then a read-transaction is started.
** then an exclusive transaction is started.
**
** P1 is the index of the database file on which the transaction is
** started.  Index 0 is the main database file and index 1 is the
** file used for temporary tables.  Indices of 2 or more are used for
** attached databases.
**
** If a write-transaction is started and the Vdbe.usesStmtJournal flag is
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3263
3264
3265
3266
3267
3268
3269

3270
3271
3272
3273
3274
3275
3276







-







*/
case OP_Transaction: {
  Btree *pBt;
  int iMeta = 0;

  assert( p->bIsReader );
  assert( p->readOnly==0 || pOp->p2==0 );
  assert( pOp->p2>=0 && pOp->p2<=2 );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( DbMaskTest(p->btreeMask, pOp->p1) );
  if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
    rc = SQLITE_READONLY;
    goto abort_due_to_error;
  }
  pBt = db->aDb[pOp->p1].pBt;
3527
3528
3529
3530
3531
3532
3533
3534

3535
3536
3537
3538

3539
3540
3541
3542
3543
3544
3545
3284
3285
3286
3287
3288
3289
3290

3291

3292
3293

3294
3295
3296
3297
3298
3299
3300
3301







-
+
-


-
+







        p->pc = (int)(pOp - aOp);
        p->rc = rc;
        goto vdbe_return;
      }
      goto abort_due_to_error;
    }

    if( p->usesStmtJournal
    if( pOp->p2 && p->usesStmtJournal 
     && pOp->p2
     && (db->autoCommit==0 || db->nVdbeRead>1) 
    ){
      assert( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE );
      assert( sqlite3BtreeIsInTrans(pBt) );
      if( p->iStatement==0 ){
        assert( db->nStatement>=0 && db->nSavepoint>=0 );
        db->nStatement++; 
        p->iStatement = db->nSavepoint + db->nStatement;
      }

      rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1);
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
3372
3373
3374
3375
3376
3377
3378

3379
3380
3381
3382
3383
3384
3385
3386
3387





3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403

3404
3405
3406
3407
3408
3409
3410
3411







-
+








-
-
-
-
-
















-
+








  sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
  pOut = out2Prerelease(p, pOp);
  pOut->u.i = iMeta;
  break;
}

/* Opcode: SetCookie P1 P2 P3 * P5
/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the integer value P3 into cookie number P2 of database P1.
** P2==1 is the schema version.  P2==2 is the database format.
** P2==3 is the recommended pager cache 
** size, and so forth.  P1==0 is the main database file and P1==1 is the 
** database file used to store temporary tables.
**
** A transaction must be started before executing this opcode.
**
** If P2 is the SCHEMA_VERSION cookie (cookie number 1) then the internal
** schema version is set to P3-P5.  The "PRAGMA schema_version=N" statement
** has P5 set to 1, so that the internal schema version will be different
** from the database schema version, resulting in a schema reset.
*/
case OP_SetCookie: {
  Db *pDb;

  sqlite3VdbeIncrWriteCounter(p, 0);
  assert( pOp->p2<SQLITE_N_BTREE_META );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( DbMaskTest(p->btreeMask, pOp->p1) );
  assert( p->readOnly==0 );
  pDb = &db->aDb[pOp->p1];
  assert( pDb->pBt!=0 );
  assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
  /* See note about index shifting on OP_ReadCookie */
  rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3);
  if( pOp->p2==BTREE_SCHEMA_VERSION ){
    /* When the schema cookie changes, record the new cookie internally */
    pDb->pSchema->schema_cookie = pOp->p3 - pOp->p5;
    pDb->pSchema->schema_cookie = pOp->p3;
    db->mDbFlags |= DBFLAG_SchemaChange;
  }else if( pOp->p2==BTREE_FILE_FORMAT ){
    /* Record changes in the file format */
    pDb->pSchema->file_format = pOp->p3;
  }
  if( pOp->p1==1 ){
    /* Invalidate all prepared statements whenever the TEMP database
3677
3678
3679
3680
3681
3682
3683
3684

3685
3686
3687
3688
3689
3690
3691
3428
3429
3430
3431
3432
3433
3434

3435
3436
3437
3438
3439
3440
3441
3442







-
+







** values need not be contiguous but all P1 values should be small integers.
** It is an error for P1 to be negative.
**
** Allowed P5 bits:
** <ul>
** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
**       of OP_SeekLE/OP_IdxLT)
**       of OP_SeekLE/OP_IdxGT)
** </ul>
**
** The P4 value may be either an integer (P4_INT32) or a pointer to
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo 
** object, then table being opened must be an [index b-tree] where the
** KeyInfo object defines the content and collating 
** sequence of that index b-tree. Otherwise, if P4 is an integer 
3707
3708
3709
3710
3711
3712
3713
3714

3715
3716
3717
3718
3719
3720
3721
3458
3459
3460
3461
3462
3463
3464

3465
3466
3467
3468
3469
3470
3471
3472







-
+







** be the same as every other ReopenIdx or OpenRead for the same cursor
** number.
**
** Allowed P5 bits:
** <ul>
** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
**       of OP_SeekLE/OP_IdxLT)
**       of OP_SeekLE/OP_IdxGT)
** </ul>
**
** See also: OP_OpenRead, OP_OpenWrite
*/
/* Opcode: OpenWrite P1 P2 P3 P4 P5
** Synopsis: root=P2 iDb=P3
**
3731
3732
3733
3734
3735
3736
3737
3738

3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756

3757
3758
3759
3760
3761
3762
3763
3482
3483
3484
3485
3486
3487
3488

3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506

3507
3508
3509
3510
3511
3512
3513
3514







-
+

















-
+







** value, then the table being opened must be a [table b-tree] with a
** number of columns no less than the value of P4.
**
** Allowed P5 bits:
** <ul>
** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
**       of OP_SeekLE/OP_IdxLT)
**       of OP_SeekLE/OP_IdxGT)
** <li>  <b>0x08 OPFLAG_FORDELETE</b>: This cursor is used only to seek
**       and subsequently delete entries in an index btree.  This is a
**       hint to the storage engine that the storage engine is allowed to
**       ignore.  The hint is not used by the official SQLite b*tree storage
**       engine, but is used by COMDB2.
** <li>  <b>0x10 OPFLAG_P2ISREG</b>: Use the content of register P2
**       as the root page, not the value of P2 itself.
** </ul>
**
** This instruction works like OpenRead except that it opens the cursor
** in read/write mode.
**
** See also: OP_OpenRead, OP_ReopenIdx
*/
case OP_ReopenIdx: {
  int nField;
  KeyInfo *pKeyInfo;
  u32 p2;
  int p2;
  int iDb;
  int wrFlag;
  Btree *pX;
  VdbeCursor *pCur;
  Db *pDb;

  assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
3780
3781
3782
3783
3784
3785
3786
3787

3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806

3807
3808
3809
3810
3811
3812
3813
3531
3532
3533
3534
3535
3536
3537

3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556

3557
3558
3559
3560
3561
3562
3563
3564







-
+


















-
+







  if( p->expired==1 ){
    rc = SQLITE_ABORT_ROLLBACK;
    goto abort_due_to_error;
  }

  nField = 0;
  pKeyInfo = 0;
  p2 = (u32)pOp->p2;
  p2 = pOp->p2;
  iDb = pOp->p3;
  assert( iDb>=0 && iDb<db->nDb );
  assert( DbMaskTest(p->btreeMask, iDb) );
  pDb = &db->aDb[iDb];
  pX = pDb->pBt;
  assert( pX!=0 );
  if( pOp->opcode==OP_OpenWrite ){
    assert( OPFLAG_FORDELETE==BTREE_FORDELETE );
    wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE);
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    if( pDb->pSchema->file_format < p->minWriteFileFormat ){
      p->minWriteFileFormat = pDb->pSchema->file_format;
    }
  }else{
    wrFlag = 0;
  }
  if( pOp->p5 & OPFLAG_P2ISREG ){
    assert( p2>0 );
    assert( p2<=(u32)(p->nMem+1 - p->nCursor) );
    assert( p2<=(p->nMem+1 - p->nCursor) );
    assert( pOp->opcode==OP_OpenWrite );
    pIn2 = &aMem[p2];
    assert( memIsValid(pIn2) );
    assert( (pIn2->flags & MEM_Int)!=0 );
    sqlite3VdbeMemIntegerify(pIn2);
    p2 = (int)pIn2->u.i;
    /* The p2 value always comes from a prior OP_CreateBtree opcode and
3843
3844
3845
3846
3847
3848
3849

3850

3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871

3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884

3885
3886
3887
3888
3889
3890
3891
3892
3893
3894

3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
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







+

+



















-
-
+









-
-
-
-
+









-
+



















-
-
-
-







  ** since moved into the btree layer.  */  
  pCur->isTable = pOp->p4type!=P4_KEYINFO;

open_cursor_set_hints:
  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
  assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
  testcase( pOp->p5 & OPFLAG_BULKCSR );
#ifdef SQLITE_ENABLE_CURSOR_HINTS
  testcase( pOp->p2 & OPFLAG_SEEKEQ );
#endif
  sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
                               (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
  if( rc ) goto abort_due_to_error;
  break;
}

/* Opcode: OpenDup P1 P2 * * *
**
** Open a new cursor P1 that points to the same ephemeral table as
** cursor P2.  The P2 cursor must have been opened by a prior OP_OpenEphemeral
** opcode.  Only ephemeral cursors may be duplicated.
**
** Duplicate ephemeral cursors are used for self-joins of materialized views.
*/
case OP_OpenDup: {
  VdbeCursor *pOrig;    /* The original cursor to be duplicated */
  VdbeCursor *pCx;      /* The new cursor */

  pOrig = p->apCsr[pOp->p2];
  assert( pOrig );
  assert( pOrig->isEphemeral );  /* Only ephemeral cursors can be duplicated */
  assert( pOrig->pBtx!=0 );  /* Only ephemeral cursors can be duplicated */

  pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->isEphemeral = 1;
  pCx->pKeyInfo = pOrig->pKeyInfo;
  pCx->isTable = pOrig->isTable;
  pCx->pgnoRoot = pOrig->pgnoRoot;
  pCx->isOrdered = pOrig->isOrdered;
  pCx->pBtx = pOrig->pBtx;
  pCx->hasBeenDuped = 1;
  pOrig->hasBeenDuped = 1;
  rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, 
  rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
                          pCx->pKeyInfo, pCx->uc.pCursor);
  /* The sqlite3BtreeCursor() routine can only fail for the first cursor
  ** opened for a database.  Since there is already an open cursor when this
  ** opcode is run, the sqlite3BtreeCursor() cannot fail */
  assert( rc==SQLITE_OK );
  break;
}


/* Opcode: OpenEphemeral P1 P2 P3 P4 P5
/* Opcode: OpenEphemeral P1 P2 * P4 P5
** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 
** the main database is read-only.  The ephemeral
** table is deleted automatically when the cursor is closed.
**
** If the cursor P1 is already opened on an ephemeral table, the table
** is cleared (all content is erased).
**
** P2 is the number of columns in the ephemeral table.
** The cursor points to a BTree table if P4==0 and to a BTree index
** if P4 is not 0.  If P4 is not NULL, it points to a KeyInfo structure
** that defines the format of keys in the index.
**
** The P5 parameter can be a mask of the BTREE_* flags defined
** in btree.h.  These flags control aspects of the operation of
** the btree.  The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are
** added automatically.
**
** If P3 is positive, then reg[P3] is modified slightly so that it
** can be used as zero-length data for OP_Insert.  This is an optimization
** that avoids an extra OP_Blob opcode to initialize that register.
*/
/* Opcode: OpenAutoindex P1 P2 * P4 *
** Synopsis: nColumn=P2
**
** This opcode works the same as OP_OpenEphemeral.  It has a
** different name to distinguish its use.  Tables created using
** by this opcode will be used for automatically created transient
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951


3952
3953

3954
3955
3956
3957
3958
3959
3960

3961
3962
3963
3964
3965
3966

3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992


























3993
3994
3995

3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
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







-
-
-
-
-
-
-
-
-

-
-
+
+
-
-
+
-
-
-




+






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

-







      SQLITE_OPEN_READWRITE |
      SQLITE_OPEN_CREATE |
      SQLITE_OPEN_EXCLUSIVE |
      SQLITE_OPEN_DELETEONCLOSE |
      SQLITE_OPEN_TRANSIENT_DB;
  assert( pOp->p1>=0 );
  assert( pOp->p2>=0 );
  if( pOp->p3>0 ){
    /* Make register reg[P3] into a value that can be used as the data
    ** form sqlite3BtreeInsert() where the length of the data is zero. */
    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->hasBeenDuped ){
    /* If the ephermeral table is already open and has no duplicates from
  if( pCx ){
    /* If the ephermeral table is already open, erase all existing content
    ** OP_OpenDup, then erase all existing content so that the table is
    ** empty again, rather than creating a new table. */
    ** 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{
    pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
    if( pCx==0 ) goto no_mem;
    pCx->nullRow = 1;
    pCx->isEphemeral = 1;
    rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
                          BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,
                          vfsFlags);
    if( rc==SQLITE_OK ){
      rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
    }
      if( rc==SQLITE_OK ){
        /* If a transient index is required, create it by calling
        ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
        ** opening it. If a transient table is required, just use the
        ** automatically created table with root-page 1 (an BLOB_INTKEY table).
        */
        if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
          assert( pOp->p4type==P4_KEYINFO );
          rc = sqlite3BtreeCreateTable(pCx->pBtx, &pCx->pgnoRoot,
              BTREE_BLOBKEY | pOp->p5); 
          if( rc==SQLITE_OK ){
            assert( pCx->pgnoRoot==SCHEMA_ROOT+1 );
            assert( pKeyInfo->db==db );
            assert( pKeyInfo->enc==ENC(db) );
            rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
                pKeyInfo, pCx->uc.pCursor);
          }
          pCx->isTable = 0;
        }else{
          pCx->pgnoRoot = SCHEMA_ROOT;
          rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR,
              0, pCx->uc.pCursor);
          pCx->isTable = 1;
        }
      }
      pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
    if( rc==SQLITE_OK ){
      /* If a transient index is required, create it by calling
      ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
      ** opening it. If a transient table is required, just use the
      ** automatically created table with root-page 1 (an BLOB_INTKEY table).
      */
      if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
        assert( pOp->p4type==P4_KEYINFO );
        rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
                                     BTREE_BLOBKEY | pOp->p5); 
        if( rc==SQLITE_OK ){
          assert( pCx->pgnoRoot==MASTER_ROOT+1 );
          assert( pKeyInfo->db==db );
          assert( pKeyInfo->enc==ENC(db) );
          rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
                                  pKeyInfo, pCx->uc.pCursor);
        }
        pCx->isTable = 0;
      }else{
        pCx->pgnoRoot = MASTER_ROOT;
        rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
                                0, pCx->uc.pCursor);
        pCx->isTable = 1;
      }
    }
    pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
      if( rc ){
        sqlite3BtreeClose(pCx->pBtx);
      }
  }
    }
  }
  if( rc ) goto abort_due_to_error;
  pCx->nullRow = 1;
  break;
}

/* Opcode: SorterOpen P1 P2 P3 P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
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
3848
3849
3850
3851
3852
3853
3854





3855
3856
3857
3858
3859


3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874

3875
3876
3877
3878
3879
3880
3881
3882







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















-
+







** that are used as an unpacked index key. 
**
** Reposition cursor P1 so that  it points to the smallest entry that 
** is greater than or equal to the key value. If there are no records 
** greater than or equal to the key and P2 is not zero, then jump to P2.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
** opcode will either land on a record that exactly matches the key, or
** else it will cause a jump to P2.  When the cursor is OPFLAG_SEEKEQ,
** this opcode must be followed by an IdxLE opcode with the same arguments.
** The IdxGT opcode will be skipped if this opcode succeeds, but the
** IdxGT opcode will be used on subsequent loop iterations.  The 
** opcode will always land on a record that equally equals the key, or
** else jump immediately to P2.  When the cursor is OPFLAG_SEEKEQ, this
** opcode must be followed by an IdxLE opcode with the same arguments.
** The IdxLE opcode will be skipped if this opcode succeeds, but the
** IdxLE opcode will be used on subsequent loop iterations.
** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
** is an equality search.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end.  In other words, the cursor is
** configured to use Next, not Prev.
**
** See also: Found, NotFound, SeekLt, SeekGt, SeekLe
*/
/* Opcode: SeekGT P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), 
** use the value in register P3 as a key. If cursor P1 refers 
** to an SQL index, then P3 is the first in an array of P4 registers 
** that are used as an unpacked index key. 
**
** Reposition cursor P1 so that it points to the smallest entry that 
** Reposition cursor P1 so that  it points to the smallest entry that 
** is greater than the key value. If there are no records greater than 
** the key and P2 is not zero, then jump to P2.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end.  In other words, the cursor is
** configured to use Next, not Prev.
**
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195



4196
4197

4198
4199
4200
4201
4202
4203
4204
4205
4206
3913
3914
3915
3916
3917
3918
3919



3920
3921
3922
3923

3924


3925
3926
3927
3928
3929
3930
3931







-
-
-
+
+
+

-
+
-
-







** less than or equal to the key and P2 is not zero, then jump to P2.
**
** This opcode leaves the cursor configured to move in reverse order,
** from the end toward the beginning.  In other words, the cursor is
** configured to use Prev, not Next.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
** opcode will either land on a record that exactly matches the key, or
** else it will cause a jump to P2.  When the cursor is OPFLAG_SEEKEQ,
** this opcode must be followed by an IdxLE opcode with the same arguments.
** opcode will always land on a record that equally equals the key, or
** else jump immediately to P2.  When the cursor is OPFLAG_SEEKEQ, this
** opcode must be followed by an IdxGE opcode with the same arguments.
** The IdxGE opcode will be skipped if this opcode succeeds, but the
** IdxGE opcode will be used on subsequent loop iterations.  The 
** IdxGE opcode will be used on subsequent loop iterations.
** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
** is an equality search.
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLT:         /* jump, in3, group */
case OP_SeekLE:         /* jump, in3, group */
case OP_SeekGE:         /* jump, in3, group */
case OP_SeekGT: {       /* jump, in3, group */
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236

4237
4238
4239
4240
4241
4242
4243
4244
4245

4246
4247
4248

4249
4250
4251
4252
4253
4254
4255
4256
4257





4258
4259

4260
4261
4262
4263

4264
4265
4266
4267
4268
4269
4270
4271
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







-
-

-
-
+







-
-
+


-
+
-
-



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







  oc = pOp->opcode;
  eqOnly = 0;
  pC->nullRow = 0;
#ifdef SQLITE_DEBUG
  pC->seekOp = pOp->opcode;
#endif

  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;
  if( pC->isTable ){
    u16 flags3, newType;
    /* The OPFLAG_SEEKEQ/BTREE_SEEK_EQ flag is only set on index cursors */
    /* The BTREE_SEEK_EQ flag is only set on index cursors */
    assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
              || CORRUPT_DB );

    /* The input value in P3 might be of any type: integer, real, string,
    ** blob, or NULL.  But it needs to be an integer before we can do
    ** the seek, so convert it. */
    pIn3 = &aMem[pOp->p3];
    flags3 = pIn3->flags;
    if( (flags3 & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
    if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
      applyNumericAffinity(pIn3, 0);
    }
    iKey = sqlite3VdbeIntValue(pIn3); /* Get the integer key value */
    iKey = sqlite3VdbeIntValue(pIn3);
    newType = pIn3->flags; /* Record the type after applying numeric affinity */
    pIn3->flags = flags3;  /* But convert the type back to its original */

    /* If the P3 value could not be converted into an integer without
    ** loss of information, then special processing is required... */
    if( (newType & (MEM_Int|MEM_IntReal))==0 ){
      if( (newType & MEM_Real)==0 ){
        if( (newType & MEM_Null) || oc>=OP_SeekGE ){
          VdbeBranchTaken(1,2);
    if( (pIn3->flags & MEM_Int)==0 ){
      if( (pIn3->flags & MEM_Real)==0 ){
        /* If the P3 value cannot be converted into any kind of a number,
        ** then the seek is not possible, so jump to P2 */
        VdbeBranchTaken(1,2); goto jump_to_p2;
          goto jump_to_p2;
        }else{
        break;
          rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
          if( rc!=SQLITE_OK ) goto abort_due_to_error;
          goto seek_not_found;
        }
      }
      }else

      /* If the approximation iKey is larger than the actual real search
      ** term, substitute >= for > and < for <=. e.g. if the search term
      ** is 4.9 and the integer approximation 5:
      **
      **        (x >  4.9)    ->     (x >= 5)
      **        (x <= 4.9)    ->     (x <  5)
4281
4282
4283
4284
4285
4286
4287
4288

4289
4290
4291
4292
4293
4294
4295
4296
4297



4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
3996
3997
3998
3999
4000
4001
4002

4003
4004
4005
4006
4007
4008
4009



4010
4011
4012

4013
4014
4015
4016
4017


4018
4019
4020
4021
4022
4023
4024







-
+






-
-
-
+
+
+
-





-
-







      ** term, substitute <= for < and > for >=.  */
      else if( pIn3->u.r>(double)iKey ){
        assert( OP_SeekLE==(OP_SeekLT+1) );
        assert( OP_SeekGT==(OP_SeekGE+1) );
        assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
        if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
      }
    }
    } 
    rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
    pC->movetoTarget = iKey;  /* Used by OP_Delete */
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
  }else{
    /* For a cursor with the OPFLAG_SEEKEQ/BTREE_SEEK_EQ hint, only the
    ** OP_SeekGE and OP_SeekLE opcodes are allowed, and these must be
    ** immediately followed by an OP_IdxGT or OP_IdxLT opcode, respectively,
    /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
    ** OP_SeekLE opcodes are allowed, and these must be immediately followed
    ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
    ** with the same key.
    */
    if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
      eqOnly = 1;
      assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
      assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
      assert( pOp->opcode==OP_SeekGE || pOp[1].opcode==OP_IdxLT );
      assert( pOp->opcode==OP_SeekLE || pOp[1].opcode==OP_IdxGT );
      assert( pOp[1].p1==pOp[0].p1 );
      assert( pOp[1].p2==pOp[0].p2 );
      assert( pOp[1].p3==pOp[0].p3 );
      assert( pOp[1].p4.i==pOp[0].p4.i );
    }

    nField = pOp->p4.i;
4338
4339
4340
4341
4342
4343
4344


4345
4346
4347
4348
4349
4350
4351
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065







+
+







      goto abort_due_to_error;
    }
    if( eqOnly && r.eqSeen==0 ){
      assert( res!=0 );
      goto seek_not_found;
    }
  }
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
  sqlite3_search_count++;
#endif
  if( oc>=OP_SeekGE ){  assert( oc==OP_SeekGE || oc==OP_SeekGT );
    if( res<0 || (res==0 && oc==OP_SeekGT) ){
      res = 0;
      rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397


4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447

4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532

4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549


4550
4551
4552
4553
4554
4555
4556

4557
4558

4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
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







-
-
-
+
+

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

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






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







  }else if( eqOnly ){
    assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
    pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */
  }
  break;
}


/* Opcode: SeekScan  P1 P2 * * *
** Synopsis: Scan-ahead up to P1 rows
/* Opcode: SeekHit P1 P2 * * *
** Synopsis: seekHit=P2
**
** This opcode is a prefix opcode to OP_SeekGE.  In other words, this
** opcode must be immediately followed by OP_SeekGE. This constraint is
** checked by assert() statements.
**
** This opcode uses the P1 through P4 operands of the subsequent
** OP_SeekGE.  In the text that follows, the operands of the subsequent
** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4.   Only
** the P1 and P2 operands of this opcode are also used, and  are called
** This.P1 and This.P2.
**
** This opcode helps to optimize IN operators on a multi-column index
** where the IN operator is on the later terms of the index by avoiding
** unnecessary seeks on the btree, substituting steps to the next row
** of the b-tree instead.  A correct answer is obtained if this opcode
** is omitted or is a no-op.
**
** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which
** is the desired entry that we want the cursor SeekGE.P1 to be pointing
** to.  Call this SeekGE.P4/P5 row the "target".
**
** If the SeekGE.P1 cursor is not currently pointing to a valid row,
** then this opcode is a no-op and control passes through into the OP_SeekGE.
**
** If the SeekGE.P1 cursor is pointing to a valid row, then that row
** might be the target row, or it might be near and slightly before the
** target row.  This opcode attempts to position the cursor on the target
** row by, perhaps by invoking sqlite3BtreeStep() on the cursor
** between 0 and This.P1 times.
**
** There are three possible outcomes from this opcode:<ol>
**
** <li> If after This.P1 steps, the cursor is still pointing to a place that
**      is earlier in the btree than the target row, then fall through
**      into the subsquence OP_SeekGE opcode.
**
** <li> If the cursor is successfully moved to the target row by 0 or more
**      sqlite3BtreeNext() calls, then jump to This.P2, which will land just
**      past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE.
**
** <li> If the cursor ends up past the target row (indicating the the target
**      row does not exist in the btree) then jump to SeekOP.P2. 
** </ol>
*/
case OP_SeekScan: {
  VdbeCursor *pC;
  int res;
  int nStep;
  UnpackedRecord r;

** Set the seekHit flag on cursor P1 to the value in P2.
  assert( pOp[1].opcode==OP_SeekGE );

  /* pOp->p2 points to the first instruction past the OP_IdxGT that
  ** follows the OP_SeekGE.  */
  assert( pOp->p2>=(int)(pOp-aOp)+2 );
  assert( aOp[pOp->p2-1].opcode==OP_IdxGT || aOp[pOp->p2-1].opcode==OP_IdxGE );
  testcase( aOp[pOp->p2-1].opcode==OP_IdxGE );
  assert( pOp[1].p1==aOp[pOp->p2-1].p1 );
  assert( pOp[1].p2==aOp[pOp->p2-1].p2 );
  assert( pOp[1].p3==aOp[pOp->p2-1].p3 );

  assert( pOp->p1>0 );
  pC = p->apCsr[pOp[1].p1];
  assert( pC!=0 );
  assert( pC->eCurType==CURTYPE_BTREE );
  assert( !pC->isTable );
  if( !sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) ){
#ifdef SQLITE_DEBUG
     if( db->flags&SQLITE_VdbeTrace ){
       printf("... cursor not valid - fall through\n");
     }        
#endif
    break;
  }
  nStep = pOp->p1;
  assert( nStep>=1 );
  r.pKeyInfo = pC->pKeyInfo;
  r.nField = (u16)pOp[1].p4.i;
  r.default_rc = 0;
  r.aMem = &aMem[pOp[1].p3];
#ifdef SQLITE_DEBUG
  {
    int i;
    for(i=0; i<r.nField; i++){
      assert( memIsValid(&r.aMem[i]) );
      REGISTER_TRACE(pOp[1].p3+i, &aMem[pOp[1].p3+i]);
    }
  }
#endif
  res = 0;  /* Not needed.  Only used to silence a warning. */
  while(1){
    rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
    if( rc ) goto abort_due_to_error;
    if( res>0 ){
      seekscan_search_fail:
#ifdef SQLITE_DEBUG
      if( db->flags&SQLITE_VdbeTrace ){
        printf("... %d steps and then skip\n", pOp->p1 - nStep);
      }        
#endif
      VdbeBranchTaken(1,3);
      pOp++;
      goto jump_to_p2;
    }
    if( res==0 ){
#ifdef SQLITE_DEBUG
      if( db->flags&SQLITE_VdbeTrace ){
        printf("... %d steps and then success\n", pOp->p1 - nStep);
      }        
#endif
      VdbeBranchTaken(2,3);
      goto jump_to_p2;
      break;
    }
    if( nStep<=0 ){
#ifdef SQLITE_DEBUG
      if( db->flags&SQLITE_VdbeTrace ){
        printf("... fall through after %d steps\n", pOp->p1);
      }        
#endif
      VdbeBranchTaken(0,3);
      break;
    }
    nStep--;
    rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
    if( rc ){
      if( rc==SQLITE_DONE ){
        rc = SQLITE_OK;
        goto seekscan_search_fail;
      }else{
        goto abort_due_to_error;
      }
    }
  }
  
** The seekHit flag is used by the IfNoHope opcode.
  break;
}


/* Opcode: SeekHit P1 P2 P3 * *
** Synopsis: set P2<=seekHit<=P3
**
** Increase or decrease the seekHit value for cursor P1, if necessary,
** so that it is no less than P2 and no greater than P3.
**
** The seekHit integer represents the maximum of terms in an index for which
** there is known to be at least one match.  If the seekHit value is smaller
** than the total number of equality terms in an index lookup, then the
** OP_IfNoHope opcode might run to see if the IN loop can be abandoned
** early, thus saving work.  This is part of the IN-early-out optimization.
**
** P1 must be a valid b-tree cursor.
** P1 must be a valid b-tree cursor.  P2 must be a boolean value,
** either 0 or 1.
*/
case OP_SeekHit: {
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pOp->p3>=pOp->p2 );
  assert( pOp->p2==0 || pOp->p2==1 );
  if( pC->seekHit<pOp->p2 ){
    pC->seekHit = pOp->p2;
  pC->seekHit = pOp->p2 & 1;
  }else if( pC->seekHit>pOp->p3 ){
    pC->seekHit = pOp->p3;
  }
  break;
}

/* Opcode: IfNotOpen P1 P2 * * *
** Synopsis: if( !csr[P1] ) goto P2
**
** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through.
*/
case OP_IfNotOpen: {        /* jump */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2);
  if( !p->apCsr[pOp->p1] ){
    goto jump_to_p2_and_check_for_interrupt;
  }
  break;
}

/* Opcode: Found P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
** If P4==0 then register P3 holds a blob constructed by MakeRecord.  If
4612
4613
4614
4615
4616
4617
4618
4619

4620
4621
4622

4623
4624
4625




4626
4627
4628
4629
4630
4631
4632


4633
4634
4635
4636
4637
4638
4639
4161
4162
4163
4164
4165
4166
4167

4168


4169
4170



4171
4172
4173
4174
4175






4176
4177
4178
4179
4180
4181
4182
4183
4184







-
+
-
-

+
-
-
-
+
+
+
+

-
-
-
-
-
-
+
+







**
** See also: Found, NotExists, NoConflict, IfNoHope
*/
/* Opcode: IfNoHope P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
** Register P3 is the first of P4 registers that form an unpacked
** record.  Cursor P1 is an index btree.  P2 is a jump destination.
** record.
** In other words, the operands to this opcode are the same as the
** operands to OP_NotFound and OP_IdxGT.
**
** Cursor P1 is on an index btree.  If the seekHit flag is set on P1, then
** This opcode is an optimization attempt only.  If this opcode always
** falls through, the correct answer is still obtained, but extra works
** is performed.
** this opcode is a no-op.  But if the seekHit flag of P1 is clear, then
** check to see if there is any entry in P1 that matches the
** prefix identified by P3 and P4.  If no entry matches the prefix,
** jump to P2.  Otherwise fall through.
**
** A value of N in the seekHit flag of cursor P1 means that there exists
** a key P3:N that will match some record in the index.  We want to know
** if it is possible for a record P3:P4 to match some record in the
** index.  If it is not possible, we can skips some work.  So if seekHit
** is less than P4, attempt to find out if a match is possible by running
** OP_NotFound.
** This opcode behaves like OP_NotFound if the seekHit
** flag is clear and it behaves like OP_Noop if the seekHit flag is set.
**
** This opcode is used in IN clause processing for a multi-column key.
** If an IN clause is attached to an element of the key other than the
** left-most element, and if there are no matches on the most recent
** seek over the whole key, then it might be that one of the key element
** to the left is prohibiting a match, and hence there is "no hope" of
** any match regardless of how many IN clause elements are checked.
4667
4668
4669
4670
4671
4672
4673
4674

4675
4676
4677
4678
4679
4680
4681
4682
4683
4212
4213
4214
4215
4216
4217
4218

4219
4220

4221
4222
4223
4224
4225
4226
4227







-
+

-







** See also: NotFound, Found, NotExists
*/
case OP_IfNoHope: {     /* jump, in3 */
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  if( pC->seekHit>=pOp->p4.i ) break;
  if( pC->seekHit ) break;
  /* Fall through into OP_NotFound */
  /* no break */ deliberate_fall_through
}
case OP_NoConflict:     /* jump, in3 */
case OP_NotFound:       /* jump, in3 */
case OP_Found: {        /* jump, in3 */
  int alreadyExists;
  int takeJump;
  int ii;
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4293
4294
4295
4296
4297
4298
4299

4300
4301
4302
4303
4304
4305
4306







-







  pC->cacheStatus = CACHE_STALE;
  if( pOp->opcode==OP_Found ){
    VdbeBranchTaken(alreadyExists!=0,2);
    if( alreadyExists ) goto jump_to_p2;
  }else{
    VdbeBranchTaken(takeJump||alreadyExists==0,2);
    if( takeJump || !alreadyExists ) goto jump_to_p2;
    if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i;
  }
  break;
}

/* Opcode: SeekRowid P1 P2 P3 * *
** Synopsis: intkey=r[P3]
**
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
4351
4352
4353
4354
4355
4356
4357






4358
4359









4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370

4371
4372
4373
4374


4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392







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


-




-
-










+







case OP_SeekRowid: {        /* jump, in3 */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  u64 iKey;

  pIn3 = &aMem[pOp->p3];
  testcase( pIn3->flags & MEM_Int );
  testcase( pIn3->flags & MEM_IntReal );
  testcase( pIn3->flags & MEM_Real );
  testcase( (pIn3->flags & (MEM_Str|MEM_Int))==MEM_Str );
  if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
    /* If pIn3->u.i does not contain an integer, compute iKey as the
  if( (pIn3->flags & MEM_Int)==0 ){
    /* Make sure pIn3->u.i contains a valid integer representation of
    ** integer value of pIn3.  Jump to P2 if pIn3 cannot be converted
    ** into an integer without loss of information.  Take care to avoid
    ** changing the datatype of pIn3, however, as it is used by other
    ** parts of the prepared statement. */
    Mem x = pIn3[0];
    applyAffinity(&x, SQLITE_AFF_NUMERIC, encoding);
    if( (x.flags & MEM_Int)==0 ) goto jump_to_p2;
    iKey = x.u.i;
    goto notExistsWithKey;
    ** the key value, but do not change the datatype of the register, as
    ** other parts of the perpared statement might be depending on the
    ** current datatype. */
    u16 origFlags = pIn3->flags;
    int isNotInt;
    applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
    isNotInt = (pIn3->flags & MEM_Int)==0;
    pIn3->flags = origFlags;
    if( isNotInt ) goto jump_to_p2;
  }
  /* Fall through into OP_NotExists */
  /* no break */ deliberate_fall_through
case OP_NotExists:          /* jump, in3 */
  pIn3 = &aMem[pOp->p3];
  assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  iKey = pIn3->u.i;
notExistsWithKey:
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
#ifdef SQLITE_DEBUG
  if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid;
#endif
  assert( pC->isTable );
  assert( pC->eCurType==CURTYPE_BTREE );
  pCrsr = pC->uc.pCursor;
  assert( pCrsr!=0 );
  res = 0;
  iKey = pIn3->u.i;
  rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
  assert( rc==SQLITE_OK || res==0 );
  pC->movetoTarget = iKey;  /* Used by OP_Delete */
  pC->nullRow = 0;
  pC->cacheStatus = CACHE_STALE;
  pC->deferredMoveto = 0;
  VdbeBranchTaken(res!=0,2);
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4437
4438
4439
4440
4441
4442
4443

4444
4445

4446
4447
4448
4449
4450
4451
4452







-


-







** 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 );
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
4604
4605
4606
4607
4608
4609
4610

4611
4612
4613
4614
4615
4616
4617







-








  pData = &aMem[pOp->p2];
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( memIsValid(pData) );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->eCurType==CURTYPE_BTREE );
  assert( pC->deferredMoveto==0 );
  assert( pC->uc.pCursor!=0 );
  assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
  assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
  REGISTER_TRACE(pOp->p2, pData);
  sqlite3VdbeIncrWriteCounter(p, pC);

  pKey = &aMem[pOp->p3];
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
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
4673
4674
4675
4676



























4677
4678
4679
4680
4681
4682
4683







-
+










-
+
-
















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







    }
  }
  if( pOp->p5 & OPFLAG_ISNOOP ) break;
#endif

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
  assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 );
  assert( pData->flags & (MEM_Blob|MEM_Str) );
  x.pData = pData->z;
  x.nData = pData->n;
  seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
  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)), 
      (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult
      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
** record in the table. If it is left pointing at the next record, then
5215
5216
5217
5218
5219
5220
5221
5222

5223
5224
5225
5226
5227
5228
5229
5230
5231

5232
5233
5234
5235
5236
5237
5238
4721
4722
4723
4724
4725
4726
4727

4728




4729
4730
4731
4732

4733
4734
4735
4736
4737
4738
4739
4740







-
+
-
-
-
-




-
+







  assert( pC!=0 );
  assert( pC->eCurType==CURTYPE_BTREE );
  assert( pC->uc.pCursor!=0 );
  assert( pC->deferredMoveto==0 );
  sqlite3VdbeIncrWriteCounter(p, pC);

#ifdef SQLITE_DEBUG
  if( pOp->p4type==P4_TABLE
  if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
   && HasRowid(pOp->p4.pTab)
   && pOp->p5==0
   && sqlite3BtreeCursorIsValidNN(pC->uc.pCursor)
  ){
    /* If p5 is zero, the seek operation that positioned the cursor prior to
    ** OP_Delete will have also set the pC->movetoTarget field to the rowid of
    ** the row that is being deleted */
    i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
    assert( CORRUPT_DB || pC->movetoTarget==iKey );
    assert( pC->movetoTarget==iKey );
  }
#endif

  /* If the update-hook or pre-update-hook will be invoked, set zDb to
  ** the name of the db to pass as to it. Also set local pTab to a copy
  ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
  ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set 
5424
5425
5426
5427
5428
5429
5430




5431
5432
5433
5434
5435
5436
5437

5438
5439
5440
5441
5442
5443
5444
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







+
+
+
+






-
+







  ** If this where not the case, on of the following assert()s
  ** would fail.  Should this ever change (because of changes in the code
  ** generator) then the fix would be to insert a call to
  ** sqlite3VdbeCursorMoveto().
  */
  assert( pC->deferredMoveto==0 );
  assert( sqlite3BtreeCursorIsValid(pCrsr) );
#if 0  /* Not required due to the previous to assert() statements */
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
#endif

  n = sqlite3BtreePayloadSize(pCrsr);
  if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }
  testcase( n==0 );
  rc = sqlite3VdbeMemFromBtreeZeroOffset(pCrsr, n, pOut);
  rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut);
  if( rc ) goto abort_due_to_error;
  if( !pOp->p3 ) Deephemeralize(pOut);
  UPDATE_MAX_BLOBSIZE(pOut);
  REGISTER_TRACE(pOp->p2, pOut);
  break;
}

5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5133
5134
5135
5136
5137
5138
5139

5140
5141
5142
5143
5144
5145
5146







-







case OP_Sort: {        /* jump */
#ifdef SQLITE_TEST
  sqlite3_sort_count++;
  sqlite3_search_count--;
#endif
  p->aCounter[SQLITE_STMTSTATUS_SORT]++;
  /* Fall through into OP_Rewind */
  /* no break */ deliberate_fall_through
}
/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty, jump immediately to P2.
** If the table or index is not empty, fall through to the following 
5755
5756
5757
5758
5759
5760
5761
5762
5763


5764
5765
5766
5767

5768
5769
5770
5771
5772
5773
5774
5260
5261
5262
5263
5264
5265
5266


5267
5268

5269
5270

5271
5272
5273
5274
5275
5276
5277
5278







-
-
+
+
-


-
+







  assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
  assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );

  /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
  ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
  assert( pOp->opcode!=OP_Next
       || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
       || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found 
       || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid);
       || pC->seekOp==OP_IfNoHope);
  assert( pOp->opcode!=OP_Prev
       || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
       || pC->seekOp==OP_Last   || pC->seekOp==OP_IfNoHope
       || pC->seekOp==OP_Last 
       || pC->seekOp==OP_NullRow);

  rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
next_tail:
  pC->cacheStatus = CACHE_STALE;
  VdbeBranchTaken(rc==SQLITE_OK,2);
  if( rc==SQLITE_OK ){
5809
5810
5811
5812
5813
5814
5815








5816
5817
5818
5819
5820
5821
5822
5823
5824

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
5878
5879
5880
5881
5882
5883
5884
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
5916
5917
5918
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335

5336
5337

5338
5339

5340
5341
5342
5343
5344
5345
5346










5347
5348
5349
5350
5351
5352
5353
5354
5355
5356



5357






















5358
5359
5360
5361

5362
5363
5364
5365
5366
5367







5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393



5394
5395
5396
5397
5398
5399
5400







+
+
+
+
+
+
+
+








-
+

-
+

-
+



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




-
+





-
-
-
-
-
-
-
















+









-
-
-







** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
** seeks on the cursor or if the most recent seek used a key equivalent
** to P2. 
**
** This instruction only works for indices.  The equivalent instruction
** for tables is OP_Insert.
*/
/* Opcode: SorterInsert P1 P2 * * *
** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions.  This opcode writes that key
** into the sorter P1.  Data for the entry is nil.
*/
case OP_SorterInsert:       /* in2 */
case OP_IdxInsert: {        /* in2 */
  VdbeCursor *pC;
  BtreePayload x;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  sqlite3VdbeIncrWriteCounter(p, pC);
  assert( pC!=0 );
  assert( !isSorter(pC) );
  assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
  pIn2 = &aMem[pOp->p2];
  assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) );
  assert( pIn2->flags & MEM_Blob );
  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  assert( pC->eCurType==CURTYPE_BTREE );
  assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
  assert( pC->isTable==0 );
  rc = ExpandBlob(pIn2);
  if( rc ) goto abort_due_to_error;
  if( pOp->opcode==OP_SorterInsert ){
    rc = sqlite3VdbeSorterWrite(pC, pIn2);
  }else{
  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;
    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;
}
  }

/* Opcode: SorterInsert P1 P2 * * *
** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions.  This opcode writes that key
** into the sorter P1.  Data for the entry is nil.
*/
case OP_SorterInsert: {     /* in2 */
  VdbeCursor *pC;

  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 );
  assert( pC->isTable==0 );
  rc = ExpandBlob(pIn2);
  if( rc ) goto abort_due_to_error;
  rc = sqlite3VdbeSorterWrite(pC, pIn2);
  if( rc) goto abort_due_to_error;
  break;
}

/* Opcode: IdxDelete P1 P2 P3 * P5
/* Opcode: IdxDelete P1 P2 P3 * *
** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the 
** index opened by cursor P1.
**
** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
** if no matching index entry is found.  This happens when running
** an UPDATE or DELETE statement and the index entry to be updated
** or deleted is not found.  For some uses of IdxDelete
** (example:  the EXCEPT operator) it does not matter that no matching
** entry is found.  For those cases, P5 is zero.
*/
case OP_IdxDelete: {
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  UnpackedRecord r;

  assert( pOp->p3>0 );
  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->eCurType==CURTYPE_BTREE );
  sqlite3VdbeIncrWriteCounter(p, pC);
  pCrsr = pC->uc.pCursor;
  assert( pCrsr!=0 );
  assert( pOp->p5==0 );
  r.pKeyInfo = pC->pKeyInfo;
  r.nField = (u16)pOp->p3;
  r.default_rc = 0;
  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;
}

5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
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
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
5464
5465
5466
5467
5468
5469
5470


5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482



















5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493

5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504

5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515

5516
5517
5518
5519
5520
5521
5522
5523







-
-












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










-
+










-
+










-
+







      assert( pTabCur->uc.pCursor!=0 );
      assert( pTabCur->isTable );
      pTabCur->nullRow = 0;
      pTabCur->movetoTarget = rowid;
      pTabCur->deferredMoveto = 1;
      assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
      pTabCur->aAltMap = pOp->p4.ai;
      assert( !pC->isEphemeral );
      assert( !pTabCur->isEphemeral );
      pTabCur->pAltCursor = pC;
    }else{
      pOut = out2Prerelease(p, pOp);
      pOut->u.i = rowid;
    }
  }else{
    assert( pOp->opcode==OP_IdxRowid );
    sqlite3VdbeMemSetNull(&aMem[pOp->p2]);
  }
  break;
}

/* Opcode: FinishSeek P1 * * * *
** 
** If cursor P1 was previously moved via OP_DeferredSeek, complete that
** seek operation now, without further delay.  If the cursor seek has
** already occurred, this instruction is a no-op.
*/
case OP_FinishSeek: {
  VdbeCursor *pC;             /* The P1 index cursor */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  if( pC->deferredMoveto ){
    rc = sqlite3VdbeFinishMoveto(pC);
    if( rc ) goto abort_due_to_error;
  }
  break;
}

/* Opcode: IdxGE P1 P2 P3 P4 *
/* Opcode: IdxGE P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index 
** key that omits the PRIMARY KEY.  Compare this key value against the index 
** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID 
** fields at the end.
**
** If the P1 index entry is greater than or equal to the key value
** then jump to P2.  Otherwise fall through to the next instruction.
*/
/* Opcode: IdxGT P1 P2 P3 P4 *
/* Opcode: IdxGT P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index 
** key that omits the PRIMARY KEY.  Compare this key value against the index 
** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID 
** fields at the end.
**
** If the P1 index entry is greater than the key value
** then jump to P2.  Otherwise fall through to the next instruction.
*/
/* Opcode: IdxLT P1 P2 P3 P4 *
/* Opcode: IdxLT P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index 
** key that omits the PRIMARY KEY or ROWID.  Compare this key value against
** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or
** ROWID on the P1 index.
**
** If the P1 index entry is less than the key value then jump to P2.
** Otherwise fall through to the next instruction.
*/
/* Opcode: IdxLE P1 P2 P3 P4 *
/* Opcode: IdxLE P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index 
** key that omits the PRIMARY KEY or ROWID.  Compare this key value against
** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or
** ROWID on the P1 index.
**
6073
6074
6075
6076
6077
6078
6079

6080
6081
6082
6083
6084
6085
6086
6087
6088
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
6120
6121
6122
6123

6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134

6135
6136
6137
6138
6139
6140
6141
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562

5563























5564

5565
5566
5567
5568
5569
5570
5571
5572
5573

5574
5575
5576
5577
5578
5579
5580
5581







+




















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









-
+







  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->isOrdered );
  assert( pC->eCurType==CURTYPE_BTREE );
  assert( pC->uc.pCursor!=0);
  assert( pC->deferredMoveto==0 );
  assert( pOp->p5==0 || pOp->p5==1 );
  assert( pOp->p4type==P4_INT32 );
  r.pKeyInfo = pC->pKeyInfo;
  r.nField = (u16)pOp->p4.i;
  if( pOp->opcode<OP_IdxLT ){
    assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxGT );
    r.default_rc = -1;
  }else{
    assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT );
    r.default_rc = 0;
  }
  r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
  {
    int i;
    for(i=0; i<r.nField; i++){
      assert( memIsValid(&r.aMem[i]) );
      REGISTER_TRACE(pOp->p3+i, &aMem[pOp->p3+i]);
    }
  }
#endif

  res = 0;  /* Not needed.  Only used to silence a warning. */
  /* Inlined version of sqlite3VdbeIdxKeyCompare() */
  {
    i64 nCellKey = 0;
    BtCursor *pCur;
    Mem m;

    assert( pC->eCurType==CURTYPE_BTREE );
    pCur = pC->uc.pCursor;
    assert( sqlite3BtreeCursorIsValid(pCur) );
    nCellKey = sqlite3BtreePayloadSize(pCur);
    /* nCellKey will always be between 0 and 0xffffffff because of the way
    ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
    if( nCellKey<=0 || nCellKey>0x7fffffff ){
      rc = SQLITE_CORRUPT_BKPT;
      goto abort_due_to_error;
    }
    sqlite3VdbeMemInit(&m, db, 0);
    rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
    if( rc ) goto abort_due_to_error;
    res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
    sqlite3VdbeMemRelease(&m);
  }
  /* End of inlined sqlite3VdbeIdxKeyCompare() */
  rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);

  assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
  if( (pOp->opcode&1)==(OP_IdxLT&1) ){
    assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
    res = -res;
  }else{
    assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
    res++;
  }
  VdbeBranchTaken(res>0,2);
  assert( rc==SQLITE_OK );
  if( rc ) goto abort_due_to_error;
  if( res>0 ) goto jump_to_p2;
  break;
}

/* Opcode: Destroy P1 P2 P3 * *
**
** Delete an entire database table or index whose root page in the database
6218
6219
6220
6221
6222
6223
6224
6225

6226
6227
6228
6229
6230
6231
6232
5658
5659
5660
5661
5662
5663
5664

5665
5666
5667
5668
5669
5670
5671
5672







-
+







  int nChange;
 
  sqlite3VdbeIncrWriteCounter(p, 0);
  nChange = 0;
  assert( p->readOnly==0 );
  assert( DbMaskTest(p->btreeMask, pOp->p2) );
  rc = sqlite3BtreeClearTable(
      db->aDb[pOp->p2].pBt, (u32)pOp->p1, (pOp->p3 ? &nChange : 0)
      db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
  );
  if( pOp->p3 ){
    p->nChange += nChange;
    if( pOp->p3>0 ){
      assert( memIsValid(&aMem[pOp->p3]) );
      memAboutToChange(p, &aMem[pOp->p3]);
      aMem[pOp->p3].u.i += nChange;
6267
6268
6269
6270
6271
6272
6273
6274

6275
6276
6277
6278
6279
6280
6281
5707
5708
5709
5710
5711
5712
5713

5714
5715
5716
5717
5718
5719
5720
5721







-
+







** Allocate a new b-tree in the main database file if P1==0 or in the
** TEMP database file if P1==1 or in an attached database if
** P1>1.  The P3 argument must be 1 (BTREE_INTKEY) for a rowid table
** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table.
** The root page number of the new b-tree is stored in register P2.
*/
case OP_CreateBtree: {          /* out2 */
  Pgno pgno;
  int pgno;
  Db *pDb;

  sqlite3VdbeIncrWriteCounter(p, 0);
  pOut = out2Prerelease(p, pOp);
  pgno = 0;
  assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
6300
6301
6302
6303
6304
6305
6306
6307

6308
6309
6310
6311
6312
6313
6314
6315
6316

6317
6318
6319
6320
6321
6322
6323
5740
5741
5742
5743
5744
5745
5746

5747
5748
5749
5750
5751
5752
5753
5754
5755

5756
5757
5758
5759
5760
5761
5762
5763







-
+








-
+







  db->nSqlExec--;
  if( rc ) goto abort_due_to_error;
  break;
}

/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the schema table of database P1
** Read and parse all entries from the SQLITE_MASTER table of database P1
** that match the WHERE clause P4.  If P4 is a NULL pointer, then the
** entire schema for P1 is reparsed.
**
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine.  It is thus a re-entrant opcode.
*/
case OP_ParseSchema: {
  int iDb;
  const char *zSchema;
  const char *zMaster;
  char *zSql;
  InitData initData;

  /* Any prepared statement that invokes this opcode will hold mutexes
  ** on every btree.  This is a prerequisite for invoking 
  ** sqlite3InitCallback().
  */
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
5771
5772
5773
5774
5775
5776
5777

5778
5779
5780
5781
5782
5783

5784
5785
5786
5787
5788

5789


5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804

5805
5806
5807
5808
5809
5810
5811
5812







-
+





-
+




-

-
-
+
+













-
+







  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);
    rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable);
    db->mDbFlags |= DBFLAG_SchemaChange;
    p->expired = 0;
  }else
#endif
  {
    zSchema = DFLT_SCHEMA_TABLE;
    zMaster = MASTER_NAME;
    initData.db = db;
    initData.iDb = iDb;
    initData.pzErrMsg = &p->zErrMsg;
    initData.mInitFlags = 0;
    initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt);
    zSql = sqlite3MPrintf(db,
       "SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid",
       db->aDb[iDb].zDbSName, zSchema, pOp->p4.z);
       "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
       db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
    if( zSql==0 ){
      rc = SQLITE_NOMEM_BKPT;
    }else{
      assert( db->init.busy==0 );
      db->init.busy = 1;
      initData.rc = SQLITE_OK;
      initData.nInitRow = 0;
      assert( !db->mallocFailed );
      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
      if( rc==SQLITE_OK ) rc = initData.rc;
      if( rc==SQLITE_OK && initData.nInitRow==0 ){
        /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse
        ** at least one SQL statement. Any less than that indicates that
        ** the sqlite_schema table is corrupt. */
        ** the sqlite_master table is corrupt. */
        rc = SQLITE_CORRUPT_BKPT;
      }
      sqlite3DbFreeNN(db, zSql);
      db->init.busy = 0;
    }
  }
  if( rc ){
6456
6457
6458
6459
6460
6461
6462
6463

6464
6465
6466
6467
6468
6469
6470
6471
6472

6473
6474
6475
6476
6477
6478
6479
6480

6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493

6494
6495
6496
6497
6498
6499
6500
5895
5896
5897
5898
5899
5900
5901

5902
5903
5904
5905
5906
5907
5908
5909
5910

5911
5912
5913
5914
5915
5916
5917
5918

5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931

5932
5933
5934
5935
5936
5937
5938
5939







-
+








-
+







-
+












-
+







** If P5 is not zero, the check is done on the auxiliary database
** file, not the main database file.
**
** This opcode is used to implement the integrity_check pragma.
*/
case OP_IntegrityCk: {
  int nRoot;      /* Number of tables to check.  (Number of root pages.) */
  Pgno *aRoot;    /* Array of rootpage numbers for tables to be checked */
  int *aRoot;     /* Array of rootpage numbers for tables to be checked */
  int nErr;       /* Number of errors reported */
  char *z;        /* Text of the error report */
  Mem *pnErr;     /* Register keeping track of errors remaining */

  assert( p->bIsReader );
  nRoot = pOp->p2;
  aRoot = pOp->p4.ai;
  assert( nRoot>0 );
  assert( aRoot[0]==(Pgno)nRoot );
  assert( aRoot[0]==nRoot );
  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  pnErr = &aMem[pOp->p3];
  assert( (pnErr->flags & MEM_Int)!=0 );
  assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
  pIn1 = &aMem[pOp->p1];
  assert( pOp->p5<db->nDb );
  assert( DbMaskTest(p->btreeMask, pOp->p5) );
  z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
                                 (int)pnErr->u.i+1, &nErr);
  sqlite3VdbeMemSetNull(pIn1);
  if( nErr==0 ){
    assert( z==0 );
  }else if( z==0 ){
    goto no_mem;
  }else{
    pnErr->u.i -= nErr-1;
    sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
  }
  UPDATE_MAX_BLOBSIZE(pIn1);
  sqlite3VdbeChangeEncoding(pIn1, encoding);
  goto check_for_interrupt;
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/* Opcode: RowSetAdd P1 P2 * * *
** Synopsis: rowset(P1)=r[P2]
**
** Insert the integer value held by register P2 into a RowSet object
6732
6733
6734
6735
6736
6737
6738
6739

6740
6741
6742
6743
6744
6745
6746
6171
6172
6173
6174
6175
6176
6177

6178
6179
6180
6181
6182
6183
6184
6185







-
+







#ifdef SQLITE_DEBUG
  /* Verify that second and subsequent executions of the same trigger do not
  ** try to reuse register values from the first use. */
  {
    int i;
    for(i=0; i<p->nMem; i++){
      aMem[i].pScopyFrom = 0;  /* Prevent false-positive AboutToChange() errs */
      MemSetTypeFlag(&aMem[i], MEM_Undefined); /* Fault if this reg is reused */
      aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */
    }
  }
#endif
  pOp = &aOp[-1];
  goto check_for_interrupt;
}

7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
6444
6445
6446
6447
6448
6449
6450

6451
6452
6453
6454
6455
6456
6457







-







  pOp->p4.pCtx = pCtx;

  /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */
  assert( pOp->p1==(pOp->opcode==OP_AggInverse) );

  pOp->opcode = OP_AggStep1;
  /* Fall through into OP_AggStep */
  /* no break */ deliberate_fall_through
}
case OP_AggStep1: {
  int i;
  sqlite3_context *pCtx;
  Mem *pMem;

  assert( pOp->p4type==P4_FUNCCTX );
7253
7254
7255
7256
7257
7258
7259
7260

7261
7262
7263
7264
7265
7266
7267
6691
6692
6693
6694
6695
6696
6697

6698
6699
6700
6701
6702
6703
6704
6705







-
+







        ** as an intermediate */
        sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF);
      }
  
      /* Open a transaction on the database file. Regardless of the journal
      ** mode, this transaction always uses a rollback journal.
      */
      assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE );
      assert( sqlite3BtreeIsInTrans(pBt)==0 );
      if( rc==SQLITE_OK ){
        rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
      }
    }
  }
#endif /* ifndef SQLITE_OMIT_WAL */

7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
6782
6783
6784
6785
6786
6787
6788






























6789
6790
6791
6792
6793
6794
6795







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







    sqlite3ExpirePreparedStatements(db, pOp->p2);
  }else{
    p->expired = pOp->p2+1;
  }
  break;
}

/* Opcode: CursorLock P1 * * * *
**
** Lock the btree to which cursor P1 is pointing so that the btree cannot be
** written by an other cursor.
*/
case OP_CursorLock: {
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->eCurType==CURTYPE_BTREE );
  sqlite3BtreeCursorPin(pC->uc.pCursor);
  break;
}

/* Opcode: CursorUnlock P1 * * * *
**
** Unlock the btree to which cursor P1 is pointing so that it can be
** written by other cursors.
*/
case OP_CursorUnlock: {
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->eCurType==CURTYPE_BTREE );
  sqlite3BtreeCursorUnpin(pC->uc.pCursor);
  break;
}

#ifndef SQLITE_OMIT_SHARED_CACHE
/* Opcode: TableLock P1 P2 P3 P4 *
** Synopsis: iDb=P1 root=P2 write=P3
**
** Obtain a lock on a particular table. This instruction is only used when
** the shared-cache feature is enabled. 
**
7618
7619
7620
7621
7622
7623
7624
7625

7626
7627
7628
7629
7630
7631
7632
7026
7027
7028
7029
7030
7031
7032

7033
7034
7035
7036
7037
7038
7039
7040







-
+







    break;
  }
  pVtab = pCur->uc.pVCur->pVtab;
  pModule = pVtab->pModule;
  assert( pModule->xColumn );
  memset(&sContext, 0, sizeof(sContext));
  sContext.pOut = pDest;
  assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
  testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
  if( pOp->p5 & OPFLAG_NOCHNG ){
    sqlite3VdbeMemSetNull(pDest);
    pDest->flags = MEM_Null|MEM_Zero;
    pDest->u.nZero = 0;
  }else{
    MemSetTypeFlag(pDest, MEM_Null);
  }
7843
7844
7845
7846
7847
7848
7849
7850
7851


7852
7853
7854


7855
7856
7857
7858


7859
7860
7861
7862
7863
7864
7865
7866
7867

7868
7869
7870


7871
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
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7251
7252
7253
7254
7255
7256
7257


7258
7259
7260


7261
7262




7263
7264
7265
7266
7267
7268
7269
7270
7271
7272

7273
7274


7275
7276
7277
7278


7279
7280


7281
7282
7283
7284
7285
7286
7287
7288
7289



7290
7291
7292




7293
7294
7295
7296

7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337

7338
7339
7340

7341
7342
7343
7344
7345
7346
7347







-
-
+
+

-
-
+
+
-
-
-
-
+
+








-
+

-
-
+
+


-
-
+
+
-
-









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

-
+

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














-



-







    if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3;
  }
  pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax);
  break;
}
#endif

/* Opcode: Function P1 P2 P3 P4 *
** Synopsis: r[P3]=func(r[P2@NP])
/* Opcode: Function0 P1 P2 P3 P4 P5
** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
** contains a pointer to the function to be run) with arguments taken
** Invoke a user function (P4 is a pointer to a FuncDef object that
** defines the function) with P5 arguments taken from register P2 and
** from register P2 and successors.  The number of arguments is in
** the sqlite3_context object that P4 points to.
** The result of the function is stored
** in register P3.  Register P3 must not be one of the function inputs.
** successors.  The result of the function is stored in register P3.
** Register P3 must not be one of the function inputs.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the 
** function was determined to be constant at compile time. If the first
** argument was constant then bit 0 of P1 is set. This is used to determine
** whether meta data associated with a user function argument using the
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** See also: AggStep, AggFinal, PureFunc
** See also: Function, AggStep, AggFinal
*/
/* Opcode: PureFunc P1 P2 P3 P4 *
** Synopsis: r[P3]=func(r[P2@NP])
/* Opcode: Function P1 P2 P3 P4 P5
** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
** contains a pointer to the function to be run) with arguments taken
** from register P2 and successors.  The number of arguments is in
** contains a pointer to the function to be run) with P5 arguments taken
** from register P2 and successors.  The result of the function is stored
** the sqlite3_context object that P4 points to.
** The result of the function is stored
** in register P3.  Register P3 must not be one of the function inputs.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the 
** function was determined to be constant at compile time. If the first
** argument was constant then bit 0 of P1 is set. This is used to determine
** whether meta data associated with a user function argument using the
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** This opcode works exactly like OP_Function.  The only difference is in
** its name.  This opcode is used in places where the function must be
** purely non-deterministic.  Some built-in date/time functions can be
** SQL functions are initially coded as OP_Function0 with P4 pointing
** to a FuncDef object.  But on first evaluation, the P4 operand is
** automatically converted into an sqlite3_context object and the operation
** either determinitic of non-deterministic, depending on their arguments.
** When those function are used in a non-deterministic way, they will check
** to see if they were called using OP_PureFunc instead of OP_Function, and
** if they were, they throw an error.
** changed to this OP_Function opcode.  In this way, the initialization of
** the sqlite3_context object occurs only once, rather than once for each
** evaluation of the function.
**
** See also: AggStep, AggFinal, Function
** See also: Function0, AggStep, AggFinal
*/
case OP_PureFunc0:              /* group */
case OP_Function0: {            /* group */
  int n;
  sqlite3_context *pCtx;

  assert( pOp->p4type==P4_FUNCDEF );
  n = pOp->p5;
  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
  pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
  if( pCtx==0 ) goto no_mem;
  pCtx->pOut = 0;
  pCtx->pFunc = pOp->p4.pFunc;
  pCtx->iOp = (int)(pOp - aOp);
  pCtx->pVdbe = p;
  pCtx->isError = 0;
  pCtx->argc = n;
  pOp->p4type = P4_FUNCCTX;
  pOp->p4.pCtx = pCtx;
  assert( OP_PureFunc == OP_PureFunc0+2 );
  assert( OP_Function == OP_Function0+2 );
  pOp->opcode += 2;
  /* Fall through into OP_Function */
}
case OP_PureFunc:              /* group */
case OP_Function: {            /* group */
  int i;
  sqlite3_context *pCtx;

  assert( pOp->p4type==P4_FUNCCTX );
  pCtx = pOp->p4.pCtx;

  /* If this function is inside of a trigger, the register array in aMem[]
  ** might change from one evaluation to the next.  The next block of code
  ** checks to see if the register array has changed, and if so it
  ** reinitializes the relavant parts of the sqlite3_context object */
  pOut = &aMem[pOp->p3];
  if( pCtx->pOut != pOut ){
    pCtx->pVdbe = p;
    pCtx->pOut = pOut;
    for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
  }
  assert( pCtx->pVdbe==p );

  memAboutToChange(p, pOut);
#ifdef SQLITE_DEBUG
  for(i=0; i<pCtx->argc; i++){
    assert( memIsValid(pCtx->argv[i]) );
    REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
  }
7995
7996
7997
7998
7999
8000
8001

8002
8003

8004
8005
8006
8007
8008
8009

8010
8011
8012

8013
8014
8015
8016
8017
8018
8019
7421
7422
7423
7424
7425
7426
7427
7428
7429

7430
7431
7432
7433
7434
7435

7436
7437
7438

7439
7440
7441
7442
7443
7444
7445
7446







+

-
+





-
+


-
+







#ifndef SQLITE_OMIT_TRACE
  if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
   && !p->doingRerun
   && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
  ){
#ifndef SQLITE_OMIT_DEPRECATED
    if( db->mTrace & SQLITE_TRACE_LEGACY ){
      void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace;
      char *z = sqlite3VdbeExpandSql(p, zTrace);
      db->trace.xLegacy(db->pTraceArg, z);
      x(db->pTraceArg, z);
      sqlite3_free(z);
    }else
#endif
    if( db->nVdbeExec>1 ){
      char *z = sqlite3MPrintf(db, "-- %s", zTrace);
      (void)db->trace.xV2(SQLITE_TRACE_STMT, db->pTraceArg, p, z);
      (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, z);
      sqlite3DbFree(db, z);
    }else{
      (void)db->trace.xV2(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
      (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
    }
  }
#ifdef SQLITE_USE_FCNTL_TRACE
  zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
  if( zTrace ){
    int j;
    for(j=0; j<db->nDb; j++){
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
7505
7506
7507
7508
7509
7510
7511

















































7512
7513
7514
7515
7516
7517
7518







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







*/
case OP_Abortable: {
  sqlite3VdbeAssertAbortable(p);
  break;
}
#endif

#ifdef SQLITE_DEBUG
/* Opcode:  ReleaseReg   P1 P2 P3 * P5
** Synopsis: release r[P1@P2] mask P3
**
** Release registers from service.  Any content that was in the
** the registers is unreliable after this opcode completes.
**
** The registers released will be the P2 registers starting at P1,
** except if bit ii of P3 set, then do not release register P1+ii.
** In other words, P3 is a mask of registers to preserve.
**
** Releasing a register clears the Mem.pScopyFrom pointer.  That means
** that if the content of the released register was set using OP_SCopy,
** a change to the value of the source register for the OP_SCopy will no longer
** generate an assertion fault in sqlite3VdbeMemAboutToChange().
**
** If P5 is set, then all released registers have their type set
** to MEM_Undefined so that any subsequent attempt to read the released
** register (before it is reinitialized) will generate an assertion fault.
**
** P5 ought to be set on every call to this opcode.
** However, there are places in the code generator will release registers
** before their are used, under the (valid) assumption that the registers
** will not be reallocated for some other purpose before they are used and
** hence are safe to release.
**
** This opcode is only available in testing and debugging builds.  It is
** not generated for release builds.  The purpose of this opcode is to help
** validate the generated bytecode.  This opcode does not actually contribute
** to computing an answer.
*/
case OP_ReleaseReg: {
  Mem *pMem;
  int i;
  u32 constMask;
  assert( pOp->p1>0 );
  assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
  pMem = &aMem[pOp->p1];
  constMask = pOp->p3;
  for(i=0; i<pOp->p2; i++, pMem++){
    if( i>=32 || (constMask & MASKBIT32(i))==0 ){
      pMem->pScopyFrom = 0;
      if( i<32 && pOp->p5 ) MemSetTypeFlag(pMem, MEM_Undefined);
    }
  }
  break;
}
#endif

/* Opcode: Noop * * * * *
**
** Do nothing.  This instruction is often useful as a jump
** destination.
*/
/*
** The magic Explain opcode are only inserted when explain==2 (which
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200

8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
7556
7557
7558
7559
7560
7561
7562






7563
7564
7565
7566
7567
7568
7569
7570
7571

7572




7573
7574
7575
7576
7577
7578
7579







-
-
-
-
-
-









-
+
-
-
-
-







      if( rc!=0 ) printf("rc=%d\n",rc);
      if( opProperty & (OPFLG_OUT2) ){
        registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
      }
      if( opProperty & OPFLG_OUT3 ){
        registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
      }
      if( opProperty==0xff ){
        /* Never happens.  This code exists to avoid a harmless linkage
        ** warning aboud sqlite3VdbeRegisterDump() being defined but not
        ** used. */
        sqlite3VdbeRegisterDump(p);
      }
    }
#endif  /* SQLITE_DEBUG */
#endif  /* NDEBUG */
  }  /* The end of the for(;;) loop the loops through opcodes */

  /* If we reach this point, it means that execution is finished with
  ** an error of some kind.
  */
abort_due_to_error:
  if( db->mallocFailed ){
  if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT;
    rc = SQLITE_NOMEM_BKPT;
  }else if( rc==SQLITE_IOERR_CORRUPTFS ){
    rc = SQLITE_CORRUPT_BKPT;
  }
  assert( rc );
  if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
    sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
  }
  p->rc = rc;
  sqlite3SystemError(db, rc);
  testcase( sqlite3GlobalConfig.xLog!=0 );
8222
8223
8224
8225
8226
8227
8228
8229

8230
8231
8232
8233
8234
8235
8236
7590
7591
7592
7593
7594
7595
7596

7597
7598
7599
7600
7601
7602
7603
7604







-
+







  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  while( nVmStep>=nProgressLimit && db->xProgress!=0 ){
    nProgressLimit += db->nProgressOps;
    if( db->xProgress(db->pProgressArg) ){
      nProgressLimit = LARGEST_UINT64;
      nProgressLimit = 0xffffffff;
      rc = SQLITE_INTERRUPT;
      goto abort_due_to_error;
    }
  }
#endif
  p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
  sqlite3VdbeLeave(p);
8255
8256
8257
8258
8259
8260
8261
8262
8263




8264
8265
7623
7624
7625
7626
7627
7628
7629


7630
7631
7632
7633
7634
7635







-
-
+
+
+
+


  rc = SQLITE_NOMEM_BKPT;
  goto abort_due_to_error;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */
abort_due_to_interrupt:
  assert( AtomicLoad(&db->u1.isInterrupted) );
  rc = SQLITE_INTERRUPT;
  assert( db->u1.isInterrupted );
  rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
  p->rc = rc;
  sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
  goto abort_due_to_error;
}

Changes to src/vdbe.h.

53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67







-
+







    double *pReal;         /* Used when p4type is P4_REAL */
    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
    sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    VTable *pVtab;         /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
    u32 *ai;               /* Used when p4type is P4_INTARRAY */
    int *ai;               /* Used when p4type is P4_INTARRAY */
    SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
    Table *pTab;           /* Used when p4type is P4_TABLE */
#ifdef SQLITE_ENABLE_CURSOR_HINTS
    Expr *pExpr;           /* Used when p4type is P4_EXPR */
#endif
    int (*xAdvance)(BtCursor *, int);
  } p4;
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
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198







-










-







#define SQLITE_PREPARE_MASK     0x0f  /* Mask of public flags */

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqlite3VdbeCreate(Parse*);
Parse *sqlite3VdbeParser(Vdbe*);
int sqlite3VdbeAddOp0(Vdbe*,int);
int sqlite3VdbeAddOp1(Vdbe*,int,int);
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
int sqlite3VdbeGoto(Vdbe*,int);
int sqlite3VdbeLoadString(Vdbe*,int,const char*);
void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
int sqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int);
void sqlite3VdbeEndCoroutine(Vdbe*,int);
#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
  void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N);
  void sqlite3VdbeVerifyNoResultRow(Vdbe *p);
#else
# define sqlite3VdbeVerifyNoMallocRequired(A,B)
# define sqlite3VdbeVerifyNoResultRow(A)
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
217
218
219
220
221
222
223





224
225
226
227
228
229
230

231
232





233
234
235
236
237
238
239







-
-
-
-
-
+
+
+
+
+


-


-
-
-
-
-







# 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 sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);
int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
#ifdef SQLITE_DEBUG
  void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int);
#else
# define sqlite3VdbeReleaseRegisters(P,A,N,M,F)
#endif
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Parse*);
void sqlite3VdbeRunOnlyOnce(Vdbe*);
282
283
284
285
286
287
288

289
290

291
292
293
294
295
296
297
298
299
300
301
302
274
275
276
277
278
279
280
281
282

283
284
285



286
287
288
289
290
291
292







+

-
+


-
-
-







int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);

typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);

#ifndef SQLITE_OMIT_TRIGGER
void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
int sqlite3VdbeHasSubProgram(Vdbe*);
#endif

int sqlite3NotPureFunc(sqlite3_context*);
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
int sqlite3VdbeBytecodeVtabInit(sqlite3*);
#endif

/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
** each VDBE opcode.
**
** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op
** comments in VDBE programs that show key decision points in the code
** generator.

Changes to src/vdbeInt.h.

27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
27
28
29
30
31
32
33

34

35
36
37
38
39
40
41







-
+
-







#endif

/*
** VDBE_DISPLAY_P4 is true or false depending on whether or not the
** "explain" P4 display logic is enabled.
*/
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \
     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
     || defined(SQLITE_ENABLE_BYTECODE_VTAB)
# define VDBE_DISPLAY_P4 1
#else
# define VDBE_DISPLAY_P4 0
#endif

/*
** SQL is translated into a sequence of instructions to be
82
83
84
85
86
87
88
89
90

91
92
93

94
95
96
97
98
99
100
81
82
83
84
85
86
87


88
89
90

91
92
93
94
95
96
97
98







-
-
+


-
+







#ifdef SQLITE_DEBUG
  u8 seekOp;              /* Most recent seek operation on this cursor */
  u8 wrFlag;              /* The wrFlag argument to sqlite3BtreeCursor() */
#endif
  Bool isEphemeral:1;     /* True for an ephemeral table */
  Bool useRandomRowid:1;  /* Generate new record numbers semi-randomly */
  Bool isOrdered:1;       /* True if the table is not BTREE_UNORDERED */
  Bool hasBeenDuped:1;    /* This cursor was source or target of OP_OpenDup */
  u16 seekHit;            /* See the OP_SeekHit and OP_IfNoHope opcodes */
  Bool seekHit:1;         /* See the OP_SeekHit and OP_IfNoHope opcodes */
  Btree *pBtx;            /* Separate file holding temporary table */
  i64 seqCount;           /* Sequence counter */
  u32 *aAltMap;           /* Mapping from table to index column numbers */
  int *aAltMap;           /* Mapping from table to index column numbers */

  /* Cached OP_Column parse information is only valid if cacheStatus matches
  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
  ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that
  ** the cache is out of date. */
  u32 cacheStatus;        /* Cache is valid if this matches Vdbe.cacheCtr */
  int seekResult;         /* Result of previous sqlite3BtreeMoveto() or 0
243
244
245
246
247
248
249
250
251
252



253
254
255

256
257
258
259
260
261
262
241
242
243
244
245
246
247



248
249
250
251
252

253
254
255
256
257
258
259
260







-
-
-
+
+
+


-
+







** flags may coexist with the MEM_Str flag.
*/
#define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */
#define MEM_IntReal   0x0020   /* MEM_Int that stringifies like MEM_Real */
#define MEM_AffMask   0x003f   /* Mask of affinity bits */
#define MEM_FromBind  0x0040   /* Value originates from sqlite3_bind() */
#define MEM_AffMask   0x001f   /* Mask of affinity bits */
#define MEM_FromBind  0x0020   /* Value originates from sqlite3_bind() */
/* Available          0x0040   */
#define MEM_Undefined 0x0080   /* Value is undefined */
#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
#define MEM_TypeMask  0xc1bf   /* Mask of type bits */
#define MEM_TypeMask  0xc1df   /* Mask of type bits */


/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
282
283
284
285
286
287
288


289
290
291
292
293
294
295
296







-
-
+







#define MemSetTypeFlag(p, f) \
   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)

/*
** True if Mem X is a NULL-nochng type.
*/
#define MemNullNochng(X) \
  (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \
    && (X)->n==0 && (X)->u.nZero==0)
  ((X)->flags==(MEM_Null|MEM_Zero) && (X)->n==0 && (X)->u.nZero==0)

/*
** Return true if a memory cell is not marked as invalid.  This macro
** is for use inside assert() statements only.
*/
#ifdef SQLITE_DEBUG
#define memIsValid(M)  ((M)->flags & MEM_Undefined)==0
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389







-
+







** 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 */
  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) */
416
417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429







-


+







  int rcApp;              /* errcode set by sqlite3_result_error_code() */
  u32 nWrite;             /* Number of write operations that have occurred */
#endif
  u16 nResColumn;         /* Number of columns in one row of the result set */
  u8 errorAction;         /* Recovery action to do in case of an error */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 prepFlags;           /* SQLITE_PREPARE_* flags */
  u8 doingRerun;          /* True if rerunning after an auto-reprepare */
  bft expired:2;          /* 1: recompile VM immediately  2: when convenient */
  bft explain:2;          /* True if EXPLAIN present on SQL command */
  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
  bft changeCntOn:1;      /* True to update the change-counter */
  bft runOnlyOnce:1;      /* Automatically expire on reset */
  bft usesStmtJournal:1;  /* True if uses a statement journal */
  bft readOnly:1;         /* True for statements that do not write */
  bft bIsReader:1;        /* True for statements that read */
  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
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
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







-
-
+



+








-
-
-
-
-
-
-
-
+








/*
** Function prototypes
*/
void sqlite3VdbeError(Vdbe*, const char *, ...);
void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*);
int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
int sqlite3VdbeCursorRestore(VdbeCursor*);
u32 sqlite3VdbeSerialTypeLen(u32);
u8 sqlite3VdbeOneByteSerialTypeLen(u8);
u32 sqlite3VdbeSerialType(Mem*, int, u32*);
u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
int sqlite3VdbeExec(Vdbe*);
#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**);
char *sqlite3VdbeDisplayP4(sqlite3*,Op*);
#endif
#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*);
#endif
#if !defined(SQLITE_OMIT_EXPLAIN)
#ifndef SQLITE_OMIT_EXPLAIN
int sqlite3VdbeList(Vdbe*);
#endif
int sqlite3VdbeHalt(Vdbe*);
int sqlite3VdbeChangeEncoding(Mem *, int);
int sqlite3VdbeMemTooBig(Mem*);
int sqlite3VdbeMemCopy(Mem*, const Mem*);
void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
525
526
527
528
529
530
531

532
533

534
535
536
537
538

539
540
541
542
543
544
545
546







-
+

-





-
+







i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);
int sqlite3VdbeBooleanValue(Mem*, int ifNull);
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
int sqlite3VdbeMemCast(Mem*,u8,u8);
void sqlite3VdbeMemCast(Mem*,u8,u8);
int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef SQLITE_OMIT_WINDOWFUNC
int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
#endif
#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
#ifndef SQLITE_OMIT_EXPLAIN
const char *sqlite3OpcodeName(int);
#endif
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
int sqlite3VdbeCloseStatement(Vdbe *, int);
#ifdef SQLITE_DEBUG
int sqlite3VdbeFrameIsValid(VdbeFrame*);
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605







-
+







int sqlite3VdbeCheckFk(Vdbe *, int);
#else
# define sqlite3VdbeCheckFk(p,i) 0
#endif

#ifdef SQLITE_DEBUG
  void sqlite3VdbePrintSql(Vdbe*);
  void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr);
  void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
#endif
#ifndef SQLITE_OMIT_UTF16
  int sqlite3VdbeMemTranslate(Mem*, u8);
  int sqlite3VdbeMemHandleBom(Mem *pMem);
#endif

#ifndef SQLITE_OMIT_INCRBLOB

Changes to src/vdbeapi.c.

69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+







  iElapse = (iNow - p->startTime)*1000000;
#ifndef SQLITE_OMIT_DEPRECATED
  if( db->xProfile ){
    db->xProfile(db->pProfileArg, p->zSql, iElapse);
  }
#endif
  if( db->mTrace & SQLITE_TRACE_PROFILE ){
    db->trace.xV2(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
    db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
  }
  p->startTime = 0;
}
/*
** The checkProfileCallback(DB,P) macro checks to see if a profile callback
** is needed, and it invokes the callback if it is needed.
*/
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
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







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

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







#endif /* SQLITE_OMIT_UTF16 */
/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five
** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
** point number string BLOB NULL
*/
int sqlite3_value_type(sqlite3_value* pVal){
  static const u8 aType[] = {
     SQLITE_BLOB,     /* 0x00 (not possible) */
     SQLITE_BLOB,     /* 0x00 */
     SQLITE_NULL,     /* 0x01 NULL */
     SQLITE_TEXT,     /* 0x02 TEXT */
     SQLITE_NULL,     /* 0x03 (not possible) */
     SQLITE_NULL,     /* 0x01 */
     SQLITE_INTEGER,  /* 0x04 INTEGER */
     SQLITE_NULL,     /* 0x05 (not possible) */
     SQLITE_INTEGER,  /* 0x06 INTEGER + TEXT */
     SQLITE_NULL,     /* 0x07 (not possible) */
     SQLITE_FLOAT,    /* 0x08 FLOAT */
     SQLITE_NULL,     /* 0x09 (not possible) */
     SQLITE_FLOAT,    /* 0x0a FLOAT + TEXT */
     SQLITE_NULL,     /* 0x0b (not possible) */
     SQLITE_INTEGER,  /* 0x0c (not possible) */
     SQLITE_NULL,     /* 0x0d (not possible) */
     SQLITE_INTEGER,  /* 0x0e (not possible) */
     SQLITE_NULL,     /* 0x0f (not possible) */
     SQLITE_BLOB,     /* 0x10 BLOB */
     SQLITE_NULL,     /* 0x11 (not possible) */
     SQLITE_TEXT,     /* 0x12 (not possible) */
     SQLITE_NULL,     /* 0x13 (not possible) */
     SQLITE_INTEGER,  /* 0x14 INTEGER + BLOB */
     SQLITE_NULL,     /* 0x15 (not possible) */
     SQLITE_INTEGER,  /* 0x16 (not possible) */
     SQLITE_NULL,     /* 0x17 (not possible) */
     SQLITE_FLOAT,    /* 0x18 FLOAT + BLOB */
     SQLITE_NULL,     /* 0x19 (not possible) */
     SQLITE_TEXT,     /* 0x02 */
     SQLITE_NULL,     /* 0x03 */
     SQLITE_INTEGER,  /* 0x04 */
     SQLITE_NULL,     /* 0x05 */
     SQLITE_INTEGER,  /* 0x06 */
     SQLITE_NULL,     /* 0x07 */
     SQLITE_FLOAT,    /* 0x08 */
     SQLITE_NULL,     /* 0x09 */
     SQLITE_FLOAT,    /* 0x1a (not possible) */
     SQLITE_NULL,     /* 0x1b (not possible) */
     SQLITE_INTEGER,  /* 0x1c (not possible) */
     SQLITE_NULL,     /* 0x1d (not possible) */
     SQLITE_INTEGER,  /* 0x1e (not possible) */
     SQLITE_NULL,     /* 0x1f (not possible) */
     SQLITE_FLOAT,    /* 0x20 INTREAL */
     SQLITE_NULL,     /* 0x21 (not possible) */
     SQLITE_TEXT,     /* 0x22 INTREAL + TEXT */
     SQLITE_NULL,     /* 0x23 (not possible) */
     SQLITE_FLOAT,    /* 0x24 (not possible) */
     SQLITE_NULL,     /* 0x25 (not possible) */
     SQLITE_FLOAT,    /* 0x26 (not possible) */
     SQLITE_NULL,     /* 0x27 (not possible) */
     SQLITE_FLOAT,    /* 0x28 (not possible) */
     SQLITE_NULL,     /* 0x29 (not possible) */
     SQLITE_FLOAT,    /* 0x2a (not possible) */
     SQLITE_NULL,     /* 0x2b (not possible) */
     SQLITE_FLOAT,    /* 0x2c (not possible) */
     SQLITE_NULL,     /* 0x2d (not possible) */
     SQLITE_FLOAT,    /* 0x0a */
     SQLITE_NULL,     /* 0x0b */
     SQLITE_INTEGER,  /* 0x0c */
     SQLITE_NULL,     /* 0x0d */
     SQLITE_INTEGER,  /* 0x0e */
     SQLITE_NULL,     /* 0x0f */
     SQLITE_FLOAT,    /* 0x2e (not possible) */
     SQLITE_NULL,     /* 0x2f (not possible) */
     SQLITE_BLOB,     /* 0x30 (not possible) */
     SQLITE_NULL,     /* 0x31 (not possible) */
     SQLITE_TEXT,     /* 0x32 (not possible) */
     SQLITE_NULL,     /* 0x33 (not possible) */
     SQLITE_FLOAT,    /* 0x34 (not possible) */
     SQLITE_NULL,     /* 0x35 (not possible) */
     SQLITE_FLOAT,    /* 0x36 (not possible) */
     SQLITE_NULL,     /* 0x37 (not possible) */
     SQLITE_FLOAT,    /* 0x38 (not possible) */
     SQLITE_NULL,     /* 0x39 (not possible) */
     SQLITE_FLOAT,    /* 0x3a (not possible) */
     SQLITE_NULL,     /* 0x3b (not possible) */
     SQLITE_FLOAT,    /* 0x3c (not possible) */
     SQLITE_NULL,     /* 0x3d (not possible) */
     SQLITE_FLOAT,    /* 0x3e (not possible) */
     SQLITE_NULL,     /* 0x3f (not possible) */
     SQLITE_BLOB,     /* 0x10 */
     SQLITE_NULL,     /* 0x11 */
     SQLITE_TEXT,     /* 0x12 */
     SQLITE_NULL,     /* 0x13 */
     SQLITE_INTEGER,  /* 0x14 */
     SQLITE_NULL,     /* 0x15 */
     SQLITE_INTEGER,  /* 0x16 */
     SQLITE_NULL,     /* 0x17 */
     SQLITE_FLOAT,    /* 0x18 */
     SQLITE_NULL,     /* 0x19 */
     SQLITE_FLOAT,    /* 0x1a */
     SQLITE_NULL,     /* 0x1b */
     SQLITE_INTEGER,  /* 0x1c */
     SQLITE_NULL,     /* 0x1d */
     SQLITE_INTEGER,  /* 0x1e */
     SQLITE_NULL,     /* 0x1f */
  };
#ifdef SQLITE_DEBUG
  {
    int eType = SQLITE_BLOB;
    if( pVal->flags & MEM_Null ){
      eType = SQLITE_NULL;
    }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){
      eType = SQLITE_FLOAT;
    }else if( pVal->flags & MEM_Int ){
      eType = SQLITE_INTEGER;
    }else if( pVal->flags & MEM_Str ){
      eType = SQLITE_TEXT;
    }
    assert( eType == aType[pVal->flags&MEM_AffMask] );
  }
#endif
  return aType[pVal->flags&MEM_AffMask];
}

/* Return true if a parameter to xUpdate represents an unchanged column */
int sqlite3_value_nochange(sqlite3_value *pVal){
  return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
}
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
511
512
513
514
515
516
517















518
519
520
521
522
523
524







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







/* An SQLITE_NOMEM error. */
void sqlite3_result_error_nomem(sqlite3_context *pCtx){
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  sqlite3VdbeMemSetNull(pCtx->pOut);
  pCtx->isError = SQLITE_NOMEM_BKPT;
  sqlite3OomFault(pCtx->pOut->db);
}

#ifndef SQLITE_UNTESTABLE
/* Force the INT64 value currently stored as the result to be
** a MEM_IntReal value.  See the SQLITE_TESTCTRL_RESULT_INTREAL
** test-control.
*/
void sqlite3ResultIntReal(sqlite3_context *pCtx){ 
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  if( pCtx->pOut->flags & MEM_Int ){
    pCtx->pOut->flags &= ~MEM_Int;
    pCtx->pOut->flags |= MEM_IntReal;
  }
}
#endif


/*
** This function is called after a transaction has been committed. It 
** invokes callbacks registered with sqlite3_wal_hook() as required.
*/
static int doWalCallbacks(sqlite3 *db){
  int rc = SQLITE_OK;
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
551
552
553
554
555
556
557

558
559
560
561
562
563
564
565







-
+







** outer sqlite3_step() wrapper procedure.
*/
static int sqlite3Step(Vdbe *p){
  sqlite3 *db;
  int rc;

  assert(p);
  if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
  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.
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
589
590
591
592
593
594
595







596
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611







-
-
-
-
-
-
-








-
+







    p->rc = SQLITE_NOMEM;
    return SQLITE_NOMEM_BKPT;
  }

  if( p->pc<0 && p->expired ){
    p->rc = SQLITE_SCHEMA;
    rc = SQLITE_ERROR;
    if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
      /* If this statement was prepared using saved SQL and an 
      ** error has occurred, then return the error code in p->rc to the
      ** caller. Set the error code in the database handle to the same value.
      */ 
      rc = sqlite3VdbeTransferError(p);
    }
    goto end_of_step;
  }
  if( p->pc<0 ){
    /* If there are no other statements currently running, then
    ** reset the interrupt flag.  This prevents a call to sqlite3_interrupt
    ** from interrupting a statement that has not yet started.
    */
    if( db->nVdbeActive==0 ){
      AtomicStore(&db->u1.isInterrupted, 0);
      db->u1.isInterrupted = 0;
    }

    assert( db->nVdbeWrite>0 || db->autoCommit==0 
        || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
    );

#ifndef SQLITE_OMIT_TRACE
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734

735
736
737
738







739
740











741
742
743
744
745
746
747
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







-
-
-
-
-
-






-


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


+
+
+
+
+
+
+
+
+
+
+








    if( rc==SQLITE_DONE && db->autoCommit ){
      assert( p->rc==SQLITE_OK );
      p->rc = doWalCallbacks(db);
      if( p->rc!=SQLITE_OK ){
        rc = SQLITE_ERROR;
      }
    }else if( rc!=SQLITE_DONE && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
      /* If this statement was prepared using saved SQL and an 
      ** error has occurred, then return the error code in p->rc to the
      ** caller. Set the error code in the database handle to the same value.
      */ 
      rc = sqlite3VdbeTransferError(p);
    }
  }

  db->errCode = rc;
  if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
    p->rc = SQLITE_NOMEM_BKPT;
    if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ) rc = p->rc;
  }
end_of_step:
  /* At this point local variable rc holds the value that should be 
  /* There are only a limited number of result codes allowed from the
  ** statements prepared using the legacy sqlite3_prepare() interface */
  assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0
       || rc==SQLITE_ROW  || rc==SQLITE_DONE   || rc==SQLITE_ERROR 
  ** returned if this statement was compiled using the legacy 
  ** sqlite3_prepare() interface. According to the docs, this can only
  ** be one of the values in the first assert() below. Variable p->rc 
  ** contains the value that would be returned if sqlite3_finalize() 
  ** were called on statement p.
  */
  assert( rc==SQLITE_ROW  || rc==SQLITE_DONE   || rc==SQLITE_ERROR 
       || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
  );
  assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
  if( rc!=SQLITE_ROW 
   && rc!=SQLITE_DONE
   && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0
  ){
    /* If this statement was prepared using saved SQL and an 
    ** error has occurred, then return the error code in p->rc to the
    ** caller. Set the error code in the database handle to the same value.
    */ 
    rc = sqlite3VdbeTransferError(p);
  }
  return (rc&db->errMask);
}

/*
** This is the top-level implementation of sqlite3_step().  Call
** sqlite3Step() to do most of the work.  If a schema error occurs,
** call sqlite3Reprepare() and try again.
839
840
841
842
843
844
845
846

847
848
849
850
851
852
853
778
779
780
781
782
783
784

785
786
787
788
789
790
791
792







-
+







** is requested more than once within the same run of a single prepared
** statement, the exact same time is returned for each invocation regardless
** of the amount of time that elapses between invocations.  In other words,
** the time returned is always the time of the first call.
*/
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
  int rc;
#ifndef SQLITE_ENABLE_STAT4
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
  sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime;
  assert( p->pVdbe!=0 );
#else
  sqlite3_int64 iTime = 0;
  sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime;
#endif
  if( *piTime==0 ){
904
905
906
907
908
909
910
911

912
913
914
915
916
917
918
843
844
845
846
847
848
849

850
851
852
853
854
855
856
857







-
+







** auxiliary data pointers that is available to all functions within a
** single prepared statement.  The iArg values must match.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
  AuxData *pAuxData;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
#if SQLITE_ENABLE_STAT4
#if SQLITE_ENABLE_STAT3_OR_STAT4
  if( pCtx->pVdbe==0 ) return 0;
#else
  assert( pCtx->pVdbe!=0 );
#endif
  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
    if(  pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
      return pAuxData->pAux;
938
939
940
941
942
943
944
945

946
947
948
949
950
951
952
877
878
879
880
881
882
883

884
885
886
887
888
889
890
891







-
+







  void *pAux, 
  void (*xDelete)(void*)
){
  AuxData *pAuxData;
  Vdbe *pVdbe = pCtx->pVdbe;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pVdbe==0 ) goto failed;
#else
  assert( pVdbe!=0 );
#endif

  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
    if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
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
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







-
+




















-
+







*/
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 ){
  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 ){
    sqlite3Error(p->db, SQLITE_RANGE);
    sqlite3_mutex_leave(p->db->mutex);
    return SQLITE_RANGE;
  }
  i--;
  pVar = &p->aVar[i];
  sqlite3VdbeMemRelease(pVar);
  pVar->flags = MEM_Null;
  p->db->errCode = SQLITE_OK;

  /* If the bit corresponding to this variable in Vdbe.expmask is set, then 
  ** binding a new value to this variable invalidates the current query plan.
  **
  ** IMPLEMENTATION-OF: R-57496-20354 If the specific value bound to a host
  ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
  ** parameter in the WHERE clause might influence the choice of query plan
  ** for a statement, then the statement will be automatically recompiled,
  ** as if there had been a schema change, on the first sqlite3_step() call
  ** following any change to the bindings of that parameter.
  */
  assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 );
  if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
1683
1684
1685
1686
1687
1688
1689
1690

1691
1692
1693
1694
1695
1696
1697
1622
1623
1624
1625
1626
1627
1628

1629
1630
1631
1632
1633
1634
1635
1636







-
+







}

/*
** 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 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.
1826
1827
1828
1829
1830
1831
1832
1833

1834
1835
1836
1837
1838
1839
1840
1765
1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777
1778
1779







-
+







  /* Test that this call is being made from within an SQLITE_DELETE or
  ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
  if( !p || p->op==SQLITE_INSERT ){
    rc = SQLITE_MISUSE_BKPT;
    goto preupdate_old_out;
  }
  if( p->pPk ){
    iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);
    iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
  }
  if( iIdx>=p->pCsr->nField || iIdx<0 ){
    rc = SQLITE_RANGE;
    goto preupdate_old_out;
  }

  /* If the old.* record has not yet been loaded into memory, do so now. */
1859
1860
1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872
1873
1874
1875
1798
1799
1800
1801
1802
1803
1804


1805

1806
1807
1808
1809
1810
1811
1812







-
-
+
-








  pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
  if( iIdx==p->pTab->iPKey ){
    sqlite3VdbeMemSetInt64(pMem, p->iKey1);
  }else if( iIdx>=p->pUnpacked->nField ){
    *ppValue = (sqlite3_value *)columnNullValue();
  }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
    if( pMem->flags & (MEM_Int|MEM_IntReal) ){
      testcase( pMem->flags & MEM_Int );
    if( pMem->flags & MEM_Int ){
      testcase( pMem->flags & MEM_IntReal );
      sqlite3VdbeMemRealify(pMem);
    }
  }

 preupdate_old_out:
  sqlite3Error(db, rc);
  return sqlite3ApiExit(db, rc);
1916
1917
1918
1919
1920
1921
1922
1923

1924
1925
1926
1927
1928
1929
1930
1853
1854
1855
1856
1857
1858
1859

1860
1861
1862
1863
1864
1865
1866
1867







-
+







  Mem *pMem;

  if( !p || p->op==SQLITE_DELETE ){
    rc = SQLITE_MISUSE_BKPT;
    goto preupdate_new_out;
  }
  if( p->pPk && p->op!=SQLITE_UPDATE ){
    iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);
    iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
  }
  if( iIdx>=p->pCsr->nField || iIdx<0 ){
    rc = SQLITE_RANGE;
    goto preupdate_new_out;
  }

  if( p->op==SQLITE_INSERT ){

Changes to src/vdbeaux.c.

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







-
-
-
-
















-
+










-
-
-
-
-
-
-







*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) 
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/* Forward references */
static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef);
static void vdbeFreeOpArray(sqlite3 *, Op *, int);

/*
** Create a new virtual database engine.
*/
Vdbe *sqlite3VdbeCreate(Parse *pParse){
  sqlite3 *db = pParse->db;
  Vdbe *p;
  p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
  if( p==0 ) return 0;
  memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
  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->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);
  return p;
}

/*
** Return the Parse object that owns a Vdbe object.
*/
Parse *sqlite3VdbeParser(Vdbe *p){
  return p->pParse;
}

/*
** Change the error string stored in Vdbe.zErrMsg
*/
void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  sqlite3DbFree(p->db, p->zErrMsg);
  va_start(ap, zFormat);
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132







-
+







  pB->pNext = pTmp;
  pTmp = pA->pPrev;
  pA->pPrev = pB->pPrev;
  pB->pPrev = pTmp;
  zTmp = pA->zSql;
  pA->zSql = pB->zSql;
  pB->zSql = zTmp;
#ifdef SQLITE_ENABLE_NORMALIZE
#if 0
  zTmp = pA->zNormSql;
  pA->zNormSql = pB->zNormSql;
  pB->zNormSql = zTmp;
#endif
  pB->expmask = pA->expmask;
  pB->prepFlags = pA->prepFlags;
  memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
179
180
181
182
183
184
185

186







187

188
189
190
191
192
193
194
195







-
+
-
-
-
-
-
-
-

-
+







  }
  return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
}

#ifdef SQLITE_DEBUG
/* This routine is just a convenient place to set a breakpoint that will
** fire after each opcode is inserted and displayed using
** "PRAGMA vdbe_addoptrace=on".  Parameters "pc" (program counter) and
** "PRAGMA vdbe_addoptrace=on".
** pOp are available to make the breakpoint conditional.
**
** Other useful labels for breakpoints include:
**   test_trace_breakpoint(pc,pOp)
**   sqlite3CorruptError(lineno)
**   sqlite3MisuseError(lineno)
**   sqlite3CantopenError(lineno)
*/
static void test_addop_breakpoint(int pc, Op *pOp){
static void test_addop_breakpoint(void){
  static int n = 0;
  n++;
}
#endif

/*
** Add a new instruction to the list of instructions current in the
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
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







-
+



















-
+







  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( 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;
  pOp->p5 = 0;
  pOp->p1 = p1;
  pOp->p2 = p2;
  pOp->p3 = p3;
  pOp->p4.p = 0;
  pOp->p4type = P4_NOTUSED;
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  pOp->zComment = 0;
#endif
#ifdef SQLITE_DEBUG
  if( p->db->flags & SQLITE_VdbeAddopTrace ){
    sqlite3VdbePrintOp(0, i, &p->aOp[i]);
    test_addop_breakpoint(i, &p->aOp[i]);
    test_addop_breakpoint();
  }
#endif
#ifdef VDBE_PROFILE
  pOp->cycles = 0;
  pOp->cnt = 0;
#endif
#ifdef SQLITE_VDBE_COVERAGE
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
317
318
319
320
321
322
323











































324
325
326
327
328
329
330







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







  int p4type          /* P4 operand type */
){
  int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
  sqlite3VdbeChangeP4(p, addr, zP4, p4type);
  return addr;
}

/*
** Add an OP_Function or OP_PureFunc opcode.
**
** The eCallCtx argument is information (typically taken from Expr.op2)
** that describes the calling context of the function.  0 means a general
** function call.  NC_IsCheck means called by a check constraint,
** NC_IdxExpr means called as part of an index expression.  NC_PartIdx
** means in the WHERE clause of a partial index.  NC_GenCol means called
** while computing a generated column value.  0 is the usual case.
*/
int sqlite3VdbeAddFunctionCall(
  Parse *pParse,        /* Parsing context */
  int p1,               /* Constant argument mask */
  int p2,               /* First argument register */
  int p3,               /* Register into which results are written */
  int nArg,             /* Number of argument */
  const FuncDef *pFunc, /* The function to be invoked */
  int eCallCtx          /* Calling context */
){
  Vdbe *v = pParse->pVdbe;
  int nByte;
  int addr;
  sqlite3_context *pCtx;
  assert( v );
  nByte = sizeof(*pCtx) + (nArg-1)*sizeof(sqlite3_value*);
  pCtx = sqlite3DbMallocRawNN(pParse->db, nByte);
  if( pCtx==0 ){
    assert( pParse->db->mallocFailed );
    freeEphemeralFunction(pParse->db, (FuncDef*)pFunc);
    return 0;
  }
  pCtx->pOut = 0;
  pCtx->pFunc = (FuncDef*)pFunc;
  pCtx->pVdbe = 0;
  pCtx->isError = 0;
  pCtx->argc = nArg;
  pCtx->iOp = sqlite3VdbeCurrentAddr(v);
  addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function,
                           p1, p2, p3, (char*)pCtx, P4_FUNCCTX);
  sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef);
  return addr;
}

/*
** Add an opcode that includes the p4 value with a P4_INT64 or
** P4_REAL type.
*/
int sqlite3VdbeAddOp4Dup8(
  Vdbe *p,            /* Add the opcode to this VM */
  int op,             /* The new opcode */
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373







-
+







void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
  (void)z1;
  (void)z2;
}
#endif

/*
** Add a new OP_Explain opcode.
** Add a new OP_ opcode.
**
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
*/
void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
#ifndef SQLITE_DEBUG
  /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
406
407
408
409
410
411
412

413
414
415

416

417
418
419
420
421
422
423







-
+


-

-







** 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){
void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){
  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.
*/
int sqlite3VdbeAddOp4Int(
  Vdbe *p,            /* Add the opcode to this VM */
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
499
500
501
502
503
504
505

506
507
508
509
510
511
512
513







-
+







    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( 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
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739

740
741
742
743
744
745
746
747
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







-
















-










-
+
-







-
-
-
-
-
-
-
-















-
+
-







** to be rolled back). This condition is true if the main program or any
** sub-programs contains any of the following:
**
**   *  OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
**   *  OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
**   *  OP_Destroy
**   *  OP_VUpdate
**   *  OP_VCreate
**   *  OP_VRename
**   *  OP_FkCounter with P2==0 (immediate foreign key constraint)
**   *  OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine 
**      (for CREATE TABLE AS SELECT ...)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
** match, or false otherwise. This function is intended to be used as
** part of an assert statement in the compiler. Similar to:
**
**   assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
*/
int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
  int hasAbort = 0;
  int hasFkCounter = 0;
  int hasCreateTable = 0;
  int hasCreateIndex = 0;
  int hasInitCoroutine = 0;
  Op *pOp;
  VdbeOpIter sIter;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

  while( (pOp = opIterNext(&sIter))!=0 ){
    int opcode = pOp->opcode;
    if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
     || opcode==OP_VDestroy
     || opcode==OP_VCreate
     || (opcode==OP_Function0 && pOp->p4.pFunc->funcFlags&SQLITE_FUNC_INTERNAL)
     || opcode==OP_ParseSchema
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;
      break;
    }
    if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
    if( mayAbort ){
      /* hasCreateIndex may also be set for some DELETE statements that use
      ** OP_Clear. So this routine may end up returning true in the case 
      ** where a "DELETE FROM tbl" has a statement-journal but does not
      ** require one. This is not so bad - it is an inefficiency, not a bug. */
      if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1;
      if( opcode==OP_Clear ) hasCreateIndex = 1;
    }
    if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
#ifndef SQLITE_OMIT_FOREIGN_KEY
    if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
      hasFkCounter = 1;
    }
#endif
  }
  sqlite3DbFree(v->db, sIter.apSub);

  /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred.
  ** If malloc failed, then the while() loop above may not have iterated
  ** through all opcodes and hasAbort may be set incorrectly. Return
  ** true for this case to prevent the assert() in the callers frame
  ** from failing.  */
  return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter
        || (hasCreateTable && hasInitCoroutine) || hasCreateIndex
              || (hasCreateTable && hasInitCoroutine) );
  );
}
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */

#ifdef SQLITE_DEBUG
/*
** Increment the nWrite counter in the VDBE if the cursor is not an
** ephemeral cursor, or if the cursor argument is NULL.
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745







-
+







    */
    if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
      /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
      ** cases from this switch! */
      switch( pOp->opcode ){
        case OP_Transaction: {
          if( pOp->p2!=0 ) p->readOnly = 0;
          /* no break */ deliberate_fall_through
          /* fall thru */
        }
        case OP_AutoCommit:
        case OP_Savepoint: {
          p->bIsReader = 1;
          break;
        }
#ifndef SQLITE_OMIT_WAL
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
778
779
780
781
782
783
784

785
786
787
788
789
790
791







-







        case OP_VFilter: {
          int n;
          assert( (pOp - p->aOp) >= 3 );
          assert( pOp[-1].opcode==OP_Integer );
          n = pOp[-1].p1;
          if( n>nMaxArgs ) nMaxArgs = n;
          /* Fall through into the default case */
          /* no break */ deliberate_fall_through
        }
#endif
        default: {
          if( pOp->p2<0 ){
            /* The mkopcodeh.tcl script has so arranged things that the only
            ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
            ** have non-negative values for P2. */
887
888
889
890
891
892
893
894

895
896
897
898
899
900
901
811
812
813
814
815
816
817

818
819
820
821
822
823
824
825







-
+







  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 );
  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
972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
896
897
898
899
900
901
902

903
904
905
906
907
908
909
910







-
+







  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 );
  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;
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
963
964
965
966
967
968
969

970
971
972

973
974
975

976
977
978

979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994




























995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016

1017
1018
1019
1020
1021
1022
1023
1024







-
+


-
+


-
+


-
+















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











+
+









-
+







#endif


/*
** Change the value of the opcode, or P1, P2, P3, or P5 operands
** for a specific instruction.
*/
void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){
void sqlite3VdbeChangeOpcode(Vdbe *p, u32 addr, u8 iNewOpcode){
  sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
}
void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
  sqlite3VdbeGetOp(p,addr)->p1 = val;
}
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
  sqlite3VdbeGetOp(p,addr)->p2 = val;
}
void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
  sqlite3VdbeGetOp(p,addr)->p3 = val;
}
void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
  assert( p->nOp>0 || p->db->mallocFailed );
  if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  sqlite3VdbeChangeP2(p, addr, p->nOp);
}

/*
** Change the P2 operand of the jump instruction at addr so that
** the jump lands on the next opcode.  Or if the jump instruction was
** the previous opcode (and is thus a no-op) then simply back up
** the next instruction counter by one slot so that the jump is
** overwritten by the next inserted opcode.
**
** This routine is an optimization of sqlite3VdbeJumpHere() that
** strives to omit useless byte-code like this:
**
**        7   Once 0 8 0
**        8   ...
*/
void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){
  if( addr==p->nOp-1 ){
    assert( p->aOp[addr].opcode==OP_Once
         || p->aOp[addr].opcode==OP_If
         || p->aOp[addr].opcode==OP_FkIfZero );
    assert( p->aOp[addr].p4type==0 );
#ifdef SQLITE_VDBE_COVERAGE
    sqlite3VdbeGetOp(p,-1)->iSrcLine = 0;  /* Erase VdbeCoverage() macros */
#endif
    p->nOp--;
  }else{
    sqlite3VdbeChangeP2(p, addr, p->nOp);
  }
}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
*/
static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
  if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
    sqlite3DbFreeNN(db, pDef);
  }
}

static void vdbeFreeOpArray(sqlite3 *, Op *, int);

/*
** Delete a P4 value if necessary.
*/
static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
  if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
  sqlite3DbFreeNN(db, p);
}
static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
  freeEphemeralFunction(db, p->pFunc);
  sqlite3DbFreeNN(db, p);
 sqlite3DbFreeNN(db, p);
}
static void freeP4(sqlite3 *db, int p4type, void *p4){
  assert( db );
  switch( p4type ){
    case P4_FUNCCTX: {
      freeP4FuncCtx(db, (sqlite3_context*)p4);
      break;
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1084
1085
1086
1087
1088
1089
1090







1091
1092
1093
1094
1095
1096
1097







-
-
-
-
-
-
-







** objects when the VM is no longer required.
*/
void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
  p->pNext = pVdbe->pProgram;
  pVdbe->pProgram = p;
}

/*
** Return true if the given Vdbe has any SubPrograms.
*/
int sqlite3VdbeHasSubProgram(Vdbe *pVdbe){
  return pVdbe->pProgram!=0;
}

/*
** Change the opcode at addr into OP_Noop
*/
int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
  VdbeOp *pOp;
  if( p->db->mallocFailed ) return 0;
  assert( addr>=0 && addr<p->nOp );
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
1110
1111
1112
1113
1114
1115
1116



































1117
1118
1119
1120
1121
1122
1123







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







int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
  if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
    return sqlite3VdbeChangeToNoop(p, p->nOp-1);
  }else{
    return 0;
  }
}

#ifdef SQLITE_DEBUG
/*
** Generate an OP_ReleaseReg opcode to indicate that a range of
** registers, except any identified by mask, are no longer in use.
*/
void sqlite3VdbeReleaseRegisters(
  Parse *pParse,       /* Parsing context */
  int iFirst,          /* Index of first register to be released */
  int N,               /* Number of registers to release */
  u32 mask,            /* Mask of registers to NOT release */
  int bUndefine        /* If true, mark registers as undefined */
){
  if( N==0 ) return;
  assert( pParse->pVdbe );
  assert( iFirst>=1 );
  assert( iFirst+N-1<=pParse->nMem );
  if( N<=31 && mask!=0 ){
    while( N>0 && (mask&1)!=0 ){
      mask >>= 1;
      iFirst++;
      N--;
    }
    while( N>0 && N<=32 && (mask & MASKBIT32(N-1))!=0 ){
      mask &= ~MASKBIT32(N-1);
      N--;
    }
  }
  if( N>0 ){
    sqlite3VdbeAddOp3(pParse->pVdbe, OP_ReleaseReg, iFirst, N, *(int*)&mask);
    if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1);
  }
}
#endif /* SQLITE_DEBUG */


/*
** Change the value of the P4 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.
**
1296
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310
1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
1166







-
+







  }
}
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->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 );
1372
1373
1374
1375
1376
1377
1378
1379

1380
1381
1382
1383
1384
1385
1386
1387
1228
1229
1230
1231
1232
1233
1234

1235

1236
1237
1238
1239
1240
1241
1242







-
+
-







** Change the comment on the most recently coded instruction.  Or
** insert a No-op and add the comment to that new instruction.  This
** makes the code easier to read during debugging.  None of this happens
** in a production build.
*/
static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
  assert( p->nOp>0 || p->aOp==0 );
  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed
  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
          || p->pParse->nErr>0 );
  if( p->nOp ){
    assert( p->aOp );
    sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
    p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
  }
}
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
1425
1426
1427
1428
1429
1430
1431
1432

1433
1434
1435
1436
1437
1438
1439
1280
1281
1282
1283
1284
1285
1286

1287
1288
1289
1290
1291
1292
1293
1294







-
+







** 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 );
  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{
1463
1464
1465
1466
1467
1468
1469
1470

1471
1472
1473



1474
1475
1476
1477
1478

1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497

1498
1499
1500
1501

1502
1503

1504
1505
1506
1507

1508
1509

1510
1511
1512
1513
1514
1515
1516


1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537




1538

1539
1540

1541
1542
1543
1544



1545

1546
1547
1548



1549
1550


1551
1552

1553
1554

1555
1556
1557
1558
1559
1560
1561
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







-
+
-

-
+
+
+




-
+

-
-
-














-
+



-
+

-
+




+


+





-
-
+
+
-
-

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

-
+


-
-
+
+
+

+

-
-
+
+
+
-
-
+
+

-
+

-
+







** Some translation occurs:
**
**       "PX"      ->  "r[X]"
**       "PX@PY"   ->  "r[X..X+Y-1]"  or "r[x]" if y is 0 or 1
**       "PX@PY+1" ->  "r[X..X+Y]"    or "r[x]" if y is 0
**       "PY..PY"  ->  "r[X..Y]"      or "r[x]" if y<=x
*/
char *sqlite3VdbeDisplayComment(
static int displayComment(
  sqlite3 *db,       /* Optional - Oom error reporting only */
  const Op *pOp,     /* The opcode to be commented */
  const char *zP4    /* Previously obtained value for P4 */
  const char *zP4,   /* Previously obtained value for P4 */
  char *zTemp,       /* Write result here */
  int nTemp          /* Space available in zTemp[] */
){
  const char *zOpName;
  const char *zSynopsis;
  int nOpName;
  int ii;
  int ii, jj;
  char zAlt[50];
  StrAccum x;

  sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
  zOpName = sqlite3OpcodeName(pOp->opcode);
  nOpName = sqlite3Strlen30(zOpName);
  if( zOpName[nOpName+1] ){
    int seenCom = 0;
    char c;
    zSynopsis = zOpName += nOpName + 1;
    if( strncmp(zSynopsis,"IF ",3)==0 ){
      if( pOp->p5 & SQLITE_STOREP2 ){
        sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3);
      }else{
        sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
      }
      zSynopsis = zAlt;
    }
    for(ii=0; (c = zSynopsis[ii])!=0; ii++){
    for(ii=jj=0; jj<nTemp-1 && (c = zSynopsis[ii])!=0; ii++){
      if( c=='P' ){
        c = zSynopsis[++ii];
        if( c=='4' ){
          sqlite3_str_appendall(&x, zP4);
          sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", zP4);
        }else if( c=='X' ){
          sqlite3_str_appendall(&x, pOp->zComment);
          sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", pOp->zComment);
          seenCom = 1;
        }else{
          int v1 = translateP(c, pOp);
          int v2;
          sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1);
          if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
            ii += 3;
            jj += sqlite3Strlen30(zTemp+jj);
            v2 = translateP(zSynopsis[ii], pOp);
            if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){
              ii += 2;
              v2++;
            }
            if( v2<2 ){
              sqlite3_str_appendf(&x, "%d", v1);
            if( v2>1 ){
              sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
            }else{
              sqlite3_str_appendf(&x, "%d..%d", v1, v1+v2-1);
            }
          }else if( strncmp(zSynopsis+ii+1, "@NP", 3)==0 ){
            sqlite3_context *pCtx = pOp->p4.pCtx;
            if( pOp->p4type!=P4_FUNCCTX || pCtx->argc==1 ){
              sqlite3_str_appendf(&x, "%d", v1);
            }else if( pCtx->argc>1 ){
              sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1);
            }else if( x.accError==0 ){
              assert( x.nChar>2 );
              x.nChar -= 2;
              ii++;
            }
            ii += 3;
          }else{
            sqlite3_str_appendf(&x, "%d", v1);
            if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
              ii += 4;
            }
          }
          }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
            ii += 4;
          }
        }
        }
        jj += sqlite3Strlen30(zTemp+jj);
      }else{
        sqlite3_str_appendchar(&x, 1, c);
        zTemp[jj++] = c;
      }
    }
    if( !seenCom && pOp->zComment ){
      sqlite3_str_appendf(&x, "; %s", pOp->zComment);
    if( !seenCom && jj<nTemp-5 && pOp->zComment ){
      sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment);
      jj += sqlite3Strlen30(zTemp+jj);
    }
    if( jj<nTemp ) zTemp[jj] = 0;
  }else if( pOp->zComment ){
    sqlite3_str_appendall(&x, pOp->zComment);
  }
    sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment);
    jj = sqlite3Strlen30(zTemp);
  }else{
  if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
    sqlite3OomFault(db);
    zTemp[0] = 0;
    jj = 0;
  }
  return sqlite3StrAccumFinish(&x);
  return jj;
}
#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */
#endif /* SQLITE_DEBUG */

#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
/*
** Translate the P4.pExpr value for an OP_CursorHint opcode into text
** that can be displayed in the P4 column of EXPLAIN output.
*/
static void displayP4Expr(StrAccum *p, Expr *pExpr){
1628
1629
1630
1631
1632
1633
1634
1635
1636


1637
1638
1639


1640
1641
1642
1643
1644

1645
1646
1647
1648
1649
1650
1651


1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668

1669
1670
1671
1672
1673
1674
1675
1676

1677
1678
1679
1680
1681

1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698

1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720



1721
1722
1723

1724

1725
1726
1727
1728
1729

1730
1731
1732
1733

1734
1735
1736
1737

1738
1739
1740
1741



1742
1743


1744
1745
1746
1747
1748



1749
1750
1751
1752
1753
1754
1755
1470
1471
1472
1473
1474
1475
1476


1477
1478
1479


1480
1481
1482
1483
1484
1485

1486
1487
1488
1489
1490
1491


1492
1493


1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504

1505


1506

1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536

1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556



1557
1558
1559
1560
1561

1562
1563
1564
1565
1566
1567
1568

1569
1570
1571
1572
1573
1574
1575
1576
1577

1578
1579
1580
1581
1582
1583
1584
1585


1586
1587



1588

1589
1590
1591
1592
1593
1594
1595
1596
1597
1598







-
-
+
+

-
-
+
+




-
+





-
-
+
+
-
-











-

-
-
+
-







+





+
















-
+



















-
-
-
+
+
+


-
+

+




-
+




+



-
+




+
+
+
-
-
+
+
-
-
-

-
+
+
+









#if VDBE_DISPLAY_P4
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
  char *zP4 = 0;
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
  char *zP4 = zTemp;
  StrAccum x;

  sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
  assert( nTemp>=20 );
  sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
  switch( pOp->p4type ){
    case P4_KEYINFO: {
      int j;
      KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
      assert( pKeyInfo->aSortFlags!=0 );
      assert( pKeyInfo->aSortOrder!=0 );
      sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
      for(j=0; j<pKeyInfo->nKeyField; j++){
        CollSeq *pColl = pKeyInfo->aColl[j];
        const char *zColl = pColl ? pColl->zName : "";
        if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
        sqlite3_str_appendf(&x, ",%s%s%s", 
               (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "", 
        sqlite3_str_appendf(&x, ",%s%s", 
               pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
               (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "", 
               zColl);
      }
      sqlite3_str_append(&x, ")", 1);
      break;
    }
#ifdef SQLITE_ENABLE_CURSOR_HINTS
    case P4_EXPR: {
      displayP4Expr(&x, pOp->p4.pExpr);
      break;
    }
#endif
    case P4_COLLSEQ: {
      static const char *const encnames[] = {"?", "8", "16LE", "16BE"};
      CollSeq *pColl = pOp->p4.pColl;
      assert( pColl->enc>=0 && pColl->enc<4 );
      sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName,
      sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
                          encnames[pColl->enc]);
      break;
    }
    case P4_FUNCDEF: {
      FuncDef *pDef = pOp->p4.pFunc;
      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
      break;
    }
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
    case P4_FUNCCTX: {
      FuncDef *pDef = pOp->p4.pCtx->pFunc;
      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
      break;
    }
#endif
    case P4_INT64: {
      sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
      break;
    }
    case P4_INT32: {
      sqlite3_str_appendf(&x, "%d", pOp->p4.i);
      break;
    }
    case P4_REAL: {
      sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal);
      break;
    }
    case P4_MEM: {
      Mem *pMem = pOp->p4.pMem;
      if( pMem->flags & MEM_Str ){
        zP4 = pMem->z;
      }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
      }else if( pMem->flags & MEM_Int ){
        sqlite3_str_appendf(&x, "%lld", pMem->u.i);
      }else if( pMem->flags & MEM_Real ){
        sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
      }else if( pMem->flags & MEM_Null ){
        zP4 = "NULL";
      }else{
        assert( pMem->flags & MEM_Blob );
        zP4 = "(blob)";
      }
      break;
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    case P4_VTAB: {
      sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
      sqlite3_str_appendf(&x, "vtab:%p", pVtab);
      break;
    }
#endif
    case P4_INTARRAY: {
      u32 i;
      u32 *ai = pOp->p4.ai;
      u32 n = ai[0];   /* The first element of an INTARRAY is always the
      int i;
      int *ai = pOp->p4.ai;
      int n = ai[0];   /* The first element of an INTARRAY is always the
                       ** count of the number of elements to follow */
      for(i=1; i<=n; i++){
        sqlite3_str_appendf(&x, "%c%u", (i==1 ? '[' : ','), ai[i]);
        sqlite3_str_appendf(&x, ",%d", ai[i]);
      }
      zTemp[0] = '[';
      sqlite3_str_append(&x, "]", 1);
      break;
    }
    case P4_SUBPROGRAM: {
      zP4 = "program";
      sqlite3_str_appendf(&x, "program");
      break;
    }
    case P4_DYNBLOB:
    case P4_ADVANCE: {
      zTemp[0] = 0;
      break;
    }
    case P4_TABLE: {
      zP4 = pOp->p4.pTab->zName;
      sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
      break;
    }
    default: {
      zP4 = pOp->p4.z;
      if( zP4==0 ){
        zP4 = zTemp;
        zTemp[0] = 0;
    }
  }
      }
    }
  if( zP4 ) sqlite3_str_appendall(&x, zP4);
  if( (x.accError & SQLITE_NOMEM)!=0 ){
    sqlite3OomFault(db);
  }
  return sqlite3StrAccumFinish(&x);
  sqlite3StrAccumFinish(&x);
  assert( zP4!=0 );
  return zP4;
}
#endif /* VDBE_DISPLAY_P4 */

/*
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
**
** The prepared statements need to know in advance the complete set of
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
1674
1675
1676
1677
1678
1679
1680


1681
1682
1683
1684



1685
1686

1687
1688

1689
1690
1691
1692
1693
1694

1695


1696
1697
1698



1699
1700
1701
1702
1703
1704
1705







-
-
+
+


-
-
-
+

-
+

-
+





-
+
-
-
+


-
-
-








#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Print a single opcode.  This routine is used for debugging only.
*/
void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
  char *zP4;
  char *zCom;
  sqlite3 dummyDb;
  char zPtr[50];
  char zCom[100];
  static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
  if( pOut==0 ) pOut = stdout;
  sqlite3BeginBenignMalloc();
  dummyDb.mallocFailed = 1;
  zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp);
  zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  zCom = sqlite3VdbeDisplayComment(0, pOp, zP4);
  displayComment(pOp, zP4, zCom, sizeof(zCom));
#else
  zCom = 0;
  zCom[0] = 0;
#endif
  /* NB:  The sqlite3OpcodeName() function is implemented by code created
  ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
  ** information from the vdbe.c source text */
  fprintf(pOut, zFormat1, pc, 
      sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, 
      sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
      zP4 ? zP4 : "", pOp->p5,
      zCom ? zCom : ""
      zCom
  );
  fflush(pOut);
  sqlite3_free(zP4);
  sqlite3_free(zCom);
  sqlite3EndBenignMalloc();
}
#endif

/*
** Initialize an array of N Mem element.
*/
static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
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
1782
1783
1784
1785
1786
1787
1788



















































































































1789
1790
1791
1792
1793
1794
1795







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







void sqlite3VdbeFrameMemDel(void *pArg){
  VdbeFrame *pFrame = (VdbeFrame*)pArg;
  assert( sqlite3VdbeFrameIsValid(pFrame) );
  pFrame->pParent = pFrame->v->pDelFrame;
  pFrame->v->pDelFrame = pFrame;
}

#if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN)
/*
** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN
** QUERY PLAN output.
**
** Return SQLITE_ROW on success.  Return SQLITE_DONE if there are no
** more opcodes to be displayed.
*/
int sqlite3VdbeNextOpcode(
  Vdbe *p,         /* The statement being explained */
  Mem *pSub,       /* Storage for keeping track of subprogram nesting */
  int eMode,       /* 0: normal.  1: EQP.  2:  TablesUsed */
  int *piPc,       /* IN/OUT: Current rowid.  Overwritten with next rowid */
  int *piAddr,     /* OUT: Write index into (*paOp)[] here */
  Op **paOp        /* OUT: Write the opcode array here */
){
  int nRow;                            /* Stop when row count reaches this */
  int nSub = 0;                        /* Number of sub-vdbes seen so far */
  SubProgram **apSub = 0;              /* Array of sub-vdbes */
  int i;                               /* Next instruction address */
  int rc = SQLITE_OK;                  /* Result code */
  Op *aOp = 0;                         /* Opcode array */
  int iPc;                             /* Rowid.  Copy of value in *piPc */

  /* When the number of output rows reaches nRow, that means the
  ** listing has finished and sqlite3_step() should return SQLITE_DONE.
  ** nRow is the sum of the number of rows in the main program, plus
  ** the sum of the number of rows in all trigger subprograms encountered
  ** so far.  The nRow value will increase as new trigger subprograms are
  ** encountered, but p->pc will eventually catch up to nRow.
  */
  nRow = p->nOp;
  if( pSub!=0 ){
    if( pSub->flags&MEM_Blob ){
      /* pSub is initiallly NULL.  It is initialized to a BLOB by
      ** the P4_SUBPROGRAM processing logic below */
      nSub = pSub->n/sizeof(Vdbe*);
      apSub = (SubProgram **)pSub->z;
    }
    for(i=0; i<nSub; i++){
      nRow += apSub[i]->nOp;
    }
  }
  iPc = *piPc;
  while(1){  /* Loop exits via break */
    i = iPc++;
    if( i>=nRow ){
      p->rc = SQLITE_OK;
      rc = SQLITE_DONE;
      break;
    }
    if( i<p->nOp ){
      /* The rowid is small enough that we are still in the
      ** main program. */
      aOp = p->aOp;
    }else{
      /* We are currently listing subprograms.  Figure out which one and
      ** pick up the appropriate opcode. */
      int j;
      i -= p->nOp;
      assert( apSub!=0 );
      assert( nSub>0 );
      for(j=0; i>=apSub[j]->nOp; j++){
        i -= apSub[j]->nOp;
        assert( i<apSub[j]->nOp || j+1<nSub );
      }
      aOp = apSub[j]->aOp;
    }

    /* When an OP_Program opcode is encounter (the only opcode that has
    ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
    ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
    ** has not already been seen.
    */
    if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){
      int nByte = (nSub+1)*sizeof(SubProgram*);
      int j;
      for(j=0; j<nSub; j++){
        if( apSub[j]==aOp[i].p4.pProgram ) break;
      }
      if( j==nSub ){
        p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
        if( p->rc!=SQLITE_OK ){
          rc = SQLITE_ERROR;
          break;
        }
        apSub = (SubProgram **)pSub->z;
        apSub[nSub++] = aOp[i].p4.pProgram;
        MemSetTypeFlag(pSub, MEM_Blob);
        pSub->n = nSub*sizeof(SubProgram*);
        nRow += aOp[i].p4.pProgram->nOp;
      }
    }
    if( eMode==0 ) break;
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
    if( eMode==2 ){
      Op *pOp = aOp + i;
      if( pOp->opcode==OP_OpenRead ) break;
      if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break;
      if( pOp->opcode==OP_ReopenIdx ) break;      
    }else
#endif
    {
      assert( eMode==1 );
      if( aOp[i].opcode==OP_Explain ) break;
      if( aOp[i].opcode==OP_Init && iPc>1 ) break;
    }
  }
  *piPc = iPc;
  *piAddr = i;
  *paOp = aOp;
  return rc;
}
#endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */


/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
** allocated by the OP_Program opcode in sqlite3VdbeExec().
*/
void sqlite3VdbeFrameDelete(VdbeFrame *p){
  int i;
2100
2101
2102
2103
2104
2105
2106



2107
2108
2109
2110
2111
2112
2113
2114

2115
2116
2117

2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133








2134
2135
2136
2137
2138
2139
2140






















2141
2142
2143
2144
2145
2146
2147








































2148
2149
2150

2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161



































2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174





















2175



2176
2177

2178

2179
2180


2181
2182

2183
2184
2185
2186
2187
2188


2189
2190
2191
2192
2193
2194
2195
2196
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837


1838
1839
1840

1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894







1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935


1936
1937
1938
1939
1940







1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976












1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002

2003
2004
2005


2006
2007


2008






2009
2010

2011
2012
2013
2014
2015
2016
2017







+
+
+






-
-
+


-
+
















+
+
+
+
+
+
+
+







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

-
-
+




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

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

+
+
+

-
+

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







**
** When p->explain==1, first the main program is listed, then each of
** the trigger subprograms are listed one by one.
*/
int sqlite3VdbeList(
  Vdbe *p                   /* The VDBE */
){
  int nRow;                            /* Stop when row count reaches this */
  int nSub = 0;                        /* Number of sub-vdbes seen so far */
  SubProgram **apSub = 0;              /* Array of sub-vdbes */
  Mem *pSub = 0;                       /* Memory cell hold array of subprogs */
  sqlite3 *db = p->db;                 /* The database connection */
  int i;                               /* Loop counter */
  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 */
  Op *pOp = 0;

  assert( p->explain );
  assert( p->iVdbeMagic==VDBE_MAGIC_RUN );
  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);
  p->pResultSet = 0;

  if( p->rc==SQLITE_NOMEM ){
    /* This happens if a malloc() inside a call to sqlite3_column_text() or
    ** sqlite3_column_text16() failed.  */
    sqlite3OomFault(db);
    return SQLITE_ERROR;
  }

  /* When the number of output rows reaches nRow, that means the
  ** listing has finished and sqlite3_step() should return SQLITE_DONE.
  ** nRow is the sum of the number of rows in the main program, plus
  ** the sum of the number of rows in all trigger subprograms encountered
  ** so far.  The nRow value will increase as new trigger subprograms are
  ** encountered, but p->pc will eventually catch up to nRow.
  */
  nRow = p->nOp;
  if( bListSubprogs ){
    /* The first 8 memory cells are used for the result set.  So we will
    ** commandeer the 9th cell to use as storage for an array of pointers
    ** to trigger subprograms.  The VDBE is guaranteed to have at least 9
    ** cells.  */
    assert( p->nMem>9 );
    pSub = &p->aMem[9];
    if( pSub->flags&MEM_Blob ){
      /* On the first call to sqlite3_step(), pSub will hold a NULL.  It is
      ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
      nSub = pSub->n/sizeof(Vdbe*);
      apSub = (SubProgram **)pSub->z;
    }
    for(i=0; i<nSub; i++){
      nRow += apSub[i]->nOp;
    }
  }

  while(1){  /* Loop exits via break */
    i = p->pc++;
    if( i>=nRow ){
      p->rc = SQLITE_OK;
      rc = SQLITE_DONE;
      break;
    }
    if( i<p->nOp ){
      /* The output line number is small enough that we are still in the
      ** main program. */
      pOp = &p->aOp[i];
  }else{
    pSub = 0;
  }

  /* Figure out which opcode is next to display */
  rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp);

    }else{
      /* We are currently listing subprograms.  Figure out which one and
      ** pick up the appropriate opcode. */
      int j;
      i -= p->nOp;
      for(j=0; i>=apSub[j]->nOp; j++){
        i -= apSub[j]->nOp;
      }
      pOp = &apSub[j]->aOp[i];
    }

    /* When an OP_Program opcode is encounter (the only opcode that has
    ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
    ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
    ** has not already been seen.
    */
    if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
      int nByte = (nSub+1)*sizeof(SubProgram*);
      int j;
      for(j=0; j<nSub; j++){
        if( apSub[j]==pOp->p4.pProgram ) break;
      }
      if( j==nSub ){
        p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
        if( p->rc!=SQLITE_OK ){
          rc = SQLITE_ERROR;
          break;
        }
        apSub = (SubProgram **)pSub->z;
        apSub[nSub++] = pOp->p4.pProgram;
        pSub->flags |= MEM_Blob;
        pSub->n = nSub*sizeof(SubProgram*);
        nRow += pOp->p4.pProgram->nOp;
      }
    }
    if( p->explain<2 ) break;
    if( pOp->opcode==OP_Explain ) break;
    if( pOp->opcode==OP_Init && p->pc>1 ) break;
  }

  if( rc==SQLITE_OK ){
    pOp = aOp + i;
    if( AtomicLoad(&db->u1.isInterrupted) ){
    if( db->u1.isInterrupted ){
      p->rc = SQLITE_INTERRUPT;
      rc = SQLITE_ERROR;
      sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
    }else{
      char *zP4 = sqlite3VdbeDisplayP4(db, pOp);
      if( p->explain==2 ){
        sqlite3VdbeMemSetInt64(pMem, pOp->p1);
        sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
        sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
        sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);     
        p->nResColumn = 4;
      char *zP4;
      if( p->explain==1 ){
        pMem->flags = MEM_Int;
        pMem->u.i = i;                                /* Program counter */
        pMem++;
    
        pMem->flags = MEM_Static|MEM_Str|MEM_Term;
        pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
        assert( pMem->z!=0 );
        pMem->n = sqlite3Strlen30(pMem->z);
        pMem->enc = SQLITE_UTF8;
        pMem++;
      }

      pMem->flags = MEM_Int;
      pMem->u.i = pOp->p1;                          /* P1 */
      pMem++;

      pMem->flags = MEM_Int;
      pMem->u.i = pOp->p2;                          /* P2 */
      pMem++;

      pMem->flags = MEM_Int;
      pMem->u.i = pOp->p3;                          /* P3 */
      pMem++;

      if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
        assert( p->db->mallocFailed );
        return SQLITE_ERROR;
      }
      pMem->flags = MEM_Str|MEM_Term;
      zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
      if( zP4!=pMem->z ){
        pMem->n = 0;
        sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
      }else{
        sqlite3VdbeMemSetInt64(pMem+0, i);
        sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
                             -1, SQLITE_UTF8, SQLITE_STATIC);
        sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
        sqlite3VdbeMemSetInt64(pMem+3, pOp->p2);
        sqlite3VdbeMemSetInt64(pMem+4, pOp->p3);
        /* pMem+5 for p4 is done last */
        sqlite3VdbeMemSetInt64(pMem+6, pOp->p5);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
        {
          char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4);
          sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
        assert( pMem->z!=0 );
        pMem->n = sqlite3Strlen30(pMem->z);
        pMem->enc = SQLITE_UTF8;
      }
      pMem++;

      if( p->explain==1 ){
        if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
          assert( p->db->mallocFailed );
          return SQLITE_ERROR;
        }
        pMem->flags = MEM_Str|MEM_Term;
        pMem->n = 2;
        sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5);   /* P5 */
        pMem->enc = SQLITE_UTF8;
        pMem++;
    
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
        if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
          assert( p->db->mallocFailed );
          return SQLITE_ERROR;
        }
        pMem->flags = MEM_Str|MEM_Term;
        pMem->n = displayComment(pOp, zP4, pMem->z, 500);
        pMem->enc = SQLITE_UTF8;
#else
        sqlite3VdbeMemSetNull(pMem+7);
        pMem->flags = MEM_Null;                       /* Comment */
#endif
      }
        sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
        p->nResColumn = 8;

      p->nResColumn = 8 - 4*(p->explain-1);
      }
      p->pResultSet = pMem;
      p->pResultSet = &p->aMem[1];
      if( db->mallocFailed ){
        p->rc = SQLITE_NOMEM;
        rc = SQLITE_ERROR;
      }else{
        p->rc = SQLITE_OK;
        rc = SQLITE_ROW;
      p->rc = SQLITE_OK;
      rc = SQLITE_ROW;
      }
    }
  }
  return rc;
}
#endif /* SQLITE_OMIT_EXPLAIN */

#ifdef SQLITE_DEBUG
2290
2291
2292
2293
2294
2295
2296
2297

2298
2299
2300
2301
2302
2303
2304

2305
2306
2307
2308
2309
2310
2311
2111
2112
2113
2114
2115
2116
2117

2118
2119
2120
2121
2122
2123
2124

2125
2126
2127
2128
2129
2130
2131
2132







-
+






-
+







** 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 );
  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->iVdbeMagic = VDBE_MAGIC_RUN;
  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;
2353
2354
2355
2356
2357
2358
2359
2360

2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2174
2175
2176
2177
2178
2179
2180

2181
2182


2183
2184
2185
2186
2187
2188
2189







-
+

-
-







  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( p->magic==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;
  
2385
2386
2387
2388
2389
2390
2391
2392

2393
2394
2395
2396
2397
2398

2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2204
2205
2206
2207
2208
2209
2210

2211






2212














2213
2214
2215
2216
2217
2218
2219







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







  assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
  x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused memory */
  assert( x.nFree>=0 );
  assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );

  resolveP2Values(p, &nArg);
  p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
  if( pParse->explain ){
  if( pParse->explain && nMem<10 ){
    static const char * const azColName[] = {
       "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
       "id", "parent", "notused", "detail"
    };
    int iFirst, mx, i;
    if( nMem<10 ) nMem = 10;
    nMem = 10;
    p->explain = pParse->explain;
    if( pParse->explain==2 ){
      sqlite3VdbeSetNumCols(p, 4);
      iFirst = 8;
      mx = 12;
    }else{
      sqlite3VdbeSetNumCols(p, 8);
      iFirst = 0;
      mx = 8;
    }
    for(i=iFirst; i<mx; i++){
      sqlite3VdbeSetColName(p, i-iFirst, COLNAME_NAME,
                            azColName[i], SQLITE_STATIC);
    }
  }
  p->expired = 0;

  /* Memory for registers, parameters, cursor, etc, is allocated in one or two
  ** passes.  On the first pass, we try to reuse unused memory at the 
  ** end of the opcode array.  If we are unable to satisfy all memory
  ** requirements by reusing the opcode array tail, then the second
2441
2442
2443
2444
2445
2446
2447



2448
2449
2450
2451
2452
2453
2454
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257







+
+
+







      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;
  p->explain = pParse->explain;
  if( db->mallocFailed ){
    p->nVar = 0;
    p->nCursor = 0;
    p->nMem = 0;
  }else{
    p->nCursor = nCursor;
    p->nVar = (ynVar)nVar;
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481





2482
2483



2484
2485
2486
2487
2488
2489
2490
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







-






+
+
+
+
+
-
-
+
+
+







** happens to hold.
*/
void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
  if( pCx==0 ){
    return;
  }
  assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE );
  assert( pCx->pBtx==0 || pCx->isEphemeral );
  switch( pCx->eCurType ){
    case CURTYPE_SORTER: {
      sqlite3VdbeSorterClose(p->db, pCx);
      break;
    }
    case CURTYPE_BTREE: {
      if( pCx->isEphemeral ){
        if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx);
        /* The pCx->pCursor will be close automatically, if it exists, by
        ** the call above. */
      }else{
      assert( pCx->uc.pCursor!=0 );
      sqlite3BtreeCloseCursor(pCx->uc.pCursor);
        assert( pCx->uc.pCursor!=0 );
        sqlite3BtreeCloseCursor(pCx->uc.pCursor);
      }
      break;
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    case CURTYPE_VTAB: {
      sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur;
      const sqlite3_module *pModule = pVCur->pVtab->pModule;
      assert( pVCur->pVtab->nRef>0 );
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
2431
2432
2433
2434
2435
2436
2437

2438
2439
2440
2441
2442
2443

2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456

2457
2458
2459
2460
2461
2462
2463
2464
2465

2466
2467
2468
2469
2470


2471
2472
2473

2474
2475
2476
2477
2478
2479
2480
2481







-
+





-
+












-
+








-
+




-
-
+
+

-
+







  return rc;
}

/*
** A read or write transaction may or may not be active on database handle
** db. If a transaction is active, commit it. If there is a
** write-transaction spanning more than one database file, this routine
** takes care of the super-journal trickery.
** takes care of the master journal trickery.
*/
static int vdbeCommit(sqlite3 *db, Vdbe *p){
  int i;
  int nTrans = 0;  /* Number of databases with an active write-transaction
                   ** that are candidates for a two-phase commit using a
                   ** super-journal */
                   ** master-journal */
  int rc = SQLITE_OK;
  int needXcommit = 0;

#ifdef SQLITE_OMIT_VIRTUALTABLE
  /* With this option, sqlite3VtabSync() is defined to be simply 
  ** SQLITE_OK so p is not used. 
  */
  UNUSED_PARAMETER(p);
#endif

  /* Before doing anything else, call the xSync() callback for any
  ** virtual module tables written in this transaction. This has to
  ** be done before determining whether a super-journal file is 
  ** be done before determining whether a master journal file is 
  ** required, as an xSync() callback may add an attached database
  ** to the transaction.
  */
  rc = sqlite3VtabSync(db, p);

  /* This loop determines (a) if the commit hook should be invoked and
  ** (b) how many database files have open write transactions, not 
  ** including the temp database. (b) is important because if more than 
  ** one database file has an open write transaction, a super-journal
  ** one database file has an open write transaction, a master journal
  ** file is required for an atomic commit.
  */ 
  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
    Btree *pBt = db->aDb[i].pBt;
    if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
      /* Whether or not a database might need a super-journal depends upon
    if( sqlite3BtreeIsInTrans(pBt) ){
      /* Whether or not a database might need a master journal depends upon
      ** its journal mode (among other things).  This matrix determines which
      ** journal modes use a super-journal and which do not */
      ** journal modes use a master journal and which do not */
      static const u8 aMJNeeded[] = {
        /* DELETE   */  1,
        /* PERSIST   */ 1,
        /* OFF       */ 0,
        /* TRUNCATE  */ 1,
        /* MEMORY    */ 0,
        /* WAL       */ 0
2697
2698
2699
2700
2701
2702
2703
2704

2705
2706
2707
2708
2709
2710
2711
2505
2506
2507
2508
2509
2510
2511

2512
2513
2514
2515
2516
2517
2518
2519







-
+







    if( rc ){
      return SQLITE_CONSTRAINT_COMMITHOOK;
    }
  }

  /* The simple case - no more than one database file (not counting the
  ** TEMP database) has a transaction active.   There is no need for the
  ** super-journal.
  ** master-journal.
  **
  ** If the return value of sqlite3BtreeGetFilename() is a zero length
  ** string, it means the main database is :memory: or a temp file.  In 
  ** that case we do not support atomic multi-file commits, so use the 
  ** simple case then too.
  */
  if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt))
2731
2732
2733
2734
2735
2736
2737
2738

2739
2740
2741
2742
2743
2744

2745
2746

2747
2748
2749
2750
2751
2752

2753
2754
2755


2756
2757
2758
2759
2760
2761
2762


2763
2764
2765

2766
2767
2768
2769
2770

2771
2772

2773
2774
2775
2776



2777
2778
2779
2780


2781
2782

2783
2784
2785
2786

2787
2788
2789
2790
2791
2792
2793



2794
2795
2796
2797
2798

2799
2800
2801
2802
2803
2804

2805
2806
2807
2808
2809



2810
2811
2812
2813
2814
2815

2816
2817
2818
2819


2820
2821
2822
2823



2824
2825
2826
2827
2828
2829


2830
2831
2832
2833
2834


2835
2836
2837
2838
2839
2840

2841
2842
2843

2844
2845
2846

2847
2848
2849
2850

2851
2852
2853
2854
2855
2856



2857
2858
2859
2860
2861
2862
2863
2539
2540
2541
2542
2543
2544
2545

2546
2547
2548
2549
2550
2551

2552
2553

2554
2555
2556
2557
2558
2559

2560
2561


2562
2563

2564
2565
2566
2567


2568
2569
2570
2571

2572
2573
2574
2575
2576

2577
2578

2579
2580



2581
2582
2583
2584
2585


2586
2587
2588

2589
2590
2591
2592

2593
2594
2595
2596
2597



2598
2599
2600
2601
2602
2603
2604

2605
2606
2607
2608
2609
2610

2611
2612
2613



2614
2615
2616
2617
2618
2619
2620
2621

2622
2623
2624


2625
2626
2627



2628
2629
2630
2631
2632
2633
2634


2635
2636
2637
2638
2639


2640
2641
2642
2643
2644
2645
2646

2647
2648
2649

2650
2651
2652

2653
2654
2655
2656

2657
2658
2659
2660



2661
2662
2663
2664
2665
2666
2667
2668
2669
2670







-
+





-
+

-
+





-
+

-
-
+
+
-




-
-
+
+


-
+




-
+

-
+

-
-
-
+
+
+


-
-
+
+

-
+



-
+




-
-
-
+
+
+




-
+





-
+


-
-
-
+
+
+





-
+


-
-
+
+

-
-
-
+
+
+




-
-
+
+



-
-
+
+





-
+


-
+


-
+



-
+



-
-
-
+
+
+







    }
    if( rc==SQLITE_OK ){
      sqlite3VtabCommit(db);
    }
  }

  /* The complex case - There is a multi-file write-transaction active.
  ** This requires a super-journal file to ensure the transaction is
  ** This requires a master journal file to ensure the transaction is
  ** committed atomically.
  */
#ifndef SQLITE_OMIT_DISKIO
  else{
    sqlite3_vfs *pVfs = db->pVfs;
    char *zSuper = 0;   /* File-name for the super-journal */
    char *zMaster = 0;   /* File-name for the master journal */
    char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
    sqlite3_file *pSuperJrnl = 0;
    sqlite3_file *pMaster = 0;
    i64 offset = 0;
    int res;
    int retryCount = 0;
    int nMainFile;

    /* Select a super-journal file name */
    /* Select a master journal file name */
    nMainFile = sqlite3Strlen30(zMainFile);
    zSuper = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0);
    if( zSuper==0 ) return SQLITE_NOMEM_BKPT;
    zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
    if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
    zSuper += 4;
    do {
      u32 iRandom;
      if( retryCount ){
        if( retryCount>100 ){
          sqlite3_log(SQLITE_FULL, "MJ delete: %s", zSuper);
          sqlite3OsDelete(pVfs, zSuper, 0);
          sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
          sqlite3OsDelete(pVfs, zMaster, 0);
          break;
        }else if( retryCount==1 ){
          sqlite3_log(SQLITE_FULL, "MJ collide: %s", zSuper);
          sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster);
        }
      }
      retryCount++;
      sqlite3_randomness(sizeof(iRandom), &iRandom);
      sqlite3_snprintf(13, &zSuper[nMainFile], "-mj%06X9%02X",
      sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X",
                               (iRandom>>8)&0xffffff, iRandom&0xff);
      /* The antipenultimate character of the super-journal name must
      /* The antipenultimate character of the master journal name must
      ** be "9" to avoid name collisions when using 8+3 filenames. */
      assert( zSuper[sqlite3Strlen30(zSuper)-3]=='9' );
      sqlite3FileSuffix3(zMainFile, zSuper);
      rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res);
      assert( zMaster[sqlite3Strlen30(zMaster)-3]=='9' );
      sqlite3FileSuffix3(zMainFile, zMaster);
      rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
    }while( rc==SQLITE_OK && res );
    if( rc==SQLITE_OK ){
      /* Open the super-journal. */
      rc = sqlite3OsOpenMalloc(pVfs, zSuper, &pSuperJrnl, 
      /* Open the master journal. */
      rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, 
          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
          SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_SUPER_JOURNAL, 0
          SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
      );
    }
    if( rc!=SQLITE_OK ){
      sqlite3DbFree(db, zSuper-4);
      sqlite3DbFree(db, zMaster);
      return rc;
    }
 
    /* Write the name of each database file in the transaction into the new
    ** super-journal file. If an error occurs at this point close
    ** and delete the super-journal file. All the individual journal files
    ** still have 'null' as the super-journal pointer, so they will roll
    ** master journal file. If an error occurs at this point close
    ** and delete the master journal file. All the individual journal files
    ** still have 'null' as the master journal pointer, so they will roll
    ** back independently if a failure occurs.
    */
    for(i=0; i<db->nDb; i++){
      Btree *pBt = db->aDb[i].pBt;
      if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
      if( sqlite3BtreeIsInTrans(pBt) ){
        char const *zFile = sqlite3BtreeGetJournalname(pBt);
        if( zFile==0 ){
          continue;  /* Ignore TEMP and :memory: databases */
        }
        assert( zFile[0]!=0 );
        rc = sqlite3OsWrite(pSuperJrnl, zFile, sqlite3Strlen30(zFile)+1,offset);
        rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
        offset += sqlite3Strlen30(zFile)+1;
        if( rc!=SQLITE_OK ){
          sqlite3OsCloseFree(pSuperJrnl);
          sqlite3OsDelete(pVfs, zSuper, 0);
          sqlite3DbFree(db, zSuper-4);
          sqlite3OsCloseFree(pMaster);
          sqlite3OsDelete(pVfs, zMaster, 0);
          sqlite3DbFree(db, zMaster);
          return rc;
        }
      }
    }

    /* Sync the super-journal file. If the IOCAP_SEQUENTIAL device
    /* Sync the master journal file. If the IOCAP_SEQUENTIAL device
    ** flag is set this is not required.
    */
    if( 0==(sqlite3OsDeviceCharacteristics(pSuperJrnl)&SQLITE_IOCAP_SEQUENTIAL)
     && SQLITE_OK!=(rc = sqlite3OsSync(pSuperJrnl, SQLITE_SYNC_NORMAL))
    if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
     && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
    ){
      sqlite3OsCloseFree(pSuperJrnl);
      sqlite3OsDelete(pVfs, zSuper, 0);
      sqlite3DbFree(db, zSuper-4);
      sqlite3OsCloseFree(pMaster);
      sqlite3OsDelete(pVfs, zMaster, 0);
      sqlite3DbFree(db, zMaster);
      return rc;
    }

    /* Sync all the db files involved in the transaction. The same call
    ** sets the super-journal pointer in each individual journal. If
    ** an error occurs here, do not delete the super-journal file.
    ** sets the master journal pointer in each individual journal. If
    ** an error occurs here, do not delete the master journal file.
    **
    ** If the error occurs during the first call to
    ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the
    ** super-journal file will be orphaned. But we cannot delete it,
    ** in case the super-journal file name was written into the journal
    ** master journal file will be orphaned. But we cannot delete it,
    ** in case the master journal file name was written into the journal
    ** file before the failure occurred.
    */
    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        rc = sqlite3BtreeCommitPhaseOne(pBt, zSuper);
        rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
      }
    }
    sqlite3OsCloseFree(pSuperJrnl);
    sqlite3OsCloseFree(pMaster);
    assert( rc!=SQLITE_BUSY );
    if( rc!=SQLITE_OK ){
      sqlite3DbFree(db, zSuper-4);
      sqlite3DbFree(db, zMaster);
      return rc;
    }

    /* Delete the super-journal file. This commits the transaction. After
    /* Delete the master journal file. This commits the transaction. After
    ** doing this the directory is synced again before any individual
    ** transaction files are deleted.
    */
    rc = sqlite3OsDelete(pVfs, zSuper, 1);
    sqlite3DbFree(db, zSuper-4);
    zSuper = 0;
    rc = sqlite3OsDelete(pVfs, zMaster, 1);
    sqlite3DbFree(db, zMaster);
    zMaster = 0;
    if( rc ){
      return rc;
    }

    /* All files and directories have already been synced, so the following
    ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
    ** deleting or truncating journals. If something goes wrong while
3033
3034
3035
3036
3037
3038
3039
3040

3041
3042
3043
3044
3045
3046
3047
2840
2841
2842
2843
2844
2845
2846

2847
2848
2849
2850
2851
2852
2853
2854







-
+







  **     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 ){
  if( p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_OK;
  }
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM_BKPT;
  }
  closeAllCursors(p);
  checkActiveVdbeCnt(db);
3085
3086
3087
3088
3089
3090
3091
3092

3093
3094
3095
3096
3097
3098
3099
2892
2893
2894
2895
2896
2897
2898

2899
2900
2901
2902
2903
2904
2905
2906







-
+







          db->autoCommit = 1;
          p->nChange = 0;
        }
      }
    }

    /* Check for immediate foreign key violations. */
    if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
    if( p->rc==SQLITE_OK ){
      sqlite3VdbeCheckFk(p, 0);
    }
  
    /* If the auto-commit flag is set and this is the only active writer 
    ** VM, then we do either a commit or rollback of the current transaction. 
    **
    ** Note: This block also runs if one of the special errors handled 
3191
3192
3193
3194
3195
3196
3197
3198

3199
3200
3201
3202
3203
3204
3205
2998
2999
3000
3001
3002
3003
3004

3005
3006
3007
3008
3009
3010
3011
3012







-
+







    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;
  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() 
3296
3297
3298
3299
3300
3301
3302
3303
3304

3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329


3330
3331
3332
3333
3334
3335
3336
3337
3103
3104
3105
3106
3107
3108
3109


3110



3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129



3130
3131

3132
3133
3134
3135
3136
3137
3138







-
-
+
-
-
-



















-
-
-
+
+
-







  /* If the VDBE has been run even partially, then transfer the error code
  ** and error message from the VDBE into the main database structure.  But
  ** if the VDBE has just been set to run but has not actually executed any
  ** instructions yet, leave the main database error information unchanged.
  */
  if( p->pc>=0 ){
    vdbeInvokeSqllog(p);
    if( db->pErr || p->zErrMsg ){
      sqlite3VdbeTransferError(p);
    sqlite3VdbeTransferError(p);
    }else{
      db->errCode = p->rc;
    }
    if( p->runOnlyOnce ) p->expired = 1;
  }else if( p->rc && p->expired ){
    /* The expired flag was set on the VDBE before the first call
    ** to sqlite3_step(). For consistency (since sqlite3_step() was
    ** called), set the database error in this case as well.
    */
    sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
  }

  /* Reset register contents and reclaim error message memory.
  */
#ifdef SQLITE_DEBUG
  /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
  ** Vdbe.aMem[] arrays have already been cleaned up.  */
  if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
  if( p->aMem ){
    for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
  }
#endif
  if( p->zErrMsg ){
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = 0;
  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = 0;
  }
  p->pResultSet = 0;
#ifdef SQLITE_DEBUG
  p->nWrite = 0;
#endif

  /* Save profiling information from this VDBE run.
  */
3364
3365
3366
3367
3368
3369
3370
3371

3372
3373
3374
3375
3376
3377
3378
3379
3380
3381

3382
3383
3384
3385
3386
3387
3388
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







-
+









-
+







        fprintf(out, "%s", zHdr);
        sqlite3VdbePrintOp(out, i, &p->aOp[i]);
      }
      fclose(out);
    }
  }
#endif
  p->iVdbeMagic = VDBE_MAGIC_RESET;
  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->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){
  if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
    rc = sqlite3VdbeReset(p);
    assert( (rc & p->db->errMask)==rc );
  }
  sqlite3VdbeDelete(p);
  return rc;
}

3435
3436
3437
3438
3439
3440
3441
3442

3443
3444
3445
3446
3447
3448
3449
3236
3237
3238
3239
3240
3241
3242

3243
3244
3245
3246
3247
3248
3249
3250







-
+







  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 ){
  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);
3483
3484
3485
3486
3487
3488
3489
3490

3491
3492
3493
3494
3495
3496
3497
3498
3499
3500

3501
3502
3503
3504
3505
3506
3507
3284
3285
3286
3287
3288
3289
3290

3291
3292
3293
3294
3295
3296
3297
3298
3299
3300

3301
3302
3303
3304
3305
3306
3307
3308







-
+









-
+







  }else{
    assert( db->pVdbe==p );
    db->pVdbe = p->pNext;
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  p->iVdbeMagic = VDBE_MAGIC_DEAD;
  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
** the appropriate error code.
*/
int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){
static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){
  int res, rc;
#ifdef SQLITE_TEST
  extern int sqlite3_search_count;
#endif
  assert( p->deferredMoveto );
  assert( p->isTable );
  assert( p->eCurType==CURTYPE_BTREE );
3555
3556
3557
3558
3559
3560
3561
3562

3563
3564
3565
3566

3567
3568

3569
3570
3571
3572
3573

3574
3575
3576
3577
3578
3579
3580
3356
3357
3358
3359
3360
3361
3362

3363
3364
3365
3366

3367


3368
3369
3370
3371
3372

3373
3374
3375
3376
3377
3378
3379
3380







-
+



-
+
-
-
+




-
+







** MoveTo now.  If no move is pending, check to see if the row has been
** deleted out from under the cursor and if it has, mark the row as
** a NULL row.
**
** If the cursor is already pointing to the correct row and that row has
** not been deleted out from under the cursor, then this routine is a no-op.
*/
int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
  VdbeCursor *p = *pp;
  assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
  if( p->deferredMoveto ){
    u32 iMap;
    int iMap;
    assert( !p->isEphemeral );
    if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){
    if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
      *pp = p->pAltCursor;
      *piCol = iMap - 1;
      return SQLITE_OK;
    }
    return sqlite3VdbeFinishMoveto(p);
    return handleDeferredMoveto(p);
  }
  if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
    return handleMovedCursor(p);
  }
  return SQLITE_OK;
}

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
3416
3417
3418
3419
3420
3421
3422

3423
3424








3425
3426
3427
3428
3429
3430
3431
3432
3433
3434

3435
3436
3437
3438
3439


3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458









3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473

3474
3475
3476
3477
3478
3479
3480







-


-
-
-
-
-
-
-
-










-
+




-
-



















-
-
-
-
-
-
-
-
-















-







**    N>=12 and even       (N-12)/2        BLOB
**    N>=13 and odd        (N-13)/2        text
**
** The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
** of SQLite will not understand those serial types.
*/

#if 0 /* Inlined into the OP_MakeRecord opcode */
/*
** Return the serial-type for the value stored in pMem.
**
** This routine might convert a large MEM_IntReal value into MEM_Real.
**
** 2019-07-11:  The primary user of this subroutine was the OP_MakeRecord
** opcode in the byte-code engine.  But by moving this routine in-line, we
** can omit some redundant tests and make that opcode a lot faster.  So
** this routine is now only used by the STAT3 logic and STAT3 support has
** ended.  The code is kept here for historical reference only.
*/
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
  int flags = pMem->flags;
  u32 n;

  assert( pLen!=0 );
  if( flags&MEM_Null ){
    *pLen = 0;
    return 0;
  }
  if( flags&(MEM_Int|MEM_IntReal) ){
  if( flags&MEM_Int ){
    /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
#   define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
    i64 i = pMem->u.i;
    u64 u;
    testcase( flags & MEM_Int );
    testcase( flags & MEM_IntReal );
    if( i<0 ){
      u = ~i;
    }else{
      u = i;
    }
    if( u<=127 ){
      if( (i&1)==i && file_format>=4 ){
        *pLen = 0;
        return 8+(u32)u;
      }else{
        *pLen = 1;
        return 1;
      }
    }
    if( u<=32767 ){ *pLen = 2; return 2; }
    if( u<=8388607 ){ *pLen = 3; return 3; }
    if( u<=2147483647 ){ *pLen = 4; return 4; }
    if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
    *pLen = 8;
    if( flags&MEM_IntReal ){
      /* If the value is IntReal and is going to take up 8 bytes to store
      ** as an integer, then we might as well make it an 8-byte floating
      ** point value */
      pMem->u.r = (double)pMem->u.i;
      pMem->flags &= ~MEM_IntReal;
      pMem->flags |= MEM_Real;
      return 7;
    }
    return 6;
  }
  if( flags&MEM_Real ){
    *pLen = 8;
    return 7;
  }
  assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
  assert( pMem->n>=0 );
  n = (u32)pMem->n;
  if( flags & MEM_Zero ){
    n += pMem->u.nZero;
  }
  *pLen = n;
  return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}
#endif /* inlined into OP_MakeRecord */

/*
** The sizes for serial types less than 128
*/
static const u8 sqlite3SmallTypeSizes[] = {
        /*  0   1   2   3   4   5   6   7   8   9 */   
/*   0 */   0,  1,  2,  3,  4,  6,  8,  8,  0,  0,
3846
3847
3848
3849
3850
3851
3852
3853

3854
3855
3856
3857
3858
3859
3860
3625
3626
3627
3628
3629
3630
3631

3632
3633
3634
3635
3636
3637
3638
3639







-
+







** and store the result in pMem.  Return the number of bytes read.
**
** This function is implemented as two separate routines for performance.
** The few cases that require local variables are broken out into a separate
** routine so that in most cases the overhead of moving the stack pointer
** is avoided.
*/ 
static u32 serialGet(
static u32 SQLITE_NOINLINE serialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){
  u64 x = FOUR_BYTE_UINT(buf);
  u32 y = FOUR_BYTE_UINT(buf+4);
  x = (x<<32) + y;
3878
3879
3880
3881
3882
3883
3884
3885

3886
3887
3888
3889
3890
3891
3892
3657
3658
3659
3660
3661
3662
3663

3664
3665
3666
3667
3668
3669
3670
3671







-
+







    u64 t2 = t1;
    swapMixedEndianFloat(t2);
    assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
    assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
    swapMixedEndianFloat(x);
    memcpy(&pMem->u.r, &x, sizeof(x));
    pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
    pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
  }
  return 8;
}
u32 sqlite3VdbeSerialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
3996
3997
3998
3999
4000
4001
4002
4003

4004
4005
4006
4007
4008
4009
4010
3775
3776
3777
3778
3779
3780
3781

3782
3783
3784
3785
3786
3787
3788
3789







-
+







){
  UnpackedRecord *p;              /* Unpacked record to return */
  int nByte;                      /* Number of bytes required for *p */
  nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
  p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
  if( !p ) return 0;
  p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
  assert( pKeyInfo->aSortFlags!=0 );
  assert( pKeyInfo->aSortOrder!=0 );
  p->pKeyInfo = pKeyInfo;
  p->nField = pKeyInfo->nKeyField + 1;
  return p;
}

/*
** Given the nKey-byte encoding of a record in pKey[], populate the 
4095
4096
4097
4098
4099
4100
4101
4102

4103
4104
4105
4106
4107
4108
4109
3874
3875
3876
3877
3878
3879
3880

3881
3882
3883
3884
3885
3886
3887
3888







-
+







  */
  /*  mem1.u.i = 0;  // not needed, here to silence compiler warning */
  
  idx1 = getVarint32(aKey1, szHdr1);
  if( szHdr1>98307 ) return SQLITE_CORRUPT;
  d1 = szHdr1;
  assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB );
  assert( pKeyInfo->aSortFlags!=0 );
  assert( pKeyInfo->aSortOrder!=0 );
  assert( pKeyInfo->nKeyField>0 );
  assert( idx1<=szHdr1 || CORRUPT_DB );
  do{
    u32 serial_type1;

    /* Read the serial types for the next element in each key. */
    idx1 += getVarint32( aKey1+idx1, serial_type1 );
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138

4139
4140
4141
4142
4143
4144
4145
3905
3906
3907
3908
3909
3910
3911






3912
3913
3914
3915
3916
3917
3918
3919







-
-
-
-
-
-
+








    /* Do the comparison
    */
    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
                           pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0);
    if( rc!=0 ){
      assert( mem1.szMalloc==0 );  /* See comment below */
      if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL)
       && ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null)) 
      ){
        rc = -rc;
      }
      if( pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC ){
      if( pKeyInfo->aSortOrder[i] ){
        rc = -rc;  /* Invert the result for DESC sort order. */
      }
      goto debugCompareEnd;
    }
    i++;
  }while( idx1<szHdr1 && i<pPKey2->nField );

4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300


4301
4302
4303
4304
4305
4306
4307
4062
4063
4064
4065
4066
4067
4068



4069


4070
4071
4072
4073
4074
4075
4076
4077
4078







-
-
-

-
-
+
+







** Do a comparison between a 64-bit signed integer and a 64-bit floating-point
** number.  Return negative, zero, or positive if the first (i64) is less than,
** equal to, or greater than the second (double).
*/
static int sqlite3IntFloatCompare(i64 i, double r){
  if( sizeof(LONGDOUBLE_TYPE)>8 ){
    LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i;
    testcase( x<r );
    testcase( x>r );
    testcase( x==r );
    if( x<r ) return -1;
    if( x>r ) return +1;  /*NO_TEST*/ /* work around bugs in gcov */
    return 0;             /*NO_TEST*/ /* work around bugs in gcov */
    if( x>r ) return +1;
    return 0;
  }else{
    i64 y;
    double s;
    if( r<-9223372036854775808.0 ) return +1;
    if( r>=9223372036854775808.0 ) return -1;
    y = (i64)r;
    if( i<y ) return -1;
4336
4337
4338
4339
4340
4341
4342
4343

4344
4345
4346
4347

4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360

4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374

4375
4376
4377
4378
4379
4380
4381
4382
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







-
+
-
-
-
-
+
-
-









-
-
+
-


-
-
-
-





-
-
+
-







  */
  if( combined_flags&MEM_Null ){
    return (f2&MEM_Null) - (f1&MEM_Null);
  }

  /* At least one of the two values is a number
  */
  if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
  if( combined_flags&(MEM_Int|MEM_Real) ){
    testcase( combined_flags & MEM_Int );
    testcase( combined_flags & MEM_Real );
    testcase( combined_flags & MEM_IntReal );
    if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
    if( (f1 & f2 & MEM_Int)!=0 ){
      testcase( f1 & f2 & MEM_Int );
      testcase( f1 & f2 & MEM_IntReal );
      if( pMem1->u.i < pMem2->u.i ) return -1;
      if( pMem1->u.i > pMem2->u.i ) return +1;
      return 0;
    }
    if( (f1 & f2 & MEM_Real)!=0 ){
      if( pMem1->u.r < pMem2->u.r ) return -1;
      if( pMem1->u.r > pMem2->u.r ) return +1;
      return 0;
    }
    if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
      testcase( f1 & MEM_Int );
    if( (f1&MEM_Int)!=0 ){
      testcase( f1 & MEM_IntReal );
      if( (f2&MEM_Real)!=0 ){
        return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
      }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
        if( pMem1->u.i < pMem2->u.i ) return -1;
        if( pMem1->u.i > pMem2->u.i ) return +1;
        return 0;
      }else{
        return -1;
      }
    }
    if( (f1&MEM_Real)!=0 ){
      if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
        testcase( f2 & MEM_Int );
      if( (f2&MEM_Int)!=0 ){
        testcase( f2 & MEM_IntReal );
        return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
      }else{
        return -1;
      }
    }
    return +1;
  }
4510
4511
4512
4513
4514
4515
4516
4517

4518
4519
4520
4521
4522
4523
4524
4525

4526
4527
4528
4529
4530
4531
4532
4533
4268
4269
4270
4271
4272
4273
4274

4275
4276
4277
4278
4279
4280
4281


4282

4283
4284
4285
4286
4287
4288
4289







-
+






-
-
+
-







    pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
    return 0;  /* Corruption */
  }

  VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
  assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField 
       || CORRUPT_DB );
  assert( pPKey2->pKeyInfo->aSortFlags!=0 );
  assert( pPKey2->pKeyInfo->aSortOrder!=0 );
  assert( pPKey2->pKeyInfo->nKeyField>0 );
  assert( idx1<=szHdr1 || CORRUPT_DB );
  do{
    u32 serial_type;

    /* RHS is an integer */
    if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
      testcase( pRhs->flags & MEM_Int );
    if( pRhs->flags & MEM_Int ){
      testcase( pRhs->flags & MEM_IntReal );
      serial_type = aKey1[idx1];
      testcase( serial_type==12 );
      if( serial_type>=10 ){
        rc = +1;
      }else if( serial_type==0 ){
        rc = -1;
      }else if( serial_type==7 ){
4567
4568
4569
4570
4571
4572
4573
4574

4575
4576
4577
4578
4579
4580
4581
4323
4324
4325
4326
4327
4328
4329

4330
4331
4332
4333
4334
4335
4336
4337







-
+







          rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
        }
      }
    }

    /* RHS is a string */
    else if( pRhs->flags & MEM_Str ){
      getVarint32NR(&aKey1[idx1], serial_type);
      getVarint32(&aKey1[idx1], serial_type);
      testcase( serial_type==12 );
      if( serial_type<12 ){
        rc = -1;
      }else if( !(serial_type & 0x01) ){
        rc = +1;
      }else{
        mem1.n = (serial_type - 12) / 2;
4601
4602
4603
4604
4605
4606
4607
4608

4609
4610
4611
4612
4613
4614
4615
4357
4358
4359
4360
4361
4362
4363

4364
4365
4366
4367
4368
4369
4370
4371







-
+







        }
      }
    }

    /* RHS is a blob */
    else if( pRhs->flags & MEM_Blob ){
      assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 );
      getVarint32NR(&aKey1[idx1], serial_type);
      getVarint32(&aKey1[idx1], serial_type);
      testcase( serial_type==12 );
      if( serial_type<12 || (serial_type & 0x01) ){
        rc = -1;
      }else{
        int nStr = (serial_type - 12) / 2;
        testcase( (d1+nStr)==(unsigned)nKey1 );
        testcase( (d1+nStr+1)==(unsigned)nKey1 );
4633
4634
4635
4636
4637
4638
4639
4640

4641
4642
4643
4644
4645
4646

4647
4648
4649
4650
4651
4652
4653
4654
4389
4390
4391
4392
4393
4394
4395

4396






4397

4398
4399
4400
4401
4402
4403
4404







-
+
-
-
-
-
-
-
+
-







    /* RHS is null */
    else{
      serial_type = aKey1[idx1];
      rc = (serial_type!=0);
    }

    if( rc!=0 ){
      int sortFlags = pPKey2->pKeyInfo->aSortFlags[i];
      if( pPKey2->pKeyInfo->aSortOrder[i] ){
      if( sortFlags ){
        if( (sortFlags & KEYINFO_ORDER_BIGNULL)==0
         || ((sortFlags & KEYINFO_ORDER_DESC)
           !=(serial_type==0 || (pRhs->flags&MEM_Null)))
        ){
          rc = -rc;
        rc = -rc;
        }
      }
      assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
      assert( mem1.szMalloc==0 );  /* See comment below */
      return rc;
    }

    i++;
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
4540
4541
4542
4543
4544
4545
4546



4547

4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564

4565




4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589







-
-
-
+
-

















-
+
-
-
-
-













+
+
+
+







){
  const u8 *aKey1 = (const u8*)pKey1;
  int serial_type;
  int res;

  assert( pPKey2->aMem[0].flags & MEM_Str );
  vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
  serial_type = (u8)(aKey1[1]);
  if( serial_type >= 0x80 ){
    sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
  getVarint32(&aKey1[1], serial_type);
  }
  if( serial_type<12 ){
    res = pPKey2->r1;      /* (pKey1/nKey1) is a number or a null */
  }else if( !(serial_type & 0x01) ){ 
    res = pPKey2->r2;      /* (pKey1/nKey1) is a blob */
  }else{
    int nCmp;
    int nStr;
    int szHdr = aKey1[0];

    nStr = (serial_type-12) / 2;
    if( (szHdr + nStr) > nKey1 ){
      pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
      return 0;    /* Corruption */
    }
    nCmp = MIN( pPKey2->aMem[0].n, nStr );
    res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);

    if( res>0 ){
    if( res==0 ){
      res = pPKey2->r2;
    }else if( res<0 ){
      res = pPKey2->r1;
    }else{
      res = nStr - pPKey2->aMem[0].n;
      if( res==0 ){
        if( pPKey2->nField>1 ){
          res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
        }else{
          res = pPKey2->default_rc;
          pPKey2->eqSeen = 1;
        }
      }else if( res>0 ){
        res = pPKey2->r2;
      }else{
        res = pPKey2->r1;
      }
    }else if( res>0 ){
      res = pPKey2->r2;
    }else{
      res = pPKey2->r1;
    }
  }

  assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res)
       || CORRUPT_DB
       || pPKey2->pKeyInfo->db->mallocFailed
  );
4860
4861
4862
4863
4864
4865
4866
4867

4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884

4885
4886
4887
4888
4889
4890
4891
4892
4607
4608
4609
4610
4611
4612
4613

4614



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


4627

4628
4629
4630
4631
4632
4633
4634







-
+
-
-
-












-
-
+
-







  ** is an integer.
  **
  ** The easiest way to enforce this limit is to consider only records with
  ** 13 fields or less. If the first field is an integer, the maximum legal
  ** header size is (12*5 + 1 + 1) bytes.  */
  if( p->pKeyInfo->nAllField<=13 ){
    int flags = p->aMem[0].flags;
    if( p->pKeyInfo->aSortFlags[0] ){
    if( p->pKeyInfo->aSortOrder[0] ){
      if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){
        return sqlite3VdbeRecordCompare;
      }
      p->r1 = 1;
      p->r2 = -1;
    }else{
      p->r1 = -1;
      p->r2 = 1;
    }
    if( (flags & MEM_Int) ){
      return vdbeRecordCompareInt;
    }
    testcase( flags & MEM_Real );
    testcase( flags & MEM_Null );
    testcase( flags & MEM_Blob );
    if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
     && p->pKeyInfo->aColl[0]==0
    if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
    ){
      assert( flags & MEM_Str );
      return vdbeRecordCompareString;
    }
  }

  return sqlite3VdbeRecordCompare;
}
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
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







-
+





-
+










-
+







  */
  assert( sqlite3BtreeCursorIsValid(pCur) );
  nCellKey = sqlite3BtreePayloadSize(pCur);
  assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );

  /* Read in the complete content of the index entry */
  sqlite3VdbeMemInit(&m, db, 0);
  rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
  if( rc ){
    return rc;
  }

  /* The index entry must begin with a header size */
  getVarint32NR((u8*)m.z, szHdr);
  (void)getVarint32((u8*)m.z, szHdr);
  testcase( szHdr==3 );
  testcase( szHdr==m.n );
  testcase( szHdr>0x7fffffff );
  assert( m.n>=0 );
  if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
    goto idx_rowid_corruption;
  }

  /* The last field of the index should be an integer - the ROWID.
  ** Verify that the last entry really is an integer. */
  getVarint32NR((u8*)&m.z[szHdr-1], typeRowid);
  (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid);
  testcase( typeRowid==1 );
  testcase( typeRowid==2 );
  testcase( typeRowid==3 );
  testcase( typeRowid==4 );
  testcase( typeRowid==5 );
  testcase( typeRowid==6 );
  testcase( typeRowid==8 );
4996
4997
4998
4999
5000
5001
5002
5003

5004
5005
5006
5007
5008
5009
5010
4738
4739
4740
4741
4742
4743
4744

4745
4746
4747
4748
4749
4750
4751
4752







-
+







  /* nCellKey will always be between 0 and 0xffffffff because of the way
  ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
  if( nCellKey<=0 || nCellKey>0x7fffffff ){
    *res = 0;
    return SQLITE_CORRUPT_BKPT;
  }
  sqlite3VdbeMemInit(&m, db, 0);
  rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
  if( rc ){
    return rc;
  }
  *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
  sqlite3VdbeMemRelease(&m);
  return SQLITE_OK;
}
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
4854
4855
4856
4857
4858
4859
4860


4861
4862
4863


4864













4865
4866
4867
4868
4869
4870
4871
4872
4873
4874







-
-
+


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







**
** OP_PureFunc means that the function must be deterministic, and should
** throw an error if it is given inputs that would make it non-deterministic.
** This routine is invoked by date/time functions that use non-deterministic
** features such as 'now'.
*/
int sqlite3NotPureFunc(sqlite3_context *pCtx){
  const VdbeOp *pOp;
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pCtx->pVdbe==0 ) return 1;
#endif
  pOp = pCtx->pVdbe->aOp + pCtx->iOp;
  if( pOp->opcode==OP_PureFunc ){
  if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){
    const char *zContext;
    char *zMsg;
    if( pOp->p5 & NC_IsCheck ){
      zContext = "a CHECK constraint";
    }else if( pOp->p5 & NC_GenCol ){
      zContext = "a generated column";
    }else{
      zContext = "an index";
    }
    zMsg = sqlite3_mprintf("non-deterministic use of %s() in %s",
                           pCtx->pFunc->zName, zContext);
    sqlite3_result_error(pCtx, zMsg, -1);
    sqlite3_free(zMsg);
    sqlite3_result_error(pCtx, 
       "non-deterministic function in index expression or CHECK constraint",
       -1);
    return 0;
  }
  return 1;
}

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
5221
5222
5223
5224
5225
5226
5227
5228

5229
5230
5231
5232
5233
5234
5235
4951
4952
4953
4954
4955
4956
4957

4958
4959
4960
4961
4962
4963
4964
4965







-
+







  preupdate.v = v;
  preupdate.pCsr = pCsr;
  preupdate.op = op;
  preupdate.iNewReg = iReg;
  preupdate.keyinfo.db = db;
  preupdate.keyinfo.enc = ENC(db);
  preupdate.keyinfo.nKeyField = pTab->nCol;
  preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder;
  preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
  preupdate.iKey1 = iKey1;
  preupdate.iKey2 = iKey2;
  preupdate.pTab = pTab;

  db->pPreUpdate = &preupdate;
  db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
  db->pPreUpdate = 0;

Changes to src/vdbeblob.c.

351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
351
352
353
354
355
356
357

358
359
360
361
362

363
364
365
366
367
368
369







-


+


-







*/
int sqlite3_blob_close(sqlite3_blob *pBlob){
  Incrblob *p = (Incrblob *)pBlob;
  int rc;
  sqlite3 *db;

  if( p ){
    sqlite3_stmt *pStmt = p->pStmt;
    db = p->db;
    sqlite3_mutex_enter(db->mutex);
    rc = sqlite3_finalize(p->pStmt);
    sqlite3DbFree(db, p);
    sqlite3_mutex_leave(db->mutex);
    rc = sqlite3_finalize(pStmt);
  }else{
    rc = SQLITE_OK;
  }
  return rc;
}

/*

Changes to src/vdbemem.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
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







-
-
-
-
-



















-
-
+
+







** stores a single value in the VDBE.  Mem is an opaque structure visible
** only within the VDBE.  Interface routines refer to a Mem using the
** name sqlite_value
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/* True if X is a power of two.  0 is considered a power of two here.
** In other words, return true if X has at most one bit set.
*/
#define ISPOWEROF2(X)  (((X)&((X)-1))==0)

#ifdef SQLITE_DEBUG
/*
** Check invariants on a Mem object.
**
** This routine is intended for use inside of assert() statements, like
** this:    assert( sqlite3VdbeCheckMemInvariants(pMem) );
*/
int sqlite3VdbeCheckMemInvariants(Mem *p){
  /* If MEM_Dyn is set then Mem.xDel!=0.  
  ** Mem.xDel might not be initialized if MEM_Dyn is clear.
  */
  assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );

  /* MEM_Dyn may only be set if Mem.szMalloc==0.  In this way we
  ** ensure that if Mem.szMalloc>0 then it is safe to do
  ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
  ** That saves a few cycles in inner loops. */
  assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );

  /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
  assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
  /* Cannot be both MEM_Int and MEM_Real at the same time */
  assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );

  if( p->flags & MEM_Null ){
    /* Cannot be both MEM_Null and some other type */
    assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );

    /* If MEM_Null is set, then either the value is a pure NULL (the usual
    ** case) or it is a pointer set using sqlite3_bind_pointer() or
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
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







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


-
-
-
+
-

















-
+




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

-
-







      ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1
    );
  }
  return 1;
}
#endif

/*
** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal
** into a buffer.
*/
static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
  StrAccum acc;
  assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) );
  assert( sz>22 );
  if( p->flags & MEM_Int ){
#if GCC_VERSION>=7000000
    /* Work-around for GCC bug
    ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96270 */
    i64 x;
    assert( (p->flags&MEM_Int)*2==sizeof(x) );
    memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2);
    sqlite3Int64ToText(x, zBuf);
#else
    sqlite3Int64ToText(p->u.i, zBuf);
#endif
  }else{
    sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
    sqlite3_str_appendf(&acc, "%!.15g", 
         (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r);
    assert( acc.zText==zBuf && acc.mxAlloc<=0 );
    zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
  }
}

#ifdef SQLITE_DEBUG
/*
** Validity checks on pMem.  pMem holds a string.
**
** (1) Check that string value of pMem agrees with its integer or real value.
** Check that string value of pMem agrees with its integer or real value.
** (2) Check that the string is correctly zero terminated
**
** A single int or real value always converts to the same strings.  But
** many different strings can be converted into the same int or real.
** If a table contains a numeric value and an index is based on the
** corresponding string value, then it is important that the string be
** derived from the numeric value, not the other way around, to ensure
** that the index and table are consistent.  See ticket
** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for
** an example.
**
** This routine looks at pMem to verify that if it has both a numeric
** representation and a string representation then the string rep has
** been derived from the numeric and not the other way around.  It returns
** true if everything is ok and false if there is a problem.
**
** This routine is for use inside of assert() statements only.
*/
int sqlite3VdbeMemValidStrRep(Mem *p){
int sqlite3VdbeMemConsistentDualRep(Mem *p){
  char zBuf[100];
  char *z;
  int i, j, incr;
  if( (p->flags & MEM_Str)==0 ) return 1;
  if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
  if( p->flags & MEM_Term ){
  if( p->flags & MEM_Int ){
    /* Insure that the string is properly zero-terminated.  Pay particular
    ** attention to the case where p->n is odd */
    sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
    if( p->szMalloc>0 && p->z==p->zMalloc ){
      assert( p->enc==SQLITE_UTF8 || p->szMalloc >= ((p->n+1)&~1)+2 );
      assert( p->enc!=SQLITE_UTF8 || p->szMalloc >= p->n+1 );
    }
  }else{
    assert( p->z[p->n]==0 );
    assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 );
    assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 );
    sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
  }
  if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
  vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
  z = p->z;
  i = j = 0;
  incr = 1;
  if( p->enc!=SQLITE_UTF8 ){
    incr = 2;
    if( p->enc==SQLITE_UTF16BE ) z++;
  }
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253
254
255
256
257
194
195
196
197
198
199
200


201





202
203
204
205
206
207
208







-
-
+
-
-
-
-
-







  ** contain a valid string or blob value.  */
  assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
  testcase( bPreserve && pMem->z==0 );

  assert( pMem->szMalloc==0
       || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
  if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
    if( pMem->db ){
      pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
    pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
    }else{
      pMem->zMalloc = sqlite3Realloc(pMem->z, n);
      if( pMem->zMalloc==0 ) sqlite3_free(pMem->z);
      pMem->z = pMem->zMalloc;
    }
    bPreserve = 0;
  }else{
    if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
    pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
  }
  if( pMem->zMalloc==0 ){
    sqlite3VdbeMemSetNull(pMem);
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
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







-
-
+
+












-
+






-
-
-
-
-


-
+




-







/*
** Change the pMem->zMalloc allocation to be at least szNew bytes.
** If pMem->zMalloc already meets or exceeds the requested size, this
** routine is a no-op.
**
** Any prior string or blob content in the pMem object may be discarded.
** The pMem->xDel destructor is called, if it exists.  Though MEM_Str
** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal,
** and MEM_Null values are preserved.
** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
** values are preserved.
**
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
** if unable to complete the resizing.
*/
int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
  assert( CORRUPT_DB || szNew>0 );
  assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
  if( pMem->szMalloc<szNew ){
    return sqlite3VdbeMemGrow(pMem, szNew, 0);
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  pMem->z = pMem->zMalloc;
  pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
  pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
  return SQLITE_OK;
}

/*
** It is already known that pMem contains an unterminated string.
** Add the zero terminator.
**
** Three bytes of zero are added.  In this way, there is guaranteed
** to be a double-zero byte at an even byte boundary in order to
** terminate a UTF16 string, even if the initial size of the buffer
** is an odd number of bytes.
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
  if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
  if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
    return SQLITE_NOMEM_BKPT;
  }
  pMem->z[pMem->n] = 0;
  pMem->z[pMem->n+1] = 0;
  pMem->z[pMem->n+2] = 0;
  pMem->flags |= MEM_Term;
  return SQLITE_OK;
}

/*
** Change pMem so that its MEM_Str or MEM_Blob value is stored in
** MEM.zMalloc, where it can be safely written.
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
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







-
-
-
+
+
+

-
-
+
+








+



-
-
-
+
+
+









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




-
+







    return SQLITE_OK;   /* Nothing to do */
  }else{
    return vdbeMemAddTerminator(pMem);
  }
}

/*
** Add MEM_Str to the set of representations for the given Mem.  This
** routine is only called if pMem is a number of some kind, not a NULL
** or a BLOB.
** Add MEM_Str to the set of representations for the given Mem.  Numbers
** are converted using sqlite3_snprintf().  Converting a BLOB to a string
** is a no-op.
**
** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated
** if bForce is true but are retained if bForce is false.
** Existing representations MEM_Int and MEM_Real are invalidated if
** bForce is true but are retained if bForce is false.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
** sqlite3_value_text()), or for ensuring that values to be used as btree
** keys are strings. In the former case a NULL pointer is returned the
** user and the latter is an internal programming error.
*/
int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
  int fg = pMem->flags;
  const int nByte = 32;

  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
  assert( !(pMem->flags&MEM_Zero) );
  assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
  assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
  assert( !(fg&MEM_Zero) );
  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );
  assert( !sqlite3VdbeMemIsRowSet(pMem) );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );


  if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
    pMem->enc = 0;
    return SQLITE_NOMEM_BKPT;
  }

  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
  ** string representation of the value. Then, if the required encoding
  ** is UTF-16le or UTF-16be do a translation.
  ** 
  ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
  */
  if( fg & MEM_Int ){
  vdbeMemRenderNum(nByte, pMem->z, pMem);
    sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
  }else{
    assert( fg & MEM_Real );
    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
  }
  assert( pMem->z!=0 );
  pMem->n = sqlite3Strlen30NN(pMem->z);
  pMem->enc = SQLITE_UTF8;
  pMem->flags |= MEM_Str|MEM_Term;
  if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
  if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
  sqlite3VdbeChangeEncoding(pMem, enc);
  return SQLITE_OK;
}

/*
** Memory cell pMem contains the context of an aggregate function.
** This routine calls the finalize method for that function.  The
465
466
467
468
469
470
471

472
473
474
475
476



477
478
479
480
481
482
483
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444







+





+
+
+







**
** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK 
** otherwise.
*/
#ifndef SQLITE_OMIT_WINDOWFUNC
int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
  sqlite3_context ctx;
  Mem t;
  assert( pFunc!=0 );
  assert( pFunc->xValue!=0 );
  assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
  assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
  memset(&ctx, 0, sizeof(ctx));
  memset(&t, 0, sizeof(t));
  t.flags = MEM_Null;
  t.db = pAccum->db;
  sqlite3VdbeMemSetNull(pOut);
  ctx.pOut = pOut;
  ctx.pMem = pAccum;
  ctx.pFunc = pFunc;
  pFunc->xValue(&ctx);
  return ctx.isError;
}
590
591
592
593
594
595
596
597
598

599
600
601
602


603
604
605
606
607
608
609
551
552
553
554
555
556
557


558
559
560
561

562
563
564
565
566
567
568
569
570







-
-
+



-
+
+







  return value;
}
i64 sqlite3VdbeIntValue(Mem *pMem){
  int flags;
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );
  flags = pMem->flags;
  if( flags & (MEM_Int|MEM_IntReal) ){
    testcase( flags & MEM_IntReal );
  if( flags & MEM_Int ){
    return pMem->u.i;
  }else if( flags & MEM_Real ){
    return doubleToInt64(pMem->u.r);
  }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){
  }else if( flags & (MEM_Str|MEM_Blob) ){
    assert( pMem->z || pMem->n==0 );
    return memIntValue(pMem);
  }else{
    return 0;
  }
}

/*
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
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







-
+
-














-
+
-







  return val;
}
double sqlite3VdbeRealValue(Mem *pMem){
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );
  if( pMem->flags & MEM_Real ){
    return pMem->u.r;
  }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
  }else if( pMem->flags & MEM_Int ){
    testcase( pMem->flags & MEM_IntReal );
    return (double)pMem->u.i;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
    return memRealValue(pMem);
  }else{
    /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
    return (double)0;
  }
}

/*
** Return 1 if pMem represents true, and return 0 if pMem represents false.
** Return the value ifNull if pMem is NULL.  
*/
int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
  testcase( pMem->flags & MEM_IntReal );
  if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
  if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
  if( pMem->flags & MEM_Null ) return ifNull;
  return sqlite3VdbeRealValue(pMem)!=0.0;
}

/*
** The MEM structure is already a MEM_Real.  Try to also make it a
** MEM_Int if we can.
699
700
701
702
703
704
705
706
707
708
709
710
711
712

713
714
715

716
717
718
719
720

721
722
723
724
725
726
727
728
729
730
731
732

733
734
735
736





737

738
739

740
741
742
743
744
745
746
747








748
749
750
751
752
753
754
755
756
757
758
759
760


761
762
763
764
765
766
767
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







-
-




-
+

-
-
+
-



-
+







-
-
-
-
-
+

-


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











-
-
+
+







  MemSetTypeFlag(pMem, MEM_Real);
  return SQLITE_OK;
}

/* Compare a floating point value to an integer.  Return true if the two
** values are the same within the precision of the floating point value.
**
** This function assumes that i was obtained by assignment from r1.
**
** For some versions of GCC on 32-bit machines, if you do the more obvious
** comparison of "r1==(double)i" you sometimes get an answer of false even
** though the r1 and (double)i values are bit-for-bit the same.
*/
int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
  double r2 = (double)i;
  return r1==0.0
      || (memcmp(&r1, &r2, sizeof(r1))==0
  return memcmp(&r1, &r2, sizeof(r1))==0;
          && i >= -2251799813685248LL && i < 2251799813685248LL);
}

/*
** Convert pMem so that it has type MEM_Real or MEM_Int.
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
**
** Every effort is made to force the conversion, even if the input
** is a string that does not look completely like a number.  Convert
** as much of the string as we can and ignore the rest.
*/
int sqlite3VdbeMemNumerify(Mem *pMem){
  testcase( pMem->flags & MEM_Int );
  testcase( pMem->flags & MEM_Real );
  testcase( pMem->flags & MEM_IntReal );
  testcase( pMem->flags & MEM_Null );
  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
    int rc;
    sqlite3_int64 ix;
    assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
    rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
    if( rc==0 ){
      MemSetTypeFlag(pMem, MEM_Int);
    }else{
      i64 i = pMem->u.i;
    rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
      sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
    if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1)
     || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r))
      if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
    ){
      pMem->u.i = ix;
      MemSetTypeFlag(pMem, MEM_Int);
    }else{
      MemSetTypeFlag(pMem, MEM_Real);
    }
  }
  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
        pMem->u.i = i;
        MemSetTypeFlag(pMem, MEM_Int);
      }else{
        MemSetTypeFlag(pMem, MEM_Real);
      }
    }
  }
  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
  pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
  return SQLITE_OK;
}

/*
** Cast the datatype of the value in pMem according to the affinity
** "aff".  Casting is different from applying affinity in that a cast
** is forced.  In other words, the value is converted into the desired
** affinity even if that results in loss of data.  This routine is
** used (for example) to implement the SQL "cast()" operator.
*/
int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
  if( pMem->flags & MEM_Null ) return SQLITE_OK;
void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
  if( pMem->flags & MEM_Null ) return;
  switch( aff ){
    case SQLITE_AFF_BLOB: {   /* Really a cast to BLOB */
      if( (pMem->flags & MEM_Blob)==0 ){
        sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
        assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
        if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob);
      }else{
783
784
785
786
787
788
789
790
791


792
793
794
795
796
797
798
799
800
801
737
738
739
740
741
742
743


744
745
746
747

748
749
750
751
752
753
754







-
-
+
+


-







    }
    default: {
      assert( aff==SQLITE_AFF_TEXT );
      assert( MEM_Str==(MEM_Blob>>3) );
      pMem->flags |= (pMem->flags&MEM_Blob)>>3;
      sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
      assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
      pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
      return sqlite3VdbeChangeEncoding(pMem, encoding);
      pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
      break;
    }
  }
  return SQLITE_OK;
}

/*
** Initialize bulk memory to be a consistent Mem object.
**
** The minimum amount of initialization feasible is performed.
*/
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
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







-
-
+
+




-
+

-
-
-
-
-
-
+





-
-
+
+
+
+
+










+








#ifdef SQLITE_DEBUG
/*
** This routine prepares a memory cell for modification by breaking
** its link to a shallow copy and by marking any current shallow
** copies of this cell as invalid.
**
** This is used for testing and debugging only - to help ensure that shallow
** copies (created by OP_SCopy) are not misused.
** This is used for testing and debugging only - to make sure shallow
** copies are not misused.
*/
void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
  int i;
  Mem *pX;
  for(i=1, pX=pVdbe->aMem+1; i<pVdbe->nMem; i++, pX++){
  for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){
    if( pX->pScopyFrom==pMem ){
      u16 mFlags;
      if( pVdbe->db->flags & SQLITE_VdbeTrace ){
        sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n",
          (int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem));
      }
      /* If pX is marked as a shallow copy of pMem, then try to verify that
      /* If pX is marked as a shallow copy of pMem, then verify that
      ** no significant changes have been made to pX since the OP_SCopy.
      ** A significant change would indicated a missed call to this
      ** function for pX.  Minor changes, such as adding or removing a
      ** dual type, are allowed, as long as the underlying value is the
      ** same. */
      mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
      assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
      u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
      assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
      assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
      assert( (mFlags&MEM_Str)==0  || (pMem->n==pX->n && pMem->z==pX->z) );
      assert( (mFlags&MEM_Blob)==0  || sqlite3BlobCompare(pMem,pX)==0 );
      
      /* pMem is the register that is changing.  But also mark pX as
      ** undefined so that we can quickly detect the shallow-copy error */
      pX->flags = MEM_Undefined;
      pX->pScopyFrom = 0;
    }
  }
  pMem->pScopyFrom = 0;
}
#endif /* SQLITE_DEBUG */


/*
** Make an shallow copy of pFrom into pTo.  Prior contents of
** pTo are freed.  The pFrom->z field is not duplicated.  If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
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
1082
1083
1084
1085
1086
1087
1088


1089








1090

1091

1092
1093
1094
1095
1096
1097
1098
1099







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

-
+







      pMem->xDel = xDel;
      flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
    }
  }

  pMem->n = nByte;
  pMem->flags = flags;
  if( enc ){
    pMem->enc = enc;
  pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
#ifdef SQLITE_ENABLE_SESSION
  }else if( pMem->db==0 ){
    pMem->enc = SQLITE_UTF8;
#endif
  }else{
    assert( pMem->db!=0 );
    pMem->enc = ENC(pMem->db);
  }


#ifndef SQLITE_OMIT_UTF16
  if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
  if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
    return SQLITE_NOMEM_BKPT;
  }
#endif

  if( nByte>iLimit ){
    return SQLITE_TOOBIG;
  }
1169
1170
1171
1172
1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126







-
+







** pMem->zMalloc space will be allocated if necessary.  The calling routine
** is responsible for making sure that the pMem object is eventually
** destroyed.
**
** If this routine fails for any reason (malloc returns NULL or unable
** to read from the disk) then the pMem is left in an inconsistent state.
*/
int sqlite3VdbeMemFromBtree(
static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
  BtCursor *pCur,   /* Cursor pointing at record to retrieve. */
  u32 offset,       /* Offset from the start of data to return bytes from. */
  u32 amt,          /* Number of bytes to return. */
  Mem *pMem         /* OUT: Return data in this Mem structure. */
){
  int rc;
  pMem->flags = MEM_Null;
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
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







-
+

+



+









-
-
+
+

-
+
+



-
+







      pMem->n = (int)amt;
    }else{
      sqlite3VdbeMemRelease(pMem);
    }
  }
  return rc;
}
int sqlite3VdbeMemFromBtreeZeroOffset(
int sqlite3VdbeMemFromBtree(
  BtCursor *pCur,   /* Cursor pointing at record to retrieve. */
  u32 offset,       /* Offset from the start of data to return bytes from. */
  u32 amt,          /* Number of bytes to return. */
  Mem *pMem         /* OUT: Return data in this Mem structure. */
){
  char *zData;        /* Data from the btree layer */
  u32 available = 0;  /* Number of bytes available on the local btree page */
  int rc = SQLITE_OK; /* Return code */

  assert( sqlite3BtreeCursorIsValid(pCur) );
  assert( !VdbeMemDynamic(pMem) );

  /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() 
  ** that both the BtShared and database handle mutexes are held. */
  assert( !sqlite3VdbeMemIsRowSet(pMem) );
  pMem->z = (char *)sqlite3BtreePayloadFetch(pCur, &available);
  assert( pMem->z!=0 );
  zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
  assert( zData!=0 );

  if( amt<=available ){
  if( offset+amt<=available ){
    pMem->z = &zData[offset];
    pMem->flags = MEM_Blob|MEM_Ephem;
    pMem->n = (int)amt;
  }else{
    rc = sqlite3VdbeMemFromBtree(pCur, 0, amt, pMem);
    rc = vdbeMemFromBtreeResize(pCur, offset, amt, pMem);
  }

  return rc;
}

/*
** The pVal argument is known to be a value other than NULL.
1250
1251
1252
1253
1254
1255
1256
1257

1258
1259
1260
1261
1262
1263
1264
1196
1197
1198
1199
1200
1201
1202

1203
1204
1205
1206
1207
1208
1209
1210







-
+







  }else{
    sqlite3VdbeMemStringify(pVal, enc, 0);
    assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
  }
  assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
              || pVal->db->mallocFailed );
  if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
    assert( sqlite3VdbeMemValidStrRep(pVal) );
    assert( sqlite3VdbeMemConsistentDualRep(pVal) );
    return pVal->z;
  }else{
    return 0;
  }
}

/* This function is only available internally, it is not part of the
1273
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284
1285
1286
1287
1219
1220
1221
1222
1223
1224
1225

1226
1227
1228
1229
1230
1231
1232
1233







-
+







*/
const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
  if( !pVal ) return 0;
  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
  assert( !sqlite3VdbeMemIsRowSet(pVal) );
  if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
    assert( sqlite3VdbeMemValidStrRep(pVal) );
    assert( sqlite3VdbeMemConsistentDualRep(pVal) );
    return pVal->z;
  }
  if( pVal->flags&MEM_Null ){
    return 0;
  }
  return valueToText(pVal, enc);
}
1317
1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1277







-
+







** Otherwise, if the second argument is non-zero, then this function is 
** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
** already been allocated, allocate the UnpackedRecord structure that 
** that function will return to its caller here. Then return a pointer to
** an sqlite3_value within the UnpackedRecord.a[] array.
*/
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( p ){
    UnpackedRecord *pRec = p->ppRec[0];

    if( pRec==0 ){
      Index *pIdx = p->pIdx;      /* Index being probed */
      int nByte;                  /* Bytes of space to allocate */
      int i;                      /* Counter variable */
1353
1354
1355
1356
1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367
1299
1300
1301
1302
1303
1304
1305

1306
1307
1308
1309
1310
1311
1312
1313







-
+







    }
  
    pRec->nField = p->iVal+1;
    return &pRec->aMem[p->iVal];
  }
#else
  UNUSED_PARAMETER(p);
#endif /* defined(SQLITE_ENABLE_STAT4) */
#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
  return sqlite3ValueNew(db);
}

/*
** The expression object indicated by the second argument is guaranteed
** to be a scalar SQL function. If
**
1377
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1323
1324
1325
1326
1327
1328
1329

1330
1331
1332
1333
1334
1335
1336
1337







-
+







** If the result is a text value, the sqlite3_value object uses encoding 
** enc.
**
** If the conditions above are not met, this function returns SQLITE_OK
** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
** NULL and an SQLite error code returned.
*/
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static int valueFromFunction(
  sqlite3 *db,                    /* The database connection */
  Expr *p,                        /* The expression to evaluate */
  u8 enc,                         /* Encoding to use */
  u8 aff,                         /* Affinity to use */
  sqlite3_value **ppVal,          /* Write the new value here */
  struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
1460
1461
1462
1463
1464
1465
1466
1467

1468
1469
1470
1471
1472
1473
1474
1406
1407
1408
1409
1410
1411
1412

1413
1414
1415
1416
1417
1418
1419
1420







-
+







  }

  *ppVal = pVal;
  return rc;
}
#else
# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
#endif /* defined(SQLITE_ENABLE_STAT4) */
#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */

/*
** Extract a value from the supplied expression in the manner described
** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
** using valueNew().
**
** If pCtx is NULL and an error occurs after the sqlite3_value object
1489
1490
1491
1492
1493
1494
1495
1496

1497
1498
1499
1500
1501
1502
1503
1435
1436
1437
1438
1439
1440
1441

1442
1443
1444
1445
1446
1447
1448
1449







-
+







  sqlite3_value *pVal = 0;
  int negInt = 1;
  const char *zNeg = "";
  int rc = SQLITE_OK;

  assert( pExpr!=0 );
  while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
#if defined(SQLITE_ENABLE_STAT4)
#if defined(SQLITE_ENABLE_STAT3_OR_STAT4)
  if( op==TK_REGISTER ) op = pExpr->op2;
#else
  if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
#endif

  /* Compressed expressions only appear when parsing the DEFAULT clause
  ** on a table column definition, and hence only when pCtx==0.  This
1538
1539
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577

1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593

1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610

1611
1612
1613
1614
1615
1616

1617
1618
1619
1620
1621
1622
1623
1484
1485
1486
1487
1488
1489
1490


1491




1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503

1504



1505
1506
1507
1508
1509
1510
1511
1512
1513

1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529

1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552

1553
1554
1555
1556
1557
1558
1559
1560







-
-
+
-
-
-
-












-

-
-
-









-
+















-
+
















-
+





-
+







      sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
    }
    if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
      sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
    }else{
      sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
    }
    assert( (pVal->flags & MEM_IntReal)==0 );
    if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
    if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
      testcase( pVal->flags & MEM_Int );
      testcase( pVal->flags & MEM_Real );
      pVal->flags &= ~MEM_Str;
    }
    if( enc!=SQLITE_UTF8 ){
      rc = sqlite3VdbeChangeEncoding(pVal, enc);
    }
  }else if( op==TK_UMINUS ) {
    /* This branch happens for multiple negative signs.  Ex: -(-5) */
    if( SQLITE_OK==valueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal,pCtx) 
     && pVal!=0
    ){
      sqlite3VdbeMemNumerify(pVal);
      if( pVal->flags & MEM_Real ){
        pVal->u.r = -pVal->u.r;
      }else if( pVal->u.i==SMALLEST_INT64 ){
#ifndef SQLITE_OMIT_FLOATING_POINT
        pVal->u.r = -(double)SMALLEST_INT64;
#else
        pVal->u.r = LARGEST_INT64;
#endif
        MemSetTypeFlag(pVal, MEM_Real);
      }else{
        pVal->u.i = -pVal->u.i;
      }
      sqlite3ValueApplyAffinity(pVal, affinity, enc);
    }
  }else if( op==TK_NULL ){
    pVal = valueNew(db, pCtx);
    if( pVal==0 ) goto no_mem;
    sqlite3VdbeMemSetNull(pVal);
    sqlite3VdbeMemNumerify(pVal);
  }
#ifndef SQLITE_OMIT_BLOB_LITERAL
  else if( op==TK_BLOB ){
    int nVal;
    assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
    assert( pExpr->u.zToken[1]=='\'' );
    pVal = valueNew(db, pCtx);
    if( !pVal ) goto no_mem;
    zVal = &pExpr->u.zToken[2];
    nVal = sqlite3Strlen30(zVal)-1;
    assert( zVal[nVal]=='\'' );
    sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
                         0, SQLITE_DYNAMIC);
  }
#endif
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  else if( op==TK_FUNCTION && pCtx!=0 ){
    rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
  }
#endif
  else if( op==TK_TRUEFALSE ){
    pVal = valueNew(db, pCtx);
    if( pVal ){
      pVal->flags = MEM_Int;
      pVal->u.i = pExpr->u.zToken[4]==0;
    }
  }

  *ppVal = pVal;
  return rc;

no_mem:
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pCtx==0 || pCtx->pParse->nErr==0 )
#endif
    sqlite3OomFault(db);
  sqlite3DbFree(db, zVal);
  assert( *ppVal==0 );
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pCtx==0 ) sqlite3ValueFree(pVal);
#else
  assert( pCtx==0 ); sqlite3ValueFree(pVal);
#endif
  return SQLITE_NOMEM_BKPT;
}

1637
1638
1639
1640
1641
1642
1643
1644


















































1645
1646
1647
1648
1649
1650
1651
1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637







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







  u8 enc,                   /* Encoding to use */
  u8 affinity,              /* Affinity to use */
  sqlite3_value **ppVal     /* Write the new value here */
){
  return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
}

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** The implementation of the sqlite_record() function. This function accepts
** a single argument of any type. The return value is a formatted database 
** record (a blob) containing the argument value.
**
** This is used to convert the value stored in the 'sample' column of the
** sqlite_stat3 table to the record format SQLite uses internally.
*/
static void recordFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const int file_format = 1;
  u32 iSerial;                    /* Serial type */
  int nSerial;                    /* Bytes of space for iSerial as varint */
  u32 nVal;                       /* Bytes of space required for argv[0] */
  int nRet;
  sqlite3 *db;
  u8 *aRet;

  UNUSED_PARAMETER( argc );
  iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal);
  nSerial = sqlite3VarintLen(iSerial);
  db = sqlite3_context_db_handle(context);

  nRet = 1 + nSerial + nVal;
  aRet = sqlite3DbMallocRawNN(db, nRet);
  if( aRet==0 ){
    sqlite3_result_error_nomem(context);
  }else{
    aRet[0] = nSerial+1;
    putVarint32(&aRet[1], iSerial);
    sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
    sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
    sqlite3DbFreeNN(db, aRet);
  }
}

/*
** Register built-in functions used to help read ANALYZE data.
*/
void sqlite3AnalyzeFunctions(void){
  static FuncDef aAnalyzeTableFuncs[] = {
    FUNCTION(sqlite_record,   1, 0, 0, recordFunc),
  };
  sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs));
}

/*
** Attempt to extract a value from pExpr and use it to construct *ppVal.
**
** If pAlloc is not NULL, then an UnpackedRecord object is created for
** pAlloc if one does not exist and the new value is added to the
** UnpackedRecord object.
**

Changes to src/vdbesort.c.

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







-
-
+
+












-
-
+







  const u8 * const v1 = &p1[ p1[0] ];   /* Pointer to value 1 */
  const u8 * const v2 = &p2[ p2[0] ];   /* Pointer to value 2 */

  int n1;
  int n2;
  int res;

  getVarint32NR(&p1[1], n1);
  getVarint32NR(&p2[1], n2);
  getVarint32(&p1[1], n1);
  getVarint32(&p2[1], n2);
  res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2);
  if( res==0 ){
    res = n1 - n2;
  }

  if( res==0 ){
    if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
      res = vdbeSorterCompareTail(
          pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
      );
    }
  }else{
    assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
    if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
    if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
      res = res * -1;
    }
  }

  return res;
}

894
895
896
897
898
899
900
901

902
903
904
905
906
907
908
909
893
894
895
896
897
898
899

900

901
902
903
904
905
906
907







-
+
-








  if( res==0 ){
    if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
      res = vdbeSorterCompareTail(
          pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
      );
    }
  }else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
  }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
    assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
    res = res * -1;
  }

  return res;
}

/*
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981

982
983
984
985
986
987
988
989
964
965
966
967
968
969
970

971
972
973
974
975
976


977

978
979
980
981
982
983
984







-






-
-
+
-







  sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);

  pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
  pCsr->uc.pSorter = pSorter;
  if( pSorter==0 ){
    rc = SQLITE_NOMEM_BKPT;
  }else{
    Btree *pBt = db->aDb[0].pBt;
    pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
    memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
    pKeyInfo->db = 0;
    if( nField && nWorker==0 ){
      pKeyInfo->nKeyField = nField;
    }
    sqlite3BtreeEnter(pBt);
    pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt);
    pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
    sqlite3BtreeLeave(pBt);
    pSorter->nTask = nWorker + 1;
    pSorter->iPrev = (u8)(nWorker - 1);
    pSorter->bUseThreads = (pSorter->nTask>1);
    pSorter->db = db;
    for(i=0; i<pSorter->nTask; i++){
      SortSubtask *pTask = &pSorter->aTask[i];
      pTask->pSorter = pSorter;
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021







-







        pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
        if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT;
      }
    }

    if( pKeyInfo->nAllField<13 
     && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
     && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0
    ){
      pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
    }
  }

  return rc;
}
1395
1396
1397
1398
1399
1400
1401

1402
1403
1404
1405
1406
1407
1408
1409
1410
1411





1412
1413
1414
1415
1416
1417
1418
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







+


-






-
+
+
+
+
+







/*
** Sort the linked list of records headed at pTask->pList. Return 
** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if 
** an error occurs.
*/
static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
  int i;
  SorterRecord **aSlot;
  SorterRecord *p;
  int rc;
  SorterRecord *aSlot[64];

  rc = vdbeSortAllocUnpacked(pTask);
  if( rc!=SQLITE_OK ) return rc;

  p = pList->pList;
  pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
  memset(aSlot, 0, sizeof(aSlot));

  aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
  if( !aSlot ){
    return SQLITE_NOMEM_BKPT;
  }

  while( p ){
    SorterRecord *pNext;
    if( pList->aMemory ){
      if( (u8*)p==pList->aMemory ){
        pNext = 0;
      }else{
1429
1430
1431
1432
1433
1434
1435
1436

1437
1438
1439
1440
1441

1442
1443
1444
1445
1446
1447
1448
1427
1428
1429
1430
1431
1432
1433

1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447







-
+





+







      aSlot[i] = 0;
    }
    aSlot[i] = p;
    p = pNext;
  }

  p = 0;
  for(i=0; i<ArraySize(aSlot); i++){
  for(i=0; i<64; i++){
    if( aSlot[i]==0 ) continue;
    p = p ? vdbeSorterMerge(pTask, p, aSlot[i]) : aSlot[i];
  }
  pList->pList = p;

  sqlite3_free(aSlot);
  assert( pTask->pUnpacked->errCode==SQLITE_OK 
       || pTask->pUnpacked->errCode==SQLITE_NOMEM 
  );
  return pTask->pUnpacked->errCode;
}

/*
1725
1726
1727
1728
1729
1730
1731
1732
1733


1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1724
1725
1726
1727
1728
1729
1730


1731
1732
1733

1734
1735
1736
1737


1738
1739
1740
1741
1742
1743
1744







-
-
+
+

-




-
-








  if( rc==SQLITE_OK ){
    if( i==nWorker ){
      /* Use the foreground thread for this operation */
      rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list);
    }else{
      /* Launch a background thread for this operation */
      u8 *aMem;
      void *pCtx;
      u8 *aMem = pTask->list.aMemory;
      void *pCtx = (void*)pTask;

      assert( pTask!=0 );
      assert( pTask->pThread==0 && pTask->bDone==0 );
      assert( pTask->list.pList==0 );
      assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 );

      aMem = pTask->list.aMemory;
      pCtx = (void*)pTask;
      pSorter->iPrev = (u8)(pTask - pSorter->aTask);
      pTask->list = pSorter->list;
      pSorter->list.pList = 0;
      pSorter->list.szPMA = 0;
      if( aMem ){
        pSorter->list.aMemory = aMem;
        pSorter->nMemory = sqlite3MallocSize(aMem);
1772
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
1768
1769
1770
1771
1772
1773
1774

1775
1776
1777
1778
1779
1780
1781
1782







-
+







  int bFlush;                     /* True to flush contents of memory to PMA */
  int nReq;                       /* Bytes of memory required */
  int nPMA;                       /* Bytes of PMA space required */
  int t;                          /* serial type of first record field */

  assert( pCsr->eCurType==CURTYPE_SORTER );
  pSorter = pCsr->uc.pSorter;
  getVarint32NR((const u8*)&pVal->z[1], t);
  getVarint32((const u8*)&pVal->z[1], t);
  if( t>0 && t<10 && t!=7 ){
    pSorter->typeMask &= SORTER_TYPE_INTEGER;
  }else if( t>10 && (t & 0x01) ){
    pSorter->typeMask &= SORTER_TYPE_TEXT;
  }else{
    pSorter->typeMask = 0;
  }

Changes to src/vdbetrace.c.

121
122
123
124
125
126
127
128

129
130
131
132
133

134
135
136
137
138
139
140
121
122
123
124
125
126
127

128
129
130
131
132

133
134
135
136
137
138
139
140







-
+




-
+







        testcase( zRawSql[0]=='$' );
        testcase( zRawSql[0]=='@' );
        testcase( zRawSql[0]=='#' );
        idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
        assert( idx>0 );
      }
      zRawSql += nToken;
      nextIndex = MAX(idx + 1, nextIndex);
      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) ){
      }else if( pVar->flags & MEM_Int ){
        sqlite3_str_appendf(&out, "%lld", pVar->u.i);
      }else if( pVar->flags & MEM_Real ){
        sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
      }else if( pVar->flags & MEM_Str ){
        int nOut;  /* Number of bytes of the string text to include in output */
#ifndef SQLITE_OMIT_UTF16
        u8 enc = ENC(db);

Deleted src/vdbevtab.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








































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2020-03-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 virtual-tables for examining the bytecode content
** of a prepared statement.
*/
#include "sqliteInt.h"
#if defined(SQLITE_ENABLE_BYTECODE_VTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
#include "vdbeInt.h"

/* An instance of the bytecode() table-valued function.
*/
typedef struct bytecodevtab bytecodevtab;
struct bytecodevtab {
  sqlite3_vtab base;     /* Base class - must be first */
  sqlite3 *db;           /* Database connection */
  int bTablesUsed;       /* 2 for tables_used().  0 for bytecode(). */
};

/* A cursor for scanning through the bytecode
*/
typedef struct bytecodevtab_cursor bytecodevtab_cursor;
struct bytecodevtab_cursor {
  sqlite3_vtab_cursor base;  /* Base class - must be first */
  sqlite3_stmt *pStmt;       /* The statement whose bytecode is displayed */
  int iRowid;                /* The rowid of the output table */
  int iAddr;                 /* Address */
  int needFinalize;          /* Cursors owns pStmt and must finalize it */
  int showSubprograms;       /* Provide a listing of subprograms */
  Op *aOp;                   /* Operand array */
  char *zP4;                 /* Rendered P4 value */
  const char *zType;         /* tables_used.type */
  const char *zSchema;       /* tables_used.schema */
  const char *zName;         /* tables_used.name */
  Mem sub;                   /* Subprograms */
};

/*
** Create a new bytecode() table-valued function.
*/
static int bytecodevtabConnect(
  sqlite3 *db,
  void *pAux,
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErr
){
  bytecodevtab *pNew;
  int rc;
  int isTabUsed = pAux!=0;
  const char *azSchema[2] = {
    /* bytecode() schema */
    "CREATE TABLE x("
      "addr INT,"
      "opcode TEXT,"
      "p1 INT,"
      "p2 INT,"
      "p3 INT,"
      "p4 TEXT,"
      "p5 INT,"
      "comment TEXT,"
      "subprog TEXT," 
      "stmt HIDDEN"
    ");",

    /* Tables_used() schema */
    "CREATE TABLE x("
      "type TEXT,"
      "schema TEXT,"
      "name TEXT,"
      "wr INT,"
      "subprog TEXT," 
      "stmt HIDDEN"
   ");"
  };

  rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
  if( rc==SQLITE_OK ){
    pNew = sqlite3_malloc( sizeof(*pNew) );
    *ppVtab = (sqlite3_vtab*)pNew;
    if( pNew==0 ) return SQLITE_NOMEM;
    memset(pNew, 0, sizeof(*pNew));
    pNew->db = db;
    pNew->bTablesUsed = isTabUsed*2;
  }
  return rc;
}

/*
** This method is the destructor for bytecodevtab objects.
*/
static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
  bytecodevtab *p = (bytecodevtab*)pVtab;
  sqlite3_free(p);
  return SQLITE_OK;
}

/*
** Constructor for a new bytecodevtab_cursor object.
*/
static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
  bytecodevtab *pVTab = (bytecodevtab*)p;
  bytecodevtab_cursor *pCur;
  pCur = sqlite3_malloc( sizeof(*pCur) );
  if( pCur==0 ) return SQLITE_NOMEM;
  memset(pCur, 0, sizeof(*pCur));
  sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
  *ppCursor = &pCur->base;
  return SQLITE_OK;
}

/*
** Clear all internal content from a bytecodevtab cursor.
*/
static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
  sqlite3_free(pCur->zP4);
  pCur->zP4 = 0;
  sqlite3VdbeMemRelease(&pCur->sub);
  sqlite3VdbeMemSetNull(&pCur->sub);
  if( pCur->needFinalize ){
    sqlite3_finalize(pCur->pStmt);
  }
  pCur->pStmt = 0;
  pCur->needFinalize = 0;
  pCur->zType = 0;
  pCur->zSchema = 0;
  pCur->zName = 0;
}

/*
** Destructor for a bytecodevtab_cursor.
*/
static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
  bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
  bytecodevtabCursorClear(pCur);
  sqlite3_free(pCur);
  return SQLITE_OK;
}


/*
** Advance a bytecodevtab_cursor to its next row of output.
*/
static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
  bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
  bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
  int rc;
  if( pCur->zP4 ){
    sqlite3_free(pCur->zP4);
    pCur->zP4 = 0;
  }
  if( pCur->zName ){
    pCur->zName = 0;
    pCur->zType = 0;
    pCur->zSchema = 0;
  }
  rc = sqlite3VdbeNextOpcode(
           (Vdbe*)pCur->pStmt, 
           pCur->showSubprograms ? &pCur->sub : 0,
           pTab->bTablesUsed,
           &pCur->iRowid,
           &pCur->iAddr,
           &pCur->aOp);
  if( rc!=SQLITE_OK ){
    sqlite3VdbeMemSetNull(&pCur->sub);
    pCur->aOp = 0;
  }
  return SQLITE_OK;
}

/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
  bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
  return pCur->aOp==0;
}

/*
** Return values of columns for the row at which the bytecodevtab_cursor
** is currently pointing.
*/
static int bytecodevtabColumn(
  sqlite3_vtab_cursor *cur,   /* The cursor */
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
  int i                       /* Which column to return */
){
  bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
  bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
  Op *pOp = pCur->aOp + pCur->iAddr;
  if( pVTab->bTablesUsed ){
    if( i==4 ){
      i = 8;
    }else{
      if( i<=2 && pCur->zType==0 ){
        Schema *pSchema;
        HashElem *k;
        int iDb = pOp->p3;
        Pgno iRoot = (Pgno)pOp->p2;
        sqlite3 *db = pVTab->db;
        pSchema = db->aDb[iDb].pSchema;
        pCur->zSchema = db->aDb[iDb].zDbSName;
        for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
          Table *pTab = (Table*)sqliteHashData(k);
          if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
            pCur->zName = pTab->zName;
            pCur->zType = "table";
            break;
          }
        }
        if( pCur->zName==0 ){
          for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
            Index *pIdx = (Index*)sqliteHashData(k);
            if( pIdx->tnum==iRoot ){
              pCur->zName = pIdx->zName;
              pCur->zType = "index";
            }
          }
        }
      }
      i += 10;
    }
  }
  switch( i ){
    case 0:   /* addr */
      sqlite3_result_int(ctx, pCur->iAddr);
      break;
    case 1:   /* opcode */
      sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
                          -1, SQLITE_STATIC);
      break;
    case 2:   /* p1 */
      sqlite3_result_int(ctx, pOp->p1);
      break;
    case 3:   /* p2 */
      sqlite3_result_int(ctx, pOp->p2);
      break;
    case 4:   /* p3 */
      sqlite3_result_int(ctx, pOp->p3);
      break;
    case 5:   /* p4 */
    case 7:   /* comment */
      if( pCur->zP4==0 ){
        pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
      }
      if( i==5 ){
        sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
      }else{
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
        char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
        sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
#endif
      }
      break;
    case 6:     /* p5 */
      sqlite3_result_int(ctx, pOp->p5);
      break;
    case 8: {   /* subprog */
      Op *aOp = pCur->aOp;
      assert( aOp[0].opcode==OP_Init );
      assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
      if( pCur->iRowid==pCur->iAddr+1 ){
        break;  /* Result is NULL for the main program */
      }else if( aOp[0].p4.z!=0 ){
         sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
      }else{
         sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
      }
      break;
    }
    case 10:  /* tables_used.type */
      sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
      break;
    case 11:  /* tables_used.schema */
      sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
      break;
    case 12:  /* tables_used.name */
      sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
      break;
    case 13:  /* tables_used.wr */
      sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
      break;
  }
  return SQLITE_OK;
}

/*
** Return the rowid for the current row.  In this implementation, the
** rowid is the same as the output value.
*/
static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
  bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
  *pRowid = pCur->iRowid;
  return SQLITE_OK;
}

/*
** Initialize a cursor.
**
**    idxNum==0     means show all subprograms
**    idxNum==1     means show only the main bytecode and omit subprograms.
*/
static int bytecodevtabFilter(
  sqlite3_vtab_cursor *pVtabCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
  bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
  int rc = SQLITE_OK;

  bytecodevtabCursorClear(pCur);
  pCur->iRowid = 0;
  pCur->iAddr = 0;
  pCur->showSubprograms = idxNum==0;
  assert( argc==1 );
  if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
    const char *zSql = (const char*)sqlite3_value_text(argv[0]);
    if( zSql==0 ){
      rc = SQLITE_NOMEM;
    }else{
      rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
      pCur->needFinalize = 1;
    }
  }else{
    pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
  }
  if( pCur->pStmt==0 ){
    pVTab->base.zErrMsg = sqlite3_mprintf(
       "argument to %s() is not a valid SQL statement",
       pVTab->bTablesUsed ? "tables_used" : "bytecode"
    );
    rc = SQLITE_ERROR;
  }else{
    bytecodevtabNext(pVtabCursor);
  }
  return rc;
}

/*
** We must have a single stmt=? constraint that will be passed through
** into the xFilter method.  If there is no valid stmt=? constraint,
** then return an SQLITE_CONSTRAINT error.
*/
static int bytecodevtabBestIndex(
  sqlite3_vtab *tab,
  sqlite3_index_info *pIdxInfo
){
  int i;
  int rc = SQLITE_CONSTRAINT;
  struct sqlite3_index_constraint *p;
  bytecodevtab *pVTab = (bytecodevtab*)tab;
  int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
  pIdxInfo->estimatedCost = (double)100;
  pIdxInfo->estimatedRows = 100;
  pIdxInfo->idxNum = 0;
  for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
    if( p->usable==0 ) continue;
    if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
      rc = SQLITE_OK;
      pIdxInfo->aConstraintUsage[i].omit = 1;
      pIdxInfo->aConstraintUsage[i].argvIndex = 1;
    }
    if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
      pIdxInfo->aConstraintUsage[i].omit = 1;
      pIdxInfo->idxNum = 1;
    }
  }
  return rc;
}

/*
** This following structure defines all the methods for the 
** virtual table.
*/
static sqlite3_module bytecodevtabModule = {
  /* iVersion    */ 0,
  /* xCreate     */ 0,
  /* xConnect    */ bytecodevtabConnect,
  /* xBestIndex  */ bytecodevtabBestIndex,
  /* xDisconnect */ bytecodevtabDisconnect,
  /* xDestroy    */ 0,
  /* xOpen       */ bytecodevtabOpen,
  /* xClose      */ bytecodevtabClose,
  /* xFilter     */ bytecodevtabFilter,
  /* xNext       */ bytecodevtabNext,
  /* xEof        */ bytecodevtabEof,
  /* xColumn     */ bytecodevtabColumn,
  /* xRowid      */ bytecodevtabRowid,
  /* xUpdate     */ 0,
  /* xBegin      */ 0,
  /* xSync       */ 0,
  /* xCommit     */ 0,
  /* xRollback   */ 0,
  /* xFindMethod */ 0,
  /* xRename     */ 0,
  /* xSavepoint  */ 0,
  /* xRelease    */ 0,
  /* xRollbackTo */ 0,
  /* xShadowName */ 0
};


int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
  int rc;
  rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
  }
  return rc;
}
#elif defined(SQLITE_ENABLE_BYTECODE_VTAB)
int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_BYTECODE_VTAB */

Changes to src/vtab.c.

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







-
-
-









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






-
-
-
-
-
+
+
+



-
-
-




















+
+
+
-
+
+







  int bDeclared;      /* True after sqlite3_declare_vtab() is called */
};

/*
** Construct and install a Module object for a virtual table.  When this
** routine is called, it is guaranteed that all appropriate locks are held
** and the module is not already part of the connection.
**
** If there already exists a module with zName, replace it with the new one.
** If pModule==0, then delete the module zName if it exists.
*/
Module *sqlite3VtabCreateModule(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
  const sqlite3_module *pModule,  /* The definition of the module */
  void *pAux,                     /* Context pointer for xCreate/xConnect */
  void (*xDestroy)(void *)        /* Module destructor function */
){
  Module *pMod;
  Module *pDel;
  char *zCopy;
  if( pModule==0 ){
    zCopy = (char*)zName;
    pMod = 0;
  }else{
    int nName = sqlite3Strlen30(zName);
    pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
    if( pMod==0 ){
      sqlite3OomFault(db);
  int nName = sqlite3Strlen30(zName);
  pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
  if( pMod==0 ){
    sqlite3OomFault(db);
      return 0;
    }
    zCopy = (char *)(&pMod[1]);
  }else{
    Module *pDel;
    char *zCopy = (char *)(&pMod[1]);
    memcpy(zCopy, zName, nName+1);
    pMod->zName = zCopy;
    pMod->pModule = pModule;
    pMod->pAux = pAux;
    pMod->xDestroy = xDestroy;
    pMod->pEpoTab = 0;
    pMod->nRefModule = 1;
  }
  pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
  if( pDel ){
    if( pDel==pMod ){
    pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
    assert( pDel==0 || pDel==pMod );
    if( pDel ){
      sqlite3OomFault(db);
      sqlite3DbFree(db, pDel);
      pMod = 0;
    }else{
      sqlite3VtabEponymousTableClear(db, pDel);
      sqlite3VtabModuleUnref(db, pDel);
    }
  }
  return pMod;
}

/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
*/
static int createModule(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
  const sqlite3_module *pModule,  /* The definition of the module */
  void *pAux,                     /* Context pointer for xCreate/xConnect */
  void (*xDestroy)(void *)        /* Module destructor function */
){
  int rc = SQLITE_OK;

  sqlite3_mutex_enter(db->mutex);
  if( sqlite3HashFind(&db->aModule, zName) ){
    rc = SQLITE_MISUSE_BKPT;
  }else{
  (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
    (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
  }
  rc = sqlite3ApiExit(db, rc);
  if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}


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
119
120
121
122
123
124
125






































126
127
128
129
130
131
132







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







){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
  return createModule(db, zName, pModule, pAux, xDestroy);
}

/*
** External API to drop all virtual-table modules, except those named
** on the azNames list.
*/
int sqlite3_drop_modules(sqlite3 *db, const char** azNames){
  HashElem *pThis, *pNext;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){
    Module *pMod = (Module*)sqliteHashData(pThis);
    pNext = sqliteHashNext(pThis);
    if( azNames ){
      int ii;
      for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){}
      if( azNames[ii]!=0 ) continue;
    }
    createModule(db, pMod->zName, 0, 0, 0);
  }
  return SQLITE_OK;
}

/*
** Decrement the reference count on a Module object.  Destroy the
** module when the reference count reaches zero.
*/
void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){
  assert( pMod->nRefModule>0 );
  pMod->nRefModule--;
  if( pMod->nRefModule==0 ){
    if( pMod->xDestroy ){
      pMod->xDestroy(pMod->pAux);
    }
    assert( pMod->pEpoTab==0 );
    sqlite3DbFree(db, pMod);
  }
}

/*
** Lock the virtual table so that it cannot be disconnected.
** Locks nest.  Every lock should have a corresponding unlock.
** If an unlock is omitted, resources leaks will occur.  
**
** If a disconnect is attempted while a virtual table is locked,
** the disconnect is deferred until all locks have been removed.
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
158
159
160
161
162
163
164

165
166
167
168
169
170
171







-







  assert( db );
  assert( pVTab->nRef>0 );
  assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE );

  pVTab->nRef--;
  if( pVTab->nRef==0 ){
    sqlite3_vtab *p = pVTab->pVtab;
    sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod);
    if( p ){
      p->pModule->xDisconnect(p);
    }
    sqlite3DbFree(db, pVTab);
  }
}

301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
252
253
254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271







+





-







**      the database handle mutex is held.
**
** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously 
** by multiple threads. It is thread-safe.
*/
void sqlite3VtabUnlockList(sqlite3 *db){
  VTable *p = db->pDisconnect;
  db->pDisconnect = 0;

  assert( sqlite3BtreeHoldsAllMutexes(db) );
  assert( sqlite3_mutex_held(db->mutex) );

  if( p ){
    db->pDisconnect = 0;
    sqlite3ExpirePreparedStatements(db, 0);
    do {
      VTable *pNext = p->pNext;
      sqlite3VtabUnlock(p);
      p = pNext;
    }while( p );
  }
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366







-
+







  pParse->sNameToken.n = (int)(
      &pModuleName->z[pModuleName->n] - pParse->sNameToken.z
  );

#ifndef SQLITE_OMIT_AUTHORIZATION
  /* Creating a virtual table invokes the authorization callback twice.
  ** The first invocation, to obtain permission to INSERT a row into the
  ** sqlite_schema table, has already been made by sqlite3StartTable().
  ** sqlite_master table, has already been made by sqlite3StartTable().
  ** The second call, to obtain permission to create the table, is made now.
  */
  if( pTable->azModuleArg ){
    int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
    assert( iDb>=0 ); /* The database the table is being created in */
    sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, 
            pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
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
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







-
+

-
+








-
-







-
+



-
+




-
+


-
+





+




-
-
+
+
-






-
+







  if( pTab==0 ) return;
  addArgumentToVtab(pParse);
  pParse->sArg.z = 0;
  if( pTab->nModuleArg<1 ) return;
  
  /* If the CREATE VIRTUAL TABLE statement is being entered for the
  ** first time (in other words if the virtual table is actually being
  ** created now instead of just being read out of sqlite_schema) then
  ** created now instead of just being read out of sqlite_master) then
  ** do additional initialization work and store the statement text
  ** in the sqlite_schema table.
  ** in the sqlite_master table.
  */
  if( !db->init.busy ){
    char *zStmt;
    char *zWhere;
    int iDb;
    int iReg;
    Vdbe *v;

    sqlite3MayAbort(pParse);

    /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
    if( pEnd ){
      pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n;
    }
    zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);

    /* A slot for the record has already been allocated in the 
    ** schema table.  We just need to update that slot with all
    ** SQLITE_MASTER table.  We just need to update that slot with all
    ** the information we've collected.  
    **
    ** The VM register number pParse->regRowid holds the rowid of an
    ** entry in the sqlite_schema table tht was created for this vtab
    ** entry in the sqlite_master table tht was created for this vtab
    ** by sqlite3StartTable().
    */
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    sqlite3NestedParse(pParse,
      "UPDATE %Q." DFLT_SCHEMA_TABLE " "
      "UPDATE %Q.%s "
         "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
       "WHERE rowid=#%d",
      db->aDb[iDb].zDbSName,
      db->aDb[iDb].zDbSName, MASTER_NAME,
      pTab->zName,
      pTab->zName,
      zStmt,
      pParse->regRowid
    );
    sqlite3DbFree(db, zStmt);
    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);
    zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
    sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
    sqlite3DbFree(db, zStmt);

    iReg = ++pParse->nMem;
    sqlite3VdbeLoadString(v, iReg, pTab->zName);
    sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
  }

  /* If we are rereading the sqlite_schema table create the in-memory
  /* If we are rereading the sqlite_master table create the in-memory
  ** record of the table. The xConnect() method is not called until
  ** the first time the virtual table is used in an SQL statement. This
  ** allows a schema that contains virtual tables to be loaded before
  ** the required virtual table implementations are registered.  */
  else {
    Table *pOld;
    Schema *pSchema = pTab->pSchema;
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
532
533
534
535
536
537
538

539
540
541
542
543
544
545







-







  if( !pVTable ){
    sqlite3OomFault(db);
    sqlite3DbFree(db, zModuleName);
    return SQLITE_NOMEM_BKPT;
  }
  pVTable->db = db;
  pVTable->pMod = pMod;
  pVTable->eVtabRisk = SQLITE_VTABRISK_Normal;

  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  pTab->azModuleArg[1] = db->aDb[iDb].zDbSName;

  /* Invoke the virtual table constructor */
  assert( &db->pVtabCtx );
  assert( xConstruct );
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
584







-








-
+







    }
    sqlite3DbFree(db, pVTable);
  }else if( ALWAYS(pVTable->pVtab) ){
    /* Justification of ALWAYS():  A correct vtab constructor must allocate
    ** the sqlite3_vtab object if successful.  */
    memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
    pVTable->pVtab->pModule = pMod->pModule;
    pMod->nRefModule++;
    pVTable->nRef = 1;
    if( sCtx.bDeclared==0 ){
      const char *zFormat = "vtable constructor did not declare schema: %s";
      *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
      sqlite3VtabUnlock(pVTable);
      rc = SQLITE_ERROR;
    }else{
      int iCol;
      u16 oooHidden = 0;
      u8 oooHidden = 0;
      /* If everything went according to plan, link the new VTable structure
      ** into the linked list headed by pTab->pVTable. Then loop through the 
      ** columns of the table to see if any of them contain the token "hidden".
      ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
      ** the type string.  */
      pVTable->pNext = pTab->pVTable;
      pTab->pVTable = pVTable;
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
603
604
605
606
607
608
609

610
611
612
613
614
615
616







-







            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;
        }
      }
    }
  }
825
826
827
828
829
830
831
832

833
834
835
836
837
838
839
771
772
773
774
775
776
777

778
779
780
781
782
783
784
785







-
+







   && !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->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
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
836
837
838
839
840
841
842


843

844
845
846
847
848
849
850
851

852
853
854
855
856
857
858







-
-
+
-








-







      assert( p->pVtab );
      if( p->pVtab->nRef>0 ){
        return SQLITE_LOCKED;
      }
    }
    p = vtabDisconnectAll(db, pTab);
    xDestroy = p->pMod->pModule->xDestroy;
    if( xDestroy==0 ) xDestroy = p->pMod->pModule->xDisconnect;
    assert( xDestroy!=0 );
    assert( xDestroy!=0 );  /* Checked before the virtual table is created */
    pTab->nTabRef++;
    rc = xDestroy(p->pVtab);
    /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
    if( rc==SQLITE_OK ){
      assert( pTab->pVTable==p && p->pNext==0 );
      p->pVtab = 0;
      pTab->pVTable = 0;
      sqlite3VtabUnlock(p);
    }
    sqlite3DeleteTable(db, pTab);
  }

  return rc;
}

/*
** This function invokes either the xRollback or xCommit method
1174
1175
1176
1177
1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188
1117
1118
1119
1120
1121
1122
1123

1124
1125
1126
1127
1128
1129
1130
1131







-
+







  Table **apVtabLock;

  assert( IsVirtual(pTab) );
  for(i=0; i<pToplevel->nVtabLock; i++){
    if( pTab==pToplevel->apVtabLock[i] ) return;
  }
  n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
  apVtabLock = sqlite3Realloc(pToplevel->apVtabLock, n);
  apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
  if( apVtabLock ){
    pToplevel->apVtabLock = apVtabLock;
    pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
  }else{
    sqlite3OomFault(pToplevel->db);
  }
}
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
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







-





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

-

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







** Call from within the xCreate() or xConnect() methods to provide 
** the SQLite core with additional information about the behavior
** of the virtual table being implemented.
*/
int sqlite3_vtab_config(sqlite3 *db, int op, ...){
  va_list ap;
  int rc = SQLITE_OK;
  VtabCtx *p;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  sqlite3_mutex_enter(db->mutex);
  va_start(ap, op);
  switch( op ){
    case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
  p = db->pVtabCtx;
  if( !p ){
    rc = SQLITE_MISUSE_BKPT;
  }else{
    assert( p->pTab==0 || IsVirtual(p->pTab) );
      VtabCtx *p = db->pVtabCtx;
      if( !p ){
        rc = SQLITE_MISUSE_BKPT;
      }else{
        assert( p->pTab==0 || IsVirtual(p->pTab) );
    va_start(ap, op);
    switch( op ){
      case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
        p->pVTable->bConstraint = (u8)va_arg(ap, int);
        break;
      }
      case SQLITE_VTAB_INNOCUOUS: {
        p->pVTable->eVtabRisk = SQLITE_VTABRISK_Low;
        break;
      }
      break;
    }
      case SQLITE_VTAB_DIRECTONLY: {
        p->pVTable->eVtabRisk = SQLITE_VTABRISK_High;
        break;
      }
      default: {
        rc = SQLITE_MISUSE_BKPT;
        break;
      }
    default:
      rc = SQLITE_MISUSE_BKPT;
      break;
  }
    }
    va_end(ap);
  va_end(ap);
  }

  if( rc!=SQLITE_OK ) sqlite3Error(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

#endif /* SQLITE_OMIT_VIRTUALTABLE */

Changes to src/wal.c.

254
255
256
257
258
259
260












261
262
263
264
265
266
267
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







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







#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
int sqlite3WalTrace = 0;
# define WALTRACE(X)  if(sqlite3WalTrace) sqlite3DebugPrintf X
#else
# define WALTRACE(X)
#endif

/*
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
** places.  The following macros try to make this explicit.
*/
#if GCC_VESRION>=5004000
# 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

/*
** The maximum (and only) versions of the wal and wal-index formats
** that may be interpreted by this version of SQLite.
**
** If a client begins recovering a WAL file and finds that (a) the checksum
** values in the wal-header are correct and (b) the version field is not
** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN.
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
475
476
477
478
479
480
481



482
483
484
485
486
487
488







-
-
-







  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
#ifdef SQLITE_DEBUG
  u8 lockError;              /* True if a locking error has occurred */
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
  WalIndexHdr *pSnapshot;    /* Start transaction here if not NULL */
#endif
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
  sqlite3 *db;
#endif
};

/*
** Candidate values for Wal.exclusiveMode.
*/
#define WAL_NORMAL_MODE     0
#define WAL_EXCLUSIVE_MODE  1     
504
505
506
507
508
509
510
511

512
513
514
515
516
517
518
513
514
515
516
517
518
519

520
521
522
523
524
525
526
527







-
+







**   walIteratorInit() - Create a new iterator,
**   walIteratorNext() - Step an iterator,
**   walIteratorFree() - Free an iterator.
**
** This functionality is used by the checkpoint code (see walCheckpoint()).
*/
struct WalIterator {
  u32 iPrior;                     /* Last result returned from the iterator */
  int iPrior;                     /* Last result returned from the iterator */
  int nSegment;                   /* Number of entries in aSegment[] */
  struct WalSegment {
    int iNext;                    /* Next slot in aIndex[] not yet returned */
    ht_slot *aIndex;              /* i0, i1, i2... such that aPgno[iN] ascend */
    u32 *aPgno;                   /* Array of page numbers. */
    int nEntry;                   /* Nr. of entries in aPgno[] and aIndex[] */
    int iZero;                    /* Frame number associated with aPgno[0] */
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587







-
+







){
  int rc = SQLITE_OK;

  /* Enlarge the pWal->apWiData[] array if required */
  if( pWal->nWiData<=iPage ){
    sqlite3_int64 nByte = sizeof(u32*)*(iPage+1);
    volatile u32 **apNew;
    apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte);
    apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
    if( !apNew ){
      *ppPage = 0;
      return SQLITE_NOMEM_BKPT;
    }
    memset((void*)&apNew[pWal->nWiData], 0,
           sizeof(u32*)*(iPage+1-pWal->nWiData));
    pWal->apWiData = apNew;
586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
595
596
597
598
599
600
601



602
603
604
605
606
607
608
609







-
-
-
+







    if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
  }else{
    rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
        pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
    );
    assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
    testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
    if( rc==SQLITE_OK ){
      if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
    }else if( (rc&0xff)==SQLITE_READONLY ){
    if( (rc&0xff)==SQLITE_READONLY ){
      pWal->readOnly |= WAL_SHM_RDONLY;
      if( rc==SQLITE_READONLY ){
        rc = SQLITE_OK;
      }
    }
  }

687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722

723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
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







-
-
-
-






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





-
+







-







    }while( aData<aEnd );
  }

  aOut[0] = s1;
  aOut[1] = s2;
}

/*
** If there is the possibility of concurrent access to the SHM file
** from multiple threads and/or processes, then do a memory barrier.
*/
static void walShmBarrier(Wal *pWal){
  if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
    sqlite3OsShmBarrier(pWal->pDbFd);
  }
}

/*
** Add the SQLITE_NO_TSAN as part of the return-type of a function
** definition as a hint that the function contains constructs that
** might give false-positive TSAN warnings.
**
** See tag-20200519-1.
*/
#if defined(__clang__) && !defined(SQLITE_NO_TSAN)
# define SQLITE_NO_TSAN __attribute__((no_sanitize_thread))
#else
# define SQLITE_NO_TSAN
#endif

/*
** Write the header information in pWal->hdr into the wal-index.
**
** The checksum on pWal->hdr is updated before it is written.
*/
static SQLITE_NO_TSAN void walIndexWriteHdr(Wal *pWal){
static void walIndexWriteHdr(Wal *pWal){
  volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
  const int nCksum = offsetof(WalIndexHdr, aCksum);

  assert( pWal->writeLock );
  pWal->hdr.isInit = 1;
  pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
  walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
  /* Possible TSAN false-positive.  See tag-20200519-1 */
  memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
  walShmBarrier(pWal);
  memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
}

/*
** This function encodes a single frame header and writes it to a buffer
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
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







-
+















-
+







static int walLockShared(Wal *pWal, int lockIdx){
  int rc;
  if( pWal->exclusiveMode ) return SQLITE_OK;
  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
                        SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
  WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
            walLockName(lockIdx), rc ? "failed" : "ok"));
  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
  return rc;
}
static void walUnlockShared(Wal *pWal, int lockIdx){
  if( pWal->exclusiveMode ) return;
  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
                         SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
  WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
}
static int walLockExclusive(Wal *pWal, int lockIdx, int n){
  int rc;
  if( pWal->exclusiveMode ) return SQLITE_OK;
  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
                        SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
  WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
            walLockName(lockIdx), n, rc ? "failed" : "ok"));
  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
  return rc;
}
static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
  if( pWal->exclusiveMode ) return;
  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
                         SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
  WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
952
953
954
955
956
957
958

959
960
961
962
963
964
965







-







  int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE;
  assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE)
       && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE)
       && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE))
       && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)
       && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE))
  );
  assert( iHash>=0 );
  return iHash;
}

/*
** Return the page number associated with frame iFrame in this WAL.
*/
static u32 walFramePgno(Wal *pWal, u32 iFrame){
1095
1096
1097
1098
1099
1100
1101
1102

1103
1104
1105
1106
1107
1108
1109
1083
1084
1085
1086
1087
1088
1089

1090
1091
1092
1093
1094
1095
1096
1097







-
+








    /* Write the aPgno[] array entry and the hash-table slot. */
    nCollide = idx;
    for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
      if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
    }
    sLoc.aPgno[idx] = iPage;
    AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
    sLoc.aHash[iKey] = (ht_slot)idx;

#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
    /* Verify that the number of entries in the hash table exactly equals
    ** the number of entries in the mapping region.
    */
    {
      int i;           /* Loop counter */
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
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







+
+
+
+
+
+















-



+
+




-
-







  */
  assert( pWal->ckptLock==1 || pWal->ckptLock==0 );
  assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 );
  assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
  assert( pWal->writeLock );
  iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
  rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
  if( rc==SQLITE_OK ){
    rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
    if( rc!=SQLITE_OK ){
      walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
    }
  }
  if( rc ){
    return rc;
  }

  WALTRACE(("WAL%p: recovery begin...\n", pWal));

  memset(&pWal->hdr, 0, sizeof(WalIndexHdr));

  rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
  if( rc!=SQLITE_OK ){
    goto recovery_error;
  }

  if( nSize>WAL_HDRSIZE ){
    u8 aBuf[WAL_HDRSIZE];         /* Buffer to load WAL header into */
    u32 *aPrivate = 0;            /* Heap copy of *-shm hash being populated */
    u8 *aFrame = 0;               /* Malloc'd buffer to load entire frame */
    int szFrame;                  /* Number of bytes in buffer aFrame[] */
    u8 *aData;                    /* Pointer to data part of aFrame buffer */
    int iFrame;                   /* Index of last frame read */
    i64 iOffset;                  /* Next offset to read from log file */
    int szPage;                   /* Page size according to the log */
    u32 magic;                    /* Magic value read from WAL header */
    u32 version;                  /* Magic value read from WAL header */
    int isValid;                  /* True if this frame is valid */
    u32 iPg;                      /* Current 32KB wal-index page */
    u32 iLastFrame;               /* Last frame in wal, based on nSize alone */

    /* Read in the WAL header. */
    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
    if( rc!=SQLITE_OK ){
      goto recovery_error;
    }

1231
1232
1233
1234
1235
1236
1237
1238

1239
1240
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1255
1256
1257

1258
1259
1260
1261


1262
1263
1264
1265
1266
1267
1268
1269








1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280










1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329


1330
1331
1332
1333
1334
1335

1336
1337
1338
1339

1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364

1365
1366
1367
1368
1369
1370
1371
1224
1225
1226
1227
1228
1229
1230

1231
1232
1233
1234
1235
1236

1237
1238

1239










1240




1241
1242
1243







1244
1245
1246
1247
1248
1249
1250
1251
1252










1253
1254
1255
1256
1257
1258
1259
1260
1261
1262

































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


1277
1278
1279
1280
1281
1282
1283

1284




1285








1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310







-
+





-


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

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

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














-
-
+
+





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

















+







    if( version!=WAL_MAX_VERSION ){
      rc = SQLITE_CANTOPEN_BKPT;
      goto finished;
    }

    /* Malloc a buffer to read frames into. */
    szFrame = szPage + WAL_FRAME_HDRSIZE;
    aFrame = (u8 *)sqlite3_malloc64(szFrame + WALINDEX_PGSZ);
    aFrame = (u8 *)sqlite3_malloc64(szFrame);
    if( !aFrame ){
      rc = SQLITE_NOMEM_BKPT;
      goto recovery_error;
    }
    aData = &aFrame[WAL_FRAME_HDRSIZE];
    aPrivate = (u32*)&aData[szPage];

    /* Read all frames from the log file. */
    iLastFrame = (nSize - WAL_HDRSIZE) / szFrame;
    iFrame = 0;
    for(iPg=0; iPg<=(u32)walFramePage(iLastFrame); iPg++){
      u32 *aShare;
      u32 iFrame;                 /* Index of last frame read */
      u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
      u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
      u32 nHdr, nHdr32;
      rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
      if( rc ) break;
      pWal->apWiData[iPg] = aPrivate;
      
    for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){
      for(iFrame=iFirst; iFrame<=iLast; iFrame++){
        i64 iOffset = walFrameOffset(iFrame, szPage);
        u32 pgno;                 /* Database page number for frame */
        u32 nTruncate;            /* dbsize field from frame header */
      u32 pgno;                   /* Database page number for frame */
      u32 nTruncate;              /* dbsize field from frame header */

        /* Read and decode the next log frame. */
        rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
        if( rc!=SQLITE_OK ) break;
        isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame);
        if( !isValid ) break;
        rc = walIndexAppend(pWal, iFrame, pgno);
        if( NEVER(rc!=SQLITE_OK) ) break;
      /* Read and decode the next log frame. */
      iFrame++;
      rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
      if( rc!=SQLITE_OK ) break;
      isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame);
      if( !isValid ) break;
      rc = walIndexAppend(pWal, iFrame, pgno);
      if( rc!=SQLITE_OK ) break;

        /* If nTruncate is non-zero, this is a commit record. */
        if( nTruncate ){
          pWal->hdr.mxFrame = iFrame;
          pWal->hdr.nPage = nTruncate;
          pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
          testcase( szPage<=32768 );
          testcase( szPage>=65536 );
          aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
          aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
        }
      /* If nTruncate is non-zero, this is a commit record. */
      if( nTruncate ){
        pWal->hdr.mxFrame = iFrame;
        pWal->hdr.nPage = nTruncate;
        pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
        testcase( szPage<=32768 );
        testcase( szPage>=65536 );
        aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
        aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
      }
      }
      pWal->apWiData[iPg] = aShare;
      nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0);
      nHdr32 = nHdr / sizeof(u32);
#ifndef SQLITE_SAFER_WALINDEX_RECOVERY
      /* Memcpy() should work fine here, on all reasonable implementations.
      ** Technically, memcpy() might change the destination to some
      ** intermediate value before setting to the final value, and that might
      ** cause a concurrent reader to malfunction.  Memcpy() is allowed to
      ** do that, according to the spec, but no memcpy() implementation that
      ** we know of actually does that, which is why we say that memcpy()
      ** is safe for this.  Memcpy() is certainly a lot faster.
      */
      memcpy(&aShare[nHdr32], &aPrivate[nHdr32], WALINDEX_PGSZ-nHdr);
#else
      /* In the event that some platform is found for which memcpy()
      ** changes the destination to some intermediate value before
      ** setting the final value, this alternative copy routine is
      ** provided.
      */
      {
        int i;
        for(i=nHdr32; i<WALINDEX_PGSZ/sizeof(u32); i++){
          if( aShare[i]!=aPrivate[i] ){
            /* Atomic memory operations are not required here because if
            ** the value needs to be changed, that means it is not being
            ** accessed concurrently. */
            aShare[i] = aPrivate[i];
          }
        }
      }
#endif
      if( iFrame<=iLast ) break;
    }

    sqlite3_free(aFrame);
  }

finished:
  if( rc==SQLITE_OK ){
    volatile WalCkptInfo *pInfo;
    int i;
    pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
    pWal->hdr.aFrameCksum[1] = aFrameCksum[1];
    walIndexWriteHdr(pWal);

    /* Reset the checkpoint-header. This is safe because this thread is 
    ** currently holding locks that exclude all other writers and 
    ** checkpointers. Then set the values of read-mark slots 1 through N.
    ** currently holding locks that exclude all other readers, writers and
    ** checkpointers.
    */
    pInfo = walCkptInfo(pWal);
    pInfo->nBackfill = 0;
    pInfo->nBackfillAttempted = pWal->hdr.mxFrame;
    pInfo->aReadMark[0] = 0;
    for(i=1; i<WAL_NREADER; i++){
    for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
      rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
      if( rc==SQLITE_OK ){
        if( i==1 && pWal->hdr.mxFrame ){
          pInfo->aReadMark[i] = pWal->hdr.mxFrame;
    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
        }else{
          pInfo->aReadMark[i] = READMARK_NOT_USED;
        }
        walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
      }else if( rc!=SQLITE_BUSY ){
        goto recovery_error;
      }
    }

    /* If more than one frame was recovered from the log file, report an
    ** event via sqlite3_log(). This is to help with identifying performance
    ** problems caused by applications routinely shutting down without
    ** checkpointing the log file.
    */
    if( pWal->hdr.nPage ){
      sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
          "recovered %d frames from WAL file %s",
          pWal->hdr.mxFrame, pWal->zWalName
      );
    }
  }

recovery_error:
  WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
  walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
  walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
  return rc;
}

/*
** Close an open wal-index.
*/
static void walIndexClose(Wal *pWal, int isDelete){
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1683
1684
1685
1686
1687
1688
1689



















































































1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707






1708
1709
1710
1711
1712
1713
1714







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


















-
-
-
-
-
-







  if( rc!=SQLITE_OK ){
    walIteratorFree(p);
    p = 0;
  }
  *pp = p;
  return rc;
}

#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
** they are supported by the VFS, and (b) the database handle is configured 
** with a busy-timeout. Return 1 if blocking locks are successfully enabled, 
** or 0 otherwise.
*/
static int walEnableBlocking(Wal *pWal){
  int res = 0;
  if( pWal->db ){
    int tmout = pWal->db->busyTimeout;
    if( tmout ){
      int rc;
      rc = sqlite3OsFileControl(
          pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
      );
      res = (rc==SQLITE_OK);
    }
  }
  return res;
}

/*
** Disable blocking locks.
*/
static void walDisableBlocking(Wal *pWal){
  int tmout = 0;
  sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
}

/*
** If parameter bLock is true, attempt to enable blocking locks, take
** the WRITER lock, and then disable blocking locks. If blocking locks
** cannot be enabled, no attempt to obtain the WRITER lock is made. Return 
** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not
** an error if blocking locks can not be enabled.
**
** If the bLock parameter is false and the WRITER lock is held, release it.
*/
int sqlite3WalWriteLock(Wal *pWal, int bLock){
  int rc = SQLITE_OK;
  assert( pWal->readLock<0 || bLock==0 );
  if( bLock ){
    assert( pWal->db );
    if( walEnableBlocking(pWal) ){
      rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
      if( rc==SQLITE_OK ){
        pWal->writeLock = 1;
      }
      walDisableBlocking(pWal);
    }
  }else if( pWal->writeLock ){
    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
    pWal->writeLock = 0;
  }
  return rc;
}

/*
** Set the database handle used to determine if blocking locks are required.
*/
void sqlite3WalDb(Wal *pWal, sqlite3 *db){
  pWal->db = db;
}

/*
** Take an exclusive WRITE lock. Blocking if so configured.
*/
static int walLockWriter(Wal *pWal){
  int rc;
  walEnableBlocking(pWal);
  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
  walDisableBlocking(pWal);
  return rc;
}
#else
# define walEnableBlocking(x) 0
# define walDisableBlocking(x)
# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
# define sqlite3WalDb(pWal, db)
#endif   /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */


/*
** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
** n. If the attempt fails and parameter xBusy is not NULL, then it is a
** busy-handler function. Invoke it and retry the lock until either the
** lock is successfully obtained or the busy-handler returns 0.
*/
static int walBusyLock(
  Wal *pWal,                      /* WAL connection */
  int (*xBusy)(void*),            /* Function to call when busy */
  void *pBusyArg,                 /* Context argument for xBusyHandler */
  int lockIdx,                    /* Offset of first byte to lock */
  int n                           /* Number of bytes to lock */
){
  int rc;
  do {
    rc = walLockExclusive(pWal, lockIdx, n);
  }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
  if( rc==SQLITE_BUSY_TIMEOUT ){
    walDisableBlocking(pWal);
    rc = SQLITE_BUSY;
  }
#endif
  return rc;
}

/*
** The cache of the wal-index header must be valid to call this function.
** Return the page-size in bytes used by the database.
*/
1888
1889
1890
1891
1892
1893
1894
1895

1896
1897
1898
1899
1900
1901
1902
1738
1739
1740
1741
1742
1743
1744

1745
1746
1747
1748
1749
1750
1751
1752







-
+







  int i;                          /* Loop counter */
  u32 *aSalt = pWal->hdr.aSalt;   /* Big-endian salt values */
  pWal->nCkpt++;
  pWal->hdr.mxFrame = 0;
  sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
  memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
  walIndexWriteHdr(pWal);
  AtomicStore(&pInfo->nBackfill, 0);
  pInfo->nBackfill = 0;
  pInfo->nBackfillAttempted = 0;
  pInfo->aReadMark[1] = 0;
  for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
  assert( pInfo->aReadMark[0]==0 );
}

/*
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
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







+
+
+
+
+
+
+
+
-
+




-
+
-

















-
+














-


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

-





-
+















-












-
+







    ** safe to write into the database.  Frames beyond mxSafeFrame might
    ** overwrite database pages that are in use by active readers and thus
    ** cannot be backfilled from the WAL.
    */
    mxSafeFrame = pWal->hdr.mxFrame;
    mxPage = pWal->hdr.nPage;
    for(i=1; i<WAL_NREADER; i++){
      /* Thread-sanitizer reports that the following is an unsafe read,
      ** as some other thread may be in the process of updating the value
      ** of the aReadMark[] slot. The assumption here is that if that is
      ** happening, the other client may only be increasing the value,
      ** not decreasing it. So assuming either that either the "old" or
      ** "new" version of the value is read, and not some arbitrary value
      ** that would never be written by a real client, things are still 
      ** safe.  */
      u32 y = AtomicLoad(pInfo->aReadMark+i);
      u32 y = pInfo->aReadMark[i];
      if( mxSafeFrame>y ){
        assert( y<=pWal->hdr.mxFrame );
        rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
        if( rc==SQLITE_OK ){
          u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
          pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
          AtomicStore(pInfo->aReadMark+i, iMark);
          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
        }else if( rc==SQLITE_BUSY ){
          mxSafeFrame = y;
          xBusy = 0;
        }else{
          goto walcheckpoint_out;
        }
      }
    }

    /* Allocate the iterator */
    if( pInfo->nBackfill<mxSafeFrame ){
      rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
      assert( rc==SQLITE_OK || pIter==0 );
    }

    if( pIter
     && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
     && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
    ){
      u32 nBackfill = pInfo->nBackfill;

      pInfo->nBackfillAttempted = mxSafeFrame;

      /* Sync the WAL to disk */
      rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));

      /* If the database may grow as a result of this checkpoint, hint
      ** about the eventual size of the db file to the VFS layer.
      */
      if( rc==SQLITE_OK ){
        i64 nReq = ((i64)mxPage * szPage);
        i64 nSize;                    /* Current size of database file */
        sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
        rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
        if( rc==SQLITE_OK && nSize<nReq ){
          if( (nSize+65536+(i64)pWal->hdr.mxFrame*szPage)<nReq ){
            /* If the size of the final database is larger than the current
            ** database plus the amount of data in the wal file, plus the
            ** maximum size of the pending-byte page (65536 bytes), then 
            ** must be corruption somewhere.  */
            rc = SQLITE_CORRUPT_BKPT;
          }else{
            sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT,&nReq);
          }
        }
          sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
        }
      }

      }

      /* Iterate through the contents of the WAL, copying data to the db file */
      while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
        i64 iOffset;
        assert( walFramePgno(pWal, iFrame)==iDbpage );
        if( AtomicLoad(&db->u1.isInterrupted) ){
        if( db->u1.isInterrupted ){
          rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
          break;
        }
        if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
          continue;
        }
        iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
        /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
        rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
        if( rc!=SQLITE_OK ) break;
        iOffset = (iDbpage-1)*(i64)szPage;
        testcase( IS_BIG_INT(iOffset) );
        rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
        if( rc!=SQLITE_OK ) break;
      }
      sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);

      /* If work was actually accomplished... */
      if( rc==SQLITE_OK ){
        if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
          i64 szDb = pWal->hdr.nPage*(i64)szPage;
          testcase( IS_BIG_INT(szDb) );
          rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
          if( rc==SQLITE_OK ){
            rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
          }
        }
        if( rc==SQLITE_OK ){
          AtomicStore(&pInfo->nBackfill, mxSafeFrame);
          pInfo->nBackfill = mxSafeFrame;
        }
      }

      /* Release the reader lock held while backfilling */
      walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
    }

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







-
+












-



-
+
-
-
-
-
-


-
+







** If and only if the read is consistent and the header is different from
** pWal->hdr, then pWal->hdr is updated to the content of the new header
** and *pChanged is set to 1.
**
** If the checksum cannot be verified return non-zero. If the header
** is read successfully and the checksum verified, return zero.
*/
static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){
static int walIndexTryHdr(Wal *pWal, int *pChanged){
  u32 aCksum[2];                  /* Checksum on the header content */
  WalIndexHdr h1, h2;             /* Two copies of the header content */
  WalIndexHdr volatile *aHdr;     /* Header in shared memory */

  /* The first page of the wal-index must be mapped at this point. */
  assert( pWal->nWiData>0 && pWal->apWiData[0] );

  /* Read the header. This might happen concurrently with a write to the
  ** same area of shared memory on a different CPU in a SMP,
  ** meaning it is possible that an inconsistent snapshot is read
  ** from the file. If this happens, return non-zero.
  **
  ** tag-20200519-1:
  ** There are two copies of the header at the beginning of the wal-index.
  ** When reading, read [0] first then [1].  Writes are in the reverse order.
  ** Memory barriers are used to prevent the compiler or the hardware from
  ** reordering the reads and writes.  TSAN and similar tools can sometimes
  ** reordering the reads and writes.
  ** give false-positive warnings about these accesses because the tools do not
  ** account for the double-read and the memory barrier. The use of mutexes
  ** here would be problematic as the memory being accessed is potentially
  ** shared among multiple processes and not all mutex implementions work
  ** reliably in that environment.
  */
  aHdr = walIndexHdr(pWal);
  memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */
  memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
  walShmBarrier(pWal);
  memcpy(&h2, (void *)&aHdr[1], sizeof(h2));

  if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
    return 1;   /* Dirty read */
  }  
  if( h1.isInit==0 ){
2325
2326
2327
2328
2329
2330
2331

2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352













2353
2354
2355


2356
2357
2358
2359
2360
2361
2362
2363
2364
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179















2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192



2193
2194


2195
2196
2197
2198
2199
2200
2201







+






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







  ** being modified by another thread or process.
  */
  badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);

  /* If the first attempt failed, it might have been due to a race
  ** with a writer.  So get a WRITE lock and try again.
  */
  assert( badHdr==0 || pWal->writeLock==0 );
  if( badHdr ){
    if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
      if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
        walUnlockShared(pWal, WAL_WRITE_LOCK);
        rc = SQLITE_READONLY_RECOVERY;
      }
    }else{
      int bWriteLock = pWal->writeLock;
      if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
        pWal->writeLock = 1;
        if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
          badHdr = walIndexTryHdr(pWal, pChanged);
          if( badHdr ){
            /* If the wal-index header is still malformed even while holding
            ** a WRITE lock, it can only mean that the header is corrupted and
            ** needs to be reconstructed.  So run recovery to do exactly that.
            */
            rc = walIndexRecover(pWal);
            *pChanged = 1;
          }
        }
    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
      pWal->writeLock = 1;
      if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
        badHdr = walIndexTryHdr(pWal, pChanged);
        if( badHdr ){
          /* If the wal-index header is still malformed even while holding
          ** a WRITE lock, it can only mean that the header is corrupted and
          ** needs to be reconstructed.  So run recovery to do exactly that.
          */
          rc = walIndexRecover(pWal);
          *pChanged = 1;
        }
      }
        if( bWriteLock==0 ){
          pWal->writeLock = 0;
          walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
      pWal->writeLock = 0;
      walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
        }
      }
    }
  }

  /* If the header is read successfully, check the version number to make
  ** sure the wal-index was not constructed with some future format that
  ** this version of SQLite cannot understand.
  */
2680
2681
2682
2683
2684
2685
2686
2687

2688
2689
2690
2691
2692
2693
2694
2517
2518
2519
2520
2521
2522
2523

2524
2525
2526
2527
2528
2529
2530
2531







-
+







      return walBeginShmUnreliable(pWal, pChanged);
    }
  }

  assert( pWal->nWiData>0 );
  assert( pWal->apWiData[0]!=0 );
  pInfo = walCkptInfo(pWal);
  if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
   && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
#endif
  ){
    /* The WAL has been completely backfilled (or it is empty).
    ** and can be safely ignored.
    */
2742
2743
2744
2745
2746
2747
2748
2749

2750
2751
2752
2753
2754
2755
2756
2757
2579
2580
2581
2582
2583
2584
2585

2586

2587
2588
2589
2590
2591
2592
2593







-
+
-







  }
  if( (pWal->readOnly & WAL_SHM_RDONLY)==0
   && (mxReadMark<mxFrame || mxI==0)
  ){
    for(i=1; i<WAL_NREADER; i++){
      rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
      if( rc==SQLITE_OK ){
        AtomicStore(pInfo->aReadMark+i,mxFrame);
        mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
        mxReadMark = mxFrame;
        mxI = i;
        walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
        break;
      }else if( rc!=SQLITE_BUSY ){
        return rc;
      }
    }
2847
2848
2849
2850
2851
2852
2853
2854

2855
2856
2857
2858
2859
2860
2861
2683
2684
2685
2686
2687
2688
2689

2690
2691
2692
2693
2694
2695
2696
2697







-
+







    if( rc==SQLITE_OK ){
      void *pBuf1 = sqlite3_malloc(szPage);
      void *pBuf2 = sqlite3_malloc(szPage);
      if( pBuf1==0 || pBuf2==0 ){
        rc = SQLITE_NOMEM;
      }else{
        u32 i = pInfo->nBackfillAttempted;
        for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){
        for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
          WalHashLoc sLoc;          /* Hash table location */
          u32 pgno;                 /* Page number in db file */
          i64 iDbOff;               /* Offset of db file entry */
          i64 iWalOff;              /* Offset of wal file entry */

          rc = walHashGet(pWal, walFramePage(i), &sLoc);
          if( rc!=SQLITE_OK ) break;
2902
2903
2904
2905
2906
2907
2908

2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919


2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748








2749
2750


















2751
2752
2753
2754
2755
2756
2757







+



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







** transaction, then *pChanged is set to 1 before returning.  The
** Pager layer will use this to know that its cache is stale and
** needs to be flushed.
*/
int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
  int rc;                         /* Return code */
  int cnt = 0;                    /* Number of TryBeginRead attempts */

#ifdef SQLITE_ENABLE_SNAPSHOT
  int bChanged = 0;
  WalIndexHdr *pSnapshot = pWal->pSnapshot;
#endif

  assert( pWal->ckptLock==0 );

#ifdef SQLITE_ENABLE_SNAPSHOT
  if( pSnapshot ){
    if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
      bChanged = 1;
  if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
    bChanged = 1;
    }

    /* It is possible that there is a checkpointer thread running 
    ** concurrent with this code. If this is the case, it may be that the
    ** checkpointer has already determined that it will checkpoint 
    ** snapshot X, where X is later in the wal file than pSnapshot, but 
    ** has not yet set the pInfo->nBackfillAttempted variable to indicate 
    ** its intent. To avoid the race condition this leads to, ensure that
    ** there is no checkpointer process by taking a shared CKPT lock 
    ** before checking pInfo->nBackfillAttempted.  */
    (void)walEnableBlocking(pWal);
    rc = walLockShared(pWal, WAL_CKPT_LOCK);
    walDisableBlocking(pWal);

    if( rc!=SQLITE_OK ){
      return rc;
    }
    pWal->ckptLock = 1;
  }
#endif

  do{
    rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
  }while( rc==WAL_RETRY );
  testcase( (rc&0xff)==SQLITE_BUSY );
2963
2964
2965
2966
2967
2968
2969















2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984















2985
2986
2987
2988
2989
2990
2991
2992





2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797















2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813







2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824







2825
2826
2827
2828
2829
2830
2831







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

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






-
-
-
-
-
-
-







      **         checkpoint need not have completed for this to cause problems.
      */
      volatile WalCkptInfo *pInfo = walCkptInfo(pWal);

      assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
      assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );

      /* It is possible that there is a checkpointer thread running 
      ** concurrent with this code. If this is the case, it may be that the
      ** checkpointer has already determined that it will checkpoint 
      ** snapshot X, where X is later in the wal file than pSnapshot, but 
      ** has not yet set the pInfo->nBackfillAttempted variable to indicate 
      ** its intent. To avoid the race condition this leads to, ensure that
      ** there is no checkpointer process by taking a shared CKPT lock 
      ** before checking pInfo->nBackfillAttempted.  
      **
      ** TODO: Does the aReadMark[] lock prevent a checkpointer from doing
      **       this already?
      */
      rc = walLockShared(pWal, WAL_CKPT_LOCK);

      if( rc==SQLITE_OK ){
      /* Check that the wal file has not been wrapped. Assuming that it has
      ** not, also check that no checkpointer has attempted to checkpoint any
      ** frames beyond pSnapshot->mxFrame. If either of these conditions are
      ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
      ** with *pSnapshot and set *pChanged as appropriate for opening the
      ** snapshot.  */
      if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
       && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
      ){
        assert( pWal->readLock>0 );
        memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
        *pChanged = bChanged;
      }else{
        rc = SQLITE_ERROR_SNAPSHOT;
      }
        /* Check that the wal file has not been wrapped. Assuming that it has
        ** not, also check that no checkpointer has attempted to checkpoint any
        ** frames beyond pSnapshot->mxFrame. If either of these conditions are
        ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
        ** with *pSnapshot and set *pChanged as appropriate for opening the
        ** snapshot.  */
        if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
         && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
        ){
          assert( pWal->readLock>0 );
          memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
          *pChanged = bChanged;
        }else{
          rc = SQLITE_ERROR_SNAPSHOT;
        }

      /* A client using a non-current snapshot may not ignore any frames
      ** from the start of the wal file. This is because, for a system
      ** where (minFrame < iSnapshot < maxFrame), a checkpointer may
      ** have omitted to checkpoint a frame earlier than minFrame in 
      ** the file because there exists a frame after iSnapshot that
      ** is the same database page.  */
      pWal->minFrame = 1;
        /* Release the shared CKPT lock obtained above. */
        walUnlockShared(pWal, WAL_CKPT_LOCK);
        pWal->minFrame = 1;
      }


      if( rc!=SQLITE_OK ){
        sqlite3WalEndReadTransaction(pWal);
      }
    }
  }

  /* Release the shared CKPT lock obtained above. */
  if( pWal->ckptLock ){
    assert( pSnapshot );
    walUnlockShared(pWal, WAL_CKPT_LOCK);
    pWal->ckptLock = 0;
  }
#endif
  return rc;
}

/*
** Finish with a read transaction.  All this does is release the
** read-lock.
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092

3093
3094
3095



3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
2897
2898
2899
2900
2901
2902
2903

2904
2905
2906
2907
2908
2909

2910



2911
2912
2913
2914
2915
2916
2917
2918
2919

2920
2921
2922
2923
2924
2925
2926







-






-
+
-
-
-
+
+
+






-







  */
  iMinHash = walFramePage(pWal->minFrame);
  for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
    WalHashLoc sLoc;              /* Hash table location */
    int iKey;                     /* Hash slot index */
    int nCollide;                 /* Number of hash collisions remaining */
    int rc;                       /* Error code */
    u32 iH;

    rc = walHashGet(pWal, iHash, &sLoc);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    nCollide = HASHTABLE_NSLOT;
    iKey = walHash(pgno);
    for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
    while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
      u32 iFrame = iH + sLoc.iZero;
      if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
      u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
      if( iFrame<=iLast && iFrame>=pWal->minFrame
       && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
        assert( iFrame>iRead || CORRUPT_DB );
        iRead = iFrame;
      }
      if( (nCollide--)==0 ){
        return SQLITE_CORRUPT_BKPT;
      }
      iKey = walNextHash(iKey);
    }
    if( iRead ) break;
  }

#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
  /* If expensive assert() statements are available, do a linear search
  ** of the wal-index file content. Make sure the results agree with the
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
2988
2989
2990
2991
2992
2993
2994










2995
2996
2997
2998
2999
3000
3001







-
-
-
-
-
-
-
-
-
-







** returns SQLITE_BUSY in that case and no write transaction is started.
**
** There can only be a single writer active at a time.
*/
int sqlite3WalBeginWriteTransaction(Wal *pWal){
  int rc;

#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
  /* If the write-lock is already held, then it was obtained before the
  ** read-transaction was even opened, making this call a no-op.
  ** Return early. */
  if( pWal->writeLock ){
    assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
    return SQLITE_OK;
  }
#endif

  /* Cannot start a write transaction without first holding a read
  ** transaction. */
  assert( pWal->readLock>=0 );
  assert( pWal->writeLock==0 && pWal->iReCksum==0 );

  if( pWal->readOnly ){
    return SQLITE_READONLY;
3426
3427
3428
3429
3430
3431
3432



3433

3434
3435
3436
3437
3438
3439
3440
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251







+
+
+

+







  PgHdr *pPage,               /* The page of the frame to be written */
  int nTruncate,              /* The commit flag.  Usually 0.  >0 for commit */
  sqlite3_int64 iOffset       /* Byte offset at which to write */
){
  int rc;                         /* Result code from subfunctions */
  void *pData;                    /* Data actually written */
  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
#if defined(SQLITE_HAS_CODEC)
  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;
#else
  pData = pPage->pData;
#endif
  walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
  rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
  if( rc ) return rc;
  /* Write the page data */
  rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
  return rc;
}
3609
3610
3611
3612
3613
3614
3615



3616

3617
3618
3619
3620
3621
3622
3623
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438







+
+
+

+







      assert( rc==SQLITE_OK || iWrite==0 );
      if( iWrite>=iFirst ){
        i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
        void *pData;
        if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
          pWal->iReCksum = iWrite;
        }
#if defined(SQLITE_HAS_CODEC)
        if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM;
#else
        pData = p->pData;
#endif
        rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff);
        if( rc ) return rc;
        p->flags &= ~PGHDR_WAL_APPEND;
        continue;
      }
    }

3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3474
3475
3476
3477
3478
3479
3480

3481
3482
3483
3484
3485
3486
3487







-







      bSync = (w.iSyncPoint==iOffset);
      testcase( bSync );
      while( iOffset<w.iSyncPoint ){
        rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
        if( rc ) return rc;
        iOffset += szFrame;
        nExtra++;
        assert( pLast!=0 );
      }
    }
    if( bSync ){
      assert( rc==SQLITE_OK );
      rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags));
    }
  }
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3506
3507
3508
3509
3510
3511
3512

3513
3514
3515
3516
3517
3518
3519







-







  */
  iFrame = pWal->hdr.mxFrame;
  for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
    if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue;
    iFrame++;
    rc = walIndexAppend(pWal, iFrame, p->pgno);
  }
  assert( pLast!=0 || nExtra==0 );
  while( rc==SQLITE_OK && nExtra>0 ){
    iFrame++;
    nExtra--;
    rc = walIndexAppend(pWal, iFrame, pLast->pgno);
  }

  if( rc==SQLITE_OK ){
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776









3777
3778
3779
3780
3781





3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802




















3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
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







-
-
-
-
-

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

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


-

-







  /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
  ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
  assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );

  if( pWal->readOnly ) return SQLITE_READONLY;
  WALTRACE(("WAL%p: checkpoint begins\n", pWal));

  /* Enable blocking locks, if possible. If blocking locks are successfully
  ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
  sqlite3WalDb(pWal, db);
  (void)walEnableBlocking(pWal);

  /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive 
  ** "checkpoint" lock on the database file.
  ** EVIDENCE-OF: R-10421-19736 If any other process is running a
  ** checkpoint operation at the same time, the lock cannot be obtained and
  ** SQLITE_BUSY is returned.
  ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
  ** it will not be invoked in this case.
  */
  ** "checkpoint" lock on the database file. */
  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
  if( rc ){
    /* EVIDENCE-OF: R-10421-19736 If any other process is running a
    ** checkpoint operation at the same time, the lock cannot be obtained and
    ** SQLITE_BUSY is returned.
    ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
    ** it will not be invoked in this case.
    */
  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
  testcase( rc==SQLITE_BUSY );
  testcase( rc!=SQLITE_OK && xBusy2!=0 );
  if( rc==SQLITE_OK ){
    pWal->ckptLock = 1;
    testcase( rc==SQLITE_BUSY );
    testcase( xBusy!=0 );
    return rc;
  }
  pWal->ckptLock = 1;

    /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
    ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
    ** file.
    **
    ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
    ** immediately, and a busy-handler is configured, it is invoked and the
    ** writer lock retried until either the busy-handler returns 0 or the
    ** lock is successfully obtained.
    */
    if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
      rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
      if( rc==SQLITE_OK ){
        pWal->writeLock = 1;
      }else if( rc==SQLITE_BUSY ){
        eMode2 = SQLITE_CHECKPOINT_PASSIVE;
        xBusy2 = 0;
        rc = SQLITE_OK;
      }
    }
  }
  /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
  ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
  ** file.
  **
  ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
  ** immediately, and a busy-handler is configured, it is invoked and the
  ** writer lock retried until either the busy-handler returns 0 or the
  ** lock is successfully obtained.
  */
  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
    rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
    if( rc==SQLITE_OK ){
      pWal->writeLock = 1;
    }else if( rc==SQLITE_BUSY ){
      eMode2 = SQLITE_CHECKPOINT_PASSIVE;
      xBusy2 = 0;
      rc = SQLITE_OK;
    }
  }



  /* Read the wal-index header. */
  if( rc==SQLITE_OK ){
    walDisableBlocking(pWal);
    rc = walIndexReadHdr(pWal, &isChanged);
    (void)walEnableBlocking(pWal);
    if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
      sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
    }
  }

  /* Copy data from the log to the database file. */
  if( rc==SQLITE_OK ){
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
3640
3641
3642
3643
3644
3645
3646



3647
3648



3649
3650

3651



3652
3653
3654
3655
3656
3657
3658







-
-
-


-
-
-
+
+
-

-
-
-







    ** out of date. So zero the cached wal-index header to ensure that
    ** next time the pager opens a snapshot on this database it knows that
    ** the cache needs to be reset.
    */
    memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
  }

  walDisableBlocking(pWal);
  sqlite3WalDb(pWal, 0);

  /* Release the locks. */
  sqlite3WalEndWriteTransaction(pWal);
  if( pWal->ckptLock ){
    walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
    pWal->ckptLock = 0;
  walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
  pWal->ckptLock = 0;
  }
  WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
  if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif
  return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
}

/* Return the value to pass to a sqlite3_wal_hook callback, the
** number of frames in the WAL at the point of the last commit since
** sqlite3WalCallback() was called.  If no commits have occurred since
** the last call, then return 0.
3963
3964
3965
3966
3967
3968
3969
3970

3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3761
3762
3763
3764
3765
3766
3767

3768



3769
3770
3771
3772
3773
3774
3775







-
+
-
-
-







  }

  return rc;
}

/* Try to open on pSnapshot when the next read-transaction starts
*/
void sqlite3WalSnapshotOpen(
void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
  Wal *pWal, 
  sqlite3_snapshot *pSnapshot
){
  pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
}

/* 
** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
*/

Changes to src/wal.h.

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





149
150







-
-
-
-
-


*/
int sqlite3WalFramesize(Wal *pWal);
#endif

/* Return the sqlite3_file object for the WAL file */
sqlite3_file *sqlite3WalFile(Wal *pWal);

#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
int sqlite3WalWriteLock(Wal *pWal, int bLock);
void sqlite3WalDb(Wal *pWal, sqlite3 *db);
#endif

#endif /* ifndef SQLITE_OMIT_WAL */
#endif /* SQLITE_WAL_H */

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
51
18
19
20
21
22
23
24

25
26
27


28


29


30











31
32
33
34
35
36
37







-
+


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









#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){
static int walkWindowList(Walker *pWalker, Window *pList){
  Window *pWin;
  for(pWin=pList; pWin; pWin=pWin->pNextWin){
    int rc;
    rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy);
    if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
    if( rc ) return WRC_Abort;
    rc = sqlite3WalkExprList(pWalker, pWin->pPartition);
    if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
    if( rc ) return WRC_Abort;
    rc = sqlite3WalkExpr(pWalker, pWin->pFilter);
    if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
    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
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
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







-

+

-



-

-
-
-
-
+
+
+

-
-
-
+
+
+

-







  int rc;
  testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
  testcase( ExprHasProperty(pExpr, EP_Reduced) );
  while(1){
    rc = pWalker->xExprCallback(pWalker, pExpr);
    if( rc ) return rc & WRC_Abort;
    if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
      assert( pExpr->x.pList==0 || pExpr->pRight==0 );
      if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
       assert( pExpr->x.pList==0 || pExpr->pRight==0 );
      if( pExpr->pRight ){
        assert( !ExprHasProperty(pExpr, EP_WinFunc) );
        pExpr = pExpr->pRight;
        continue;
      }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        assert( !ExprHasProperty(pExpr, EP_WinFunc) );
        if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
      }else{
        if( pExpr->x.pList ){
          if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) 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;
        }
      if( ExprHasProperty(pExpr, EP_WinFunc) ){
        if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort;
      }
#endif
      }
    }
    break;
  }
  return WRC_Continue;
}
int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
  return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue;
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
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







-
-
-
+
+

















-
+


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







  if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
  if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
  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);
      int rc = walkWindowList(pWalker, p->pWinDefn);
      assert( rc==WRC_Continue );
      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;
  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;
      }
      if( pItem->fg.isTabFunc
       && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
      ){
        return WRC_Abort;
  assert( pSrc!=0 );
  for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
    if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
      return WRC_Abort;
    }
    if( pItem->fg.isTabFunc
     && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
    ){
      return WRC_Abort;
      }
    }
  }
  return WRC_Continue;
} 

/*
** Call sqlite3WalkExpr() for every expression in Select statement p.
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
184
185
186
187
188
189
190












































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    if( pWalker->xSelectCallback2 ){
      pWalker->xSelectCallback2(pWalker, p);
    }
    p = p->pPrior;
  }while( p!=0 );
  return WRC_Continue;
}

/* Increase the walkerDepth when entering a subquery, and
** descrease when leaving the subquery.
*/
int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){
  UNUSED_PARAMETER(pSelect);
  pWalker->walkerDepth++;
  return WRC_Continue;
}
void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){
  UNUSED_PARAMETER(pSelect);
  pWalker->walkerDepth--;
}


/*
** No-op routine for the parse-tree walker.
**
** When this routine is the Walker.xExprCallback then expression trees
** are walked without any actions being taken at each node.  Presumably,
** when this routine is used for Walker.xExprCallback then 
** Walker.xSelectCallback is set to do something useful for every 
** subquery in the parser tree.
*/
int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  return WRC_Continue;
}

/*
** No-op routine for the parse-tree walker for SELECT statements.
** subquery in the parser tree.
*/
int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  return WRC_Continue;
}

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
52
53
54
55
56
57


58
59
60
61
62
63
64
65
66
67
68
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







+
+
+
+
+
+

















-
-
+
+
-
-
-
-







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

/*
** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this
** WHERE clause returns outputs for DISTINCT processing.
*/
int sqlite3WhereIsDistinct(WhereInfo *pWInfo){
  return pWInfo->eDistinct;
}

/*
** Return the number of ORDER BY terms that are satisfied by the
** WHERE clause.  A return of 0 means that the output must be
** Return TRUE if the WHERE clause returns rows in ORDER BY order.
** Return FALSE if the output needs to be sorted.
** completely sorted.  A return equal to the number of ORDER BY
** terms means that no sorting is needed at all.  A return that
** is positive but less than the number of ORDER BY terms means that
** block sorting is required.
*/
int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
  return pWInfo->nOBSat;
}

/*
** In the ORDER BY LIMIT optimization, if the inner-most loop is known
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
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







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



















-
+







    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 );
  return pWInfo->iContinue;
}

/*
** Return the VDBE address or label to jump to in order to break
** out of a WHERE loop.
*/
int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
  return pWInfo->iBreak;
}

/*
** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to
** operate directly on the rowids returned by a WHERE clause.  Return
** operate directly on the rowis returned by a WHERE clause.  Return
** ONEPASS_SINGLE (1) if the statement can operation directly because only
** a single row is to be changed.  Return ONEPASS_MULTI (2) if the one-pass
** optimization can be used on multiple 
**
** If the ONEPASS optimization is used (if this routine returns true)
** then also write the indices of open cursors used by ONEPASS
** into aiCur[0] and aiCur[1].  iaCur[0] gets the cursor of the data
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
143
144
145
146
147
148
149








150
151
152
153
154
155
156







-
-
-
-
-
-
-
-







         pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI",
         aiCur[0], aiCur[1]);
  }
#endif
  return pWInfo->eOnePass;
}

/*
** Return TRUE if the WHERE loop uses the OP_DeferredSeek opcode to move
** the data cursor to the row selected by the index cursor.
*/
int sqlite3WhereUsesDeferredSeek(WhereInfo *pWInfo){
  return pWInfo->bDeferredSeek;
}

/*
** Move the content of pSrc into pDest
*/
static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
  pDest->n = pSrc->n;
  memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
}
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
219
220
221
222
223
224
225










226
227
228
229
230
231
232







-
-
-
-
-
-
-
-
-
-







** array will never overflow.
*/
static void createMask(WhereMaskSet *pMaskSet, int iCursor){
  assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
  pMaskSet->ix[pMaskSet->n++] = iCursor;
}

/*
** If the right-hand branch of the expression is a TK_COLUMN, then return
** a pointer to the right-hand branch.  Otherwise, return NULL.
*/
static Expr *whereRightSubexprIsColumn(Expr *p){
  p = sqlite3ExprSkipCollateAndLikely(p->pRight);
  if( ALWAYS(p!=0) && p->op==TK_COLUMN ) return p;
  return 0;
}

/*
** Advance to the next WhereTerm that matches according to the criteria
** established when the pScan object was initialized by whereScanInit().
** Return NULL if there are no more matching WhereTerms.
*/
static WhereTerm *whereScanNext(WhereScan *pScan){
  int iCur;            /* The cursor on the LHS of the term */
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263







-
+







-
+







  while(1){
    iColumn = pScan->aiColumn[pScan->iEquiv-1];
    iCur = pScan->aiCur[pScan->iEquiv-1];
    assert( pWC!=0 );
    do{
      for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
        if( pTerm->leftCursor==iCur
         && pTerm->u.x.leftColumn==iColumn
         && pTerm->u.leftColumn==iColumn
         && (iColumn!=XN_EXPR
             || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
                                       pScan->pIdxExpr,iCur)==0)
         && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
        ){
          if( (pTerm->eOperator & WO_EQUIV)!=0
           && pScan->nEquiv<ArraySize(pScan->aiCur)
           && (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0
           && (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN
          ){
            int j;
            for(j=0; j<pScan->nEquiv; j++){
              if( pScan->aiCur[j]==pX->iTable
               && pScan->aiColumn[j]==pX->iColumn ){
                  break;
              }
316
317
318
319
320
321
322
323


324
325
326
327
328
329
330
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289







-
+
+







              CollSeq *pColl;
              Parse *pParse = pWC->pWInfo->pParse;
              pX = pTerm->pExpr;
              if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
                continue;
              }
              assert(pX->pLeft);
              pColl = sqlite3ExprCompareCollSeq(pParse, pX);
              pColl = sqlite3BinaryCompareCollSeq(pParse,
                                                  pX->pLeft, pX->pRight);
              if( pColl==0 ) pColl = pParse->db->pDfltColl;
              if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
                continue;
              }
            }
            if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
             && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
486
487
488
489
490
491
492
493

494
495

496
497
498
499
500
501
502
445
446
447
448
449
450
451

452


453
454
455
456
457
458
459
460







-
+
-
-
+







  Index *pIdx,                    /* Index to match column of */
  int iCol                        /* Column of index to match */
){
  int i;
  const char *zColl = pIdx->azColl[iCol];

  for(i=0; i<pList->nExpr; i++){
    Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr);
    Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
    if( ALWAYS(p!=0)
     && p->op==TK_COLUMN
    if( p->op==TK_COLUMN
     && p->iColumn==pIdx->aiColumn[iCol]
     && p->iTable==iBase
    ){
      CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr);
      if( 0==sqlite3StrICmp(pColl->zName, zColl) ){
        return i;
      }
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
566
509
510
511
512
513
514
515

516

517
518
519
520
521
522
523







-
+
-







  pTab = pTabList->a[0].pTab;

  /* If any of the expressions is an IPK column on table iBase, then return 
  ** true. Note: The (p->iTable==iBase) part of this test may be false if the
  ** current SELECT is a correlated sub-query.
  */
  for(i=0; i<pDistinct->nExpr; i++){
    Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr);
    Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
    if( NEVER(p==0) ) continue;
    if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
  }

  /* Loop through all indices on the table, checking each to see if it makes
  ** the DISTINCT qualifier redundant. It does so if:
  **
  **   1. The index is itself UNIQUE, and
601
602
603
604
605
606
607
608
609
610
611




612
613
614
615
616
617
618

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





635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686


687
688
689
690
691
692
693
694
695
696
697

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


715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731

732
733
734
735
736
737
738
558
559
560
561
562
563
564




565
566
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
582
583
584
585
586
587
588



589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643


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

656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671


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

690
691
692
693
694
695
696
697







-
-
-
-
+
+
+
+






-
+













-
-
-
+
+
+
+
+
















-
+

















-
+















-
-
+
+










-
+















-
-
+
+
















-
+







/*
** Convert OP_Column opcodes to OP_Copy in previously generated code.
**
** This routine runs over generated VDBE code and translates OP_Column
** opcodes into OP_Copy when the table is being accessed via co-routine 
** instead of via table lookup.
**
** If the iAutoidxCur is not zero, then any OP_Rowid instructions on
** cursor iTabCur are transformed into OP_Sequence opcode for the
** iAutoidxCur cursor, in order to generate unique rowids for the
** automatic index being generated.
** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
** then each OP_Rowid is transformed into an instruction to increment the
** value stored in its output register.
*/
static void translateColumnToCopy(
  Parse *pParse,      /* Parsing context */
  int iStart,         /* Translate from this opcode to the end */
  int iTabCur,        /* OP_Column/OP_Rowid references to this table */
  int iRegister,      /* The first column is in this register */
  int iAutoidxCur     /* If non-zero, cursor of autoindex being generated */
  int bIncrRowid      /* If non-zero, transform OP_rowid to OP_AddImm(1) */
){
  Vdbe *v = pParse->pVdbe;
  VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
  int iEnd = sqlite3VdbeCurrentAddr(v);
  if( pParse->db->mallocFailed ) return;
  for(; iStart<iEnd; iStart++, pOp++){
    if( pOp->p1!=iTabCur ) continue;
    if( pOp->opcode==OP_Column ){
      pOp->opcode = OP_Copy;
      pOp->p1 = pOp->p2 + iRegister;
      pOp->p2 = pOp->p3;
      pOp->p3 = 0;
    }else if( pOp->opcode==OP_Rowid ){
      if( iAutoidxCur ){
        pOp->opcode = OP_Sequence;
        pOp->p1 = iAutoidxCur;
      if( bIncrRowid ){
        /* Increment the value stored in the P2 operand of the OP_Rowid. */
        pOp->opcode = OP_AddImm;
        pOp->p1 = pOp->p2;
        pOp->p2 = 1;
      }else{
        pOp->opcode = OP_Null;
        pOp->p1 = 0;
        pOp->p3 = 0;
      }
    }
  }
}

/*
** Two routines for printing the content of an sqlite3_index_info
** structure.  Used for testing and debugging only.  If neither
** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
** are no-ops.
*/
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED)
static void whereTraceIndexInfoInputs(sqlite3_index_info *p){
static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
  int i;
  if( !sqlite3WhereTrace ) return;
  for(i=0; i<p->nConstraint; i++){
    sqlite3DebugPrintf("  constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",
       i,
       p->aConstraint[i].iColumn,
       p->aConstraint[i].iTermOffset,
       p->aConstraint[i].op,
       p->aConstraint[i].usable);
  }
  for(i=0; i<p->nOrderBy; i++){
    sqlite3DebugPrintf("  orderby[%d]: col=%d desc=%d\n",
       i,
       p->aOrderBy[i].iColumn,
       p->aOrderBy[i].desc);
  }
}
static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){
static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){
  int i;
  if( !sqlite3WhereTrace ) return;
  for(i=0; i<p->nConstraint; i++){
    sqlite3DebugPrintf("  usage[%d]: argvIdx=%d omit=%d\n",
       i,
       p->aConstraintUsage[i].argvIndex,
       p->aConstraintUsage[i].omit);
  }
  sqlite3DebugPrintf("  idxNum=%d\n", p->idxNum);
  sqlite3DebugPrintf("  idxStr=%s\n", p->idxStr);
  sqlite3DebugPrintf("  orderByConsumed=%d\n", p->orderByConsumed);
  sqlite3DebugPrintf("  estimatedCost=%g\n", p->estimatedCost);
  sqlite3DebugPrintf("  estimatedRows=%lld\n", p->estimatedRows);
}
#else
#define whereTraceIndexInfoInputs(A)
#define whereTraceIndexInfoOutputs(A)
#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
** 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 */
  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)
   && (pTerm->eOperator & WO_IS)
  ){
    /* Cannot use an IS term from the WHERE clause as an index driver for
    ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
    ** the ON clause.  */
    return 0;
  }
  if( (pTerm->prereqRight & notReady)!=0 ) return 0;
  if( pTerm->u.x.leftColumn<0 ) return 0;
  aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
  if( pTerm->u.leftColumn<0 ) return 0;
  aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
  if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
  testcase( pTerm->pExpr->op==TK_IS );
  return 1;
}
#endif


#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
** 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 */
  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 */
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721







-
+







  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 */
  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 );
774
775
776
777
778
779
780
781

782
783
784
785

786
787
788
789
790
791
792
733
734
735
736
737
738
739

740
741
742
743

744
745
746
747
748
749
750
751







-
+



-
+







    assert( !ExprHasProperty(pExpr, EP_FromJoin)    /* prereq always non-zero */
         || pExpr->iRightJoinTable!=pSrc->iCursor   /*   for the right-hand   */
         || pLoop->prereq!=0 );                     /*   table of a LEFT JOIN */
    if( pLoop->prereq==0
     && (pTerm->wtFlags & TERM_VIRTUAL)==0
     && !ExprHasProperty(pExpr, EP_FromJoin)
     && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
      pPartial = sqlite3ExprAnd(pParse, pPartial,
      pPartial = sqlite3ExprAnd(pParse->db, pPartial,
                                sqlite3ExprDup(pParse->db, pExpr, 0));
    }
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      int iCol = pTerm->u.x.leftColumn;
      int iCol = pTerm->u.leftColumn;
      Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
      testcase( iCol==BMS );
      testcase( iCol==BMS-1 );
      if( !sentWarning ){
        sqlite3_log(SQLITE_WARNING_AUTOINDEX,
            "automatic index on %s(%s)", pTable->zName,
            pTable->aCol[iCol].zName);
831
832
833
834
835
836
837
838

839
840
841
842
843
844
845
846


847
848
849
850
851
852
853
854
790
791
792
793
794
795
796

797
798
799
800
801
802
803


804
805

806
807
808
809
810
811
812







-
+






-
-
+
+
-







  pLoop->u.btree.pIndex = pIdx;
  pIdx->zName = "auto-index";
  pIdx->pTable = pTable;
  n = 0;
  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      int iCol = pTerm->u.x.leftColumn;
      int iCol = pTerm->u.leftColumn;
      Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
      testcase( iCol==BMS-1 );
      testcase( iCol==BMS );
      if( (idxCols & cMask)==0 ){
        Expr *pX = pTerm->pExpr;
        idxCols |= cMask;
        pIdx->aiColumn[n] = pTerm->u.x.leftColumn;
        pColl = sqlite3ExprCompareCollSeq(pParse, pX);
        pIdx->aiColumn[n] = pTerm->u.leftColumn;
        pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
        assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */
        pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
        n++;
      }
    }
  }
  assert( (u32)n==pLoop->u.btree.nEq );

902
903
904
905
906
907
908
909
910
911

912
913
914
915
916
917

918
919
920
921
922
923
924
860
861
862
863
864
865
866

867

868
869
870
871
872

873
874
875
876
877
878
879
880
881







-

-
+




-

+







  );
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
  if( pTabItem->fg.viaCoroutine ){
    sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
    testcase( pParse->db->mallocFailed );
    assert( pLevel->iIdxCur>0 );
    translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
                          pTabItem->regResult, pLevel->iIdxCur);
                          pTabItem->regResult, 1);
    sqlite3VdbeGoto(v, addrTop);
    pTabItem->fg.viaCoroutine = 0;
  }else{
    sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
    sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  }
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  
  /* Jump here when skipping the initialization */
  sqlite3VdbeJumpHere(v, addrInit);

end_auto_index_create:
932
933
934
935
936
937
938
939

940
941
942
943
944
945
946
889
890
891
892
893
894
895

896
897
898
899
900
901
902
903







-
+







** 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 */
  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;
959
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995






996
997
998
999

1000
1001
1002
1003






1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022

1023








1024
1025
1026
1027


1028
1029
1030
1031
1032
1033
1034
916
917
918
919
920
921
922

923
924
925
926
927
928
929
930
931
932
933
934
935
936

937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962




963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981




982
983
984
985
986
987
988
989
990
991
992
993
994
995


996
997
998
999
1000
1001
1002
1003
1004







-
+













-















+
+
+
+
+
+




+
-
-
-
-
+
+
+
+
+
+













-
-
-
-


+

+
+
+
+
+
+
+
+


-
-
+
+







    assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
    testcase( pTerm->eOperator & WO_IN );
    testcase( pTerm->eOperator & WO_ISNULL );
    testcase( pTerm->eOperator & WO_IS );
    testcase( pTerm->eOperator & WO_ALL );
    if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
    if( pTerm->wtFlags & TERM_VNULL ) continue;
    assert( pTerm->u.x.leftColumn>=(-1) );
    assert( pTerm->u.leftColumn>=(-1) );
    nTerm++;
  }

  /* If the ORDER BY clause contains only columns in the current 
  ** virtual table then allocate space for the aOrderBy part of
  ** the sqlite3_index_info structure.
  */
  nOrderBy = 0;
  if( pOrderBy ){
    int n = pOrderBy->nExpr;
    for(i=0; i<n; i++){
      Expr *pExpr = pOrderBy->a[i].pExpr;
      if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
      if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break;
    }
    if( i==n){
      nOrderBy = n;
    }
  }

  /* Allocate the sqlite3_index_info structure
  */
  pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
                           + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
                           + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
  if( pIdxInfo==0 ){
    sqlite3ErrorMsg(pParse, "out of memory");
    return 0;
  }

  /* Initialize the structure.  The sqlite3_index_info structure contains
  ** many fields that are declared "const" to prevent xBestIndex from
  ** changing them.  We have to do some funky casting in order to
  ** initialize those fields.
  */
  pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
  pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
  pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
  pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
  *(int*)&pIdxInfo->nConstraint = nTerm;
  pIdxInfo->nOrderBy = nOrderBy;
  pIdxInfo->aConstraint = pIdxCons;
  pIdxInfo->aOrderBy = pIdxOrderBy;
  pIdxInfo->aConstraintUsage = pUsage;
  *(int*)&pIdxInfo->nOrderBy = nOrderBy;
  *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons;
  *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
  *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
                                                                   pUsage;

  pHidden->pWC = pWC;
  pHidden->pParse = pParse;
  for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
    u16 op;
    if( pTerm->leftCursor != pSrc->iCursor ) continue;
    if( pTerm->prereqRight & mUnusable ) continue;
    assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
    testcase( pTerm->eOperator & WO_IN );
    testcase( pTerm->eOperator & WO_IS );
    testcase( pTerm->eOperator & WO_ISNULL );
    testcase( pTerm->eOperator & WO_ALL );
    if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
    if( pTerm->wtFlags & TERM_VNULL ) continue;

    /* tag-20191211-002: WHERE-clause constraints are not useful to the
    ** right-hand table of a LEFT JOIN.  See tag-20191211-001 for the
    ** equivalent restriction for ordinary tables. */
    if( (pSrc->fg.jointype & JT_LEFT)!=0
     && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
     && (pTerm->eOperator & (WO_IS|WO_ISNULL))
    ){
      /* An "IS" term in the WHERE clause where the virtual table is the rhs
      ** of a LEFT JOIN. Do not pass this term to the virtual table
      ** implementation, as this can lead to incorrect results from SQL such
      ** as:
      **
      **   "LEFT JOIN vtab WHERE vtab.col IS NULL"  */
      testcase( pTerm->eOperator & WO_ISNULL );
      testcase( pTerm->eOperator & WO_IS );
      continue;
    }
    assert( pTerm->u.x.leftColumn>=(-1) );
    pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
    assert( pTerm->u.leftColumn>=(-1) );
    pIdxCons[j].iColumn = pTerm->u.leftColumn;
    pIdxCons[j].iTermOffset = i;
    op = pTerm->eOperator & WO_ALL;
    if( op==WO_IN ) op = WO_EQ;
    if( op==WO_AUX ){
      pIdxCons[j].op = pTerm->eMatchOp;
    }else if( op & (WO_ISNULL|WO_IS) ){
      if( op==WO_ISNULL ){
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
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







-
-
+







-



-
+







      assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
      assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
      assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) );

      if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
       && sqlite3ExprIsVector(pTerm->pExpr->pRight) 
      ){
        testcase( j!=i );
        if( j<16 ) mNoOmit |= (1 << j);
        if( i<16 ) mNoOmit |= (1 << i);
        if( op==WO_LT ) pIdxCons[j].op = WO_LE;
        if( op==WO_GT ) pIdxCons[j].op = WO_GE;
      }
    }

    j++;
  }
  pIdxInfo->nConstraint = j;
  for(i=0; i<nOrderBy; i++){
    Expr *pExpr = pOrderBy->a[i].pExpr;
    pIdxOrderBy[i].iColumn = pExpr->iColumn;
    pIdxOrderBy[i].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC;
    pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
  }

  *pmNoOmit = mNoOmit;
  return pIdxInfo;
}

/*
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
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







-
+

-
+
















-
+







** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
** that this is required.
*/
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
  sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
  int rc;

  whereTraceIndexInfoInputs(p);
  TRACE_IDX_INPUTS(p);
  rc = pVtab->pModule->xBestIndex(pVtab, p);
  whereTraceIndexInfoOutputs(p);
  TRACE_IDX_OUTPUTS(p);

  if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
    if( rc==SQLITE_NOMEM ){
      sqlite3OomFault(pParse->db);
    }else if( !pVtab->zErrMsg ){
      sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
    }else{
      sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
    }
  }
  sqlite3_free(pVtab->zErrMsg);
  pVtab->zErrMsg = 0;
  return rc;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the location of a particular key among all keys in an
** index.  Store the results in aStat as follows:
**
**    aStat[0]      Est. number of rows less than pRec
**    aStat[1]      Est. number of rows equal to pRec
**
1299
1300
1301
1302
1303
1304
1305
1306

1307
1308
1309
1310
1311
1312
1313
1267
1268
1269
1270
1271
1272
1273

1274
1275
1276
1277
1278
1279
1280
1281







-
+







    aStat[1] = pIdx->aAvgEq[nField-1];
  }

  /* Restore the pRec->nField value before returning.  */
  pRec->nField = nField;
  return i;
}
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

/*
** If it is not NULL, pTerm is a term that provides an upper or lower
** bound on a range scan. Without considering pTerm, it is estimated 
** that the scan will visit nNew rows. This function returns the number
** estimated to be visited after taking pTerm into account.
**
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
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







-
+








-





-
+







      nRet -= 20;        assert( 20==sqlite3LogEst(4) );
    }
  }
  return nRet;
}


#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Return the affinity for a single column of an index.
*/
char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
  assert( iCol>=0 && iCol<pIdx->nColumn );
  if( !pIdx->zColAff ){
    if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
  }
  assert( pIdx->zColAff[iCol]!=0 );
  return pIdx->zColAff[iCol];
}
#endif


#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* 
** This function is called to estimate the number of rows visited by a
** range-scan on a skip-scan index. For example:
**
**   CREATE INDEX i1 ON t1(a, b, c);
**   SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?;
**
1446
1447
1448
1449
1450
1451
1452
1453

1454
1455
1456
1457
1458
1459
1460
1413
1414
1415
1416
1417
1418
1419

1420
1421
1422
1423
1424
1425
1426
1427







-
+








  sqlite3ValueFree(p1);
  sqlite3ValueFree(p2);
  sqlite3ValueFree(pVal);

  return rc;
}
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

/*
** This function is used to estimate the number of rows that will be visited
** by scanning an index for a range of values. The range may have an upper
** bound, a lower bound, or both. The WHERE clause terms that set the upper
** and lower bounds are represented by pLower and pUpper respectively. For
** example, assuming that index p is on t1(a):
1499
1500
1501
1502
1503
1504
1505
1506

1507
1508
1509
1510
1511


1512
1513
1514
1515
1516
1517
1518
1466
1467
1468
1469
1470
1471
1472

1473
1474
1475
1476


1477
1478
1479
1480
1481
1482
1483
1484
1485







-
+



-
-
+
+







  WhereTerm *pUpper,   /* Upper bound on the range. ex: "x<455" Might be NULL */
  WhereLoop *pLoop     /* Modify the .nOut and maybe .rRun fields */
){
  int rc = SQLITE_OK;
  int nOut = pLoop->nOut;
  LogEst nNew;

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  Index *p = pLoop->u.btree.pIndex;
  int nEq = pLoop->u.btree.nEq;

  if( p->nSample>0 && ALWAYS(nEq<p->nSampleCol)
   && OptimizationEnabled(pParse->db, SQLITE_Stat4)
  if( p->nSample>0 && nEq<p->nSampleCol
   && OptimizationEnabled(pParse->db, SQLITE_Stat34)
  ){
    if( nEq==pBuilder->nRecValid ){
      UnpackedRecord *pRec = pBuilder->pRec;
      tRowcnt a[2];
      int nBtm = pLoop->u.btree.nBtm;
      int nTop = pLoop->u.btree.nTop;

1602
1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1569
1570
1571
1572
1573
1574
1575

1576
1577
1578
1579
1580
1581
1582
1583







-
+







      pBuilder->pRec = pRec;
      if( rc==SQLITE_OK ){
        if( iUpper>iLower ){
          nNew = sqlite3LogEst(iUpper - iLower);
          /* TUNING:  If both iUpper and iLower are derived from the same
          ** sample, then assume they are 4x more selective.  This brings
          ** the estimated selectivity more in line with what it would be
          ** if estimated without the use of STAT4 tables. */
          ** if estimated without the use of STAT3/4 tables. */
          if( iLwrIdx==iUprIdx ) nNew -= 20;  assert( 20==sqlite3LogEst(4) );
        }else{
          nNew = 10;        assert( 10==sqlite3LogEst(2) );
        }
        if( nNew<nOut ){
          nOut = nNew;
        }
1651
1652
1653
1654
1655
1656
1657
1658

1659
1660
1661
1662
1663

1664
1665
1666
1667
1668
1669
1670
1618
1619
1620
1621
1622
1623
1624

1625
1626
1627
1628
1629

1630
1631
1632
1633
1634
1635
1636
1637







-
+




-
+







                    pLoop->nOut, nOut));
  }
#endif
  pLoop->nOut = (LogEst)nOut;
  return rc;
}

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in
** the histogram data.  This only works when x is the left-most
** column of an index and sqlite_stat4 histogram data is available
** column of an index and sqlite_stat3 histogram data is available
** for that index.  When pExpr==NULL that means the constraint is
** "x IS NULL" instead of "x=VALUE".
**
** Write the estimated row count into *pnRow and return SQLITE_OK. 
** If unable to make an estimate, leave *pnRow unchanged and return
** non-zero.
**
1714
1715
1716
1717
1718
1719
1720
1721

1722
1723

1724
1725
1726
1727
1728
1729
1730
1681
1682
1683
1684
1685
1686
1687

1688
1689

1690
1691
1692
1693
1694
1695
1696
1697







-
+

-
+







  whereKeyStats(pParse, p, pRec, 0, a);
  WHERETRACE(0x10,("equality scan regions %s(%d): %d\n",
                   p->zName, nEq-1, (int)a[1]));
  *pnRow = a[1];
  
  return rc;
}
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an IN constraint where the right-hand side of the IN operator
** is a list of values.  Example:
**
**        WHERE x IN (1,2,3,4)
**
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
1730
1731
1732
1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743

1744
1745
1746
1747

1748
1749

1750
1751
1752
1753

1754
1755

1756
1757

1758
1759
1760
1761
1762
1763


1764
1765





1766




1767
1768
1769


1770
1771

1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783

1784
1785
1786
1787
1788
1789
1790
1791
1792

1793
1794
1795

1796
1797
1798
1799
1800
1801
1802
1803







-
+






-
+



-
+

-
+



-


-
+

-
+





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

-












-
+








-
+


-
+







    if( nRowEst > nRow0 ) nRowEst = nRow0;
    *pnRow = nRowEst;
    WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst));
  }
  assert( pBuilder->nRecValid==nRecValid );
  return rc;
}
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */


#ifdef WHERETRACE_ENABLED
/*
** Print the content of a WhereTerm object
*/
void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
static void whereTermPrint(WhereTerm *pTerm, int iTerm){
  if( pTerm==0 ){
    sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
  }else{
    char zType[8];
    char zType[4];
    char zLeft[50];
    memcpy(zType, "....", 5);
    memcpy(zType, "...", 4);
    if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
    if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
    if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
    if( pTerm->wtFlags & TERM_CODED  ) zType[3] = 'C';
    if( pTerm->eOperator & WO_SINGLE ){
      sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
                       pTerm->leftCursor, pTerm->u.x.leftColumn);
                       pTerm->leftCursor, pTerm->u.leftColumn);
    }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
      sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", 
      sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", 
                       pTerm->u.pOrInfo->indexable);
    }else{
      sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
    }
    sqlite3DebugPrintf(
       "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x",
       iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags);
       "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x",
       iTerm, pTerm, zType, zLeft, pTerm->truthProb,
    /* The 0x10000 .wheretrace flag causes extra information to be
    ** shown about each Term */
    if( sqlite3WhereTrace & 0x10000 ){
      sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
        pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight);
       pTerm->eOperator, pTerm->wtFlags);
    }
    if( pTerm->u.x.iField ){
      sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField);
    }
    if( pTerm->iField ){
      sqlite3DebugPrintf(" iField=%d\n", pTerm->iField);
    }else{
    if( pTerm->iParent>=0 ){
      sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
      sqlite3DebugPrintf("\n");
    }
    sqlite3DebugPrintf("\n");
    sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
  }
}
#endif

#ifdef WHERETRACE_ENABLED
/*
** Show the complete content of a WhereClause
*/
void sqlite3WhereClausePrint(WhereClause *pWC){
  int i;
  for(i=0; i<pWC->nTerm; i++){
    sqlite3WhereTermPrint(&pWC->a[i], i);
    whereTermPrint(&pWC->a[i], i);
  }
}
#endif

#ifdef WHERETRACE_ENABLED
/*
** Print a WhereLoop object for debugging purposes
*/
void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){
static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
  WhereInfo *pWInfo = pWC->pWInfo;
  int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
  SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
  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 ){
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
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







-
+
















-
+







      sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq);
    }else{
      sqlite3DebugPrintf("%20s","");
    }
  }else{
    char *z;
    if( p->u.vtab.idxStr ){
      z = sqlite3_mprintf("(%d,\"%s\",%#x)",
      z = sqlite3_mprintf("(%d,\"%s\",%x)",
                p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask);
    }else{
      z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
    }
    sqlite3DebugPrintf(" %-19s", z);
    sqlite3_free(z);
  }
  if( p->wsFlags & WHERE_SKIPSCAN ){
    sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
  }else{
    sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
  }
  sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
  if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
    int i;
    for(i=0; i<p->nLTerm; i++){
      sqlite3WhereTermPrint(p->aLTerm[i], i);
      whereTermPrint(p->aLTerm[i], i);
    }
  }
}
#endif

/*
** Convert bulk memory into a valid WhereLoop that can be passed
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1932
1933
1934
1935
1936
1937
1938

1939
1940
1941
1942
1943
1944
1945







-







  }
  sqlite3WhereClauseClear(&pWInfo->sWC);
  while( pWInfo->pLoops ){
    WhereLoop *p = pWInfo->pLoops;
    pWInfo->pLoops = p->pNextLoop;
    whereLoopDelete(db, p);
  }
  assert( pWInfo->pExprMods==0 );
  sqlite3DbFreeNN(db, pWInfo);
}

/*
** Return TRUE if all of the following are true:
**
**   (1)  X has the same or lower cost that Y
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198

2199
2200
2201
2202
2203
2204
2205
2206

2207
2208
2209
2210
2211
2212
2213
2214
2215

2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231

2232
2233
2234
2235
2236

2237
2238
2239
2240
2241
2242
2243
2133
2134
2135
2136
2137
2138
2139


2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153

2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171

2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187

2188
2189
2190
2191
2192

2193
2194
2195
2196
2197
2198
2199
2200







-
-














-
+








+








-
+















-
+




-
+







  if( pBuilder->iPlanLimit==0 ){
    WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
    if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
    return SQLITE_DONE;
  }
  pBuilder->iPlanLimit--;

  whereLoopAdjustCost(pWInfo->pLoops, pTemplate);

  /* If pBuilder->pOrSet is defined, then only keep track of the costs
  ** and prereqs.
  */
  if( pBuilder->pOrSet!=0 ){
    if( pTemplate->nLTerm ){
#if WHERETRACE_ENABLED
      u16 n = pBuilder->pOrSet->n;
      int x =
#endif
      whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
                                    pTemplate->nOut);
#if WHERETRACE_ENABLED /* 0x8 */
      if( sqlite3WhereTrace & 0x8 ){
        sqlite3DebugPrintf(x?"   or-%d:  ":"   or-X:  ", n);
        sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC);
        whereLoopPrint(pTemplate, pBuilder->pWC);
      }
#endif
    }
    return SQLITE_OK;
  }

  /* Look for an existing WhereLoop to replace with pTemplate
  */
  whereLoopAdjustCost(pWInfo->pLoops, pTemplate);
  ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate);

  if( ppPrev==0 ){
    /* There already exists a WhereLoop on the list that is better
    ** than pTemplate, so just ignore pTemplate */
#if WHERETRACE_ENABLED /* 0x8 */
    if( sqlite3WhereTrace & 0x8 ){
      sqlite3DebugPrintf("   skip: ");
      sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC);
      whereLoopPrint(pTemplate, pBuilder->pWC);
    }
#endif
    return SQLITE_OK;  
  }else{
    p = *ppPrev;
  }

  /* If we reach this point it means that either p[] should be overwritten
  ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
  ** WhereLoop and insert it.
  */
#if WHERETRACE_ENABLED /* 0x8 */
  if( sqlite3WhereTrace & 0x8 ){
    if( p!=0 ){
      sqlite3DebugPrintf("replace: ");
      sqlite3WhereLoopPrint(p, pBuilder->pWC);
      whereLoopPrint(p, pBuilder->pWC);
      sqlite3DebugPrintf("   with: ");
    }else{
      sqlite3DebugPrintf("    add: ");
    }
    sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC);
    whereLoopPrint(pTemplate, pBuilder->pWC);
  }
#endif
  if( p==0 ){
    /* Allocate a new WhereLoop to add to the end of the list */
    *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop));
    if( p==0 ) return SQLITE_NOMEM_BKPT;
    whereLoopInit(p);
2253
2254
2255
2256
2257
2258
2259
2260

2261
2262
2263
2264
2265
2266
2267
2210
2211
2212
2213
2214
2215
2216

2217
2218
2219
2220
2221
2222
2223
2224







-
+







      if( ppTail==0 ) break;
      pToDel = *ppTail;
      if( pToDel==0 ) break;
      *ppTail = pToDel->pNextLoop;
#if WHERETRACE_ENABLED /* 0x8 */
      if( sqlite3WhereTrace & 0x8 ){
        sqlite3DebugPrintf(" delete: ");
        sqlite3WhereLoopPrint(pToDel, pBuilder->pWC);
        whereLoopPrint(pToDel, pBuilder->pWC);
      }
#endif
      whereLoopDelete(db, pToDel);
    }
  }
  rc = whereLoopXfer(db, p, pTemplate);
  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
2305
2306
2307
2308
2309
2310
2311
2312

2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336

2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347

2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2262
2263
2264
2265
2266
2267
2268

2269
2270
2271
2272
2273

2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291

2292


2293

2294
2295
2296
2297
2298
2299

2300



2301
2302
2303
2304
2305
2306
2307







-
+




-


















-
+
-
-

-






-
+
-
-
-







static void whereLoopOutputAdjust(
  WhereClause *pWC,      /* The WHERE clause */
  WhereLoop *pLoop,      /* The loop to adjust downward */
  LogEst nRow            /* Number of rows in the entire table */
){
  WhereTerm *pTerm, *pX;
  Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
  int i, j;
  int i, j, k;
  LogEst iReduce = 0;    /* pLoop->nOut should not exceed nRow-iReduce */

  assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
  for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
    assert( pTerm!=0 );
    if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
    if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
    if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
    for(j=pLoop->nLTerm-1; j>=0; j--){
      pX = pLoop->aLTerm[j];
      if( pX==0 ) continue;
      if( pX==pTerm ) break;
      if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
    }
    if( j<0 ){
      if( pTerm->truthProb<=0 ){
        /* If a truth probability is specified using the likelihood() hints,
        ** then use the probability provided by the application. */
        pLoop->nOut += pTerm->truthProb;
      }else{
        /* In the absence of explicit truth probabilities, use heuristics to
        ** guess a reasonable truth probability. */
        pLoop->nOut--;
        if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0
        if( pTerm->eOperator&(WO_EQ|WO_IS) ){
         && (pTerm->wtFlags & TERM_HIGHTRUTH)==0  /* tag-20200224-1 */
        ){
          Expr *pRight = pTerm->pExpr->pRight;
          int k = 0;
          testcase( pTerm->pExpr->op==TK_IS );
          if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
            k = 10;
          }else{
            k = 20;
          }
          if( iReduce<k ){
          if( iReduce<k ) iReduce = k;
            pTerm->wtFlags |= TERM_HEURTRUTH;
            iReduce = k;
          }
        }
      }
    }
  }
  if( pLoop->nOut > nRow-iReduce )  pLoop->nOut = nRow - iReduce;
}

2441
2442
2443
2444
2445
2446
2447
2448

2449
2450
2451
2452
2453
2454
2455
2391
2392
2393
2394
2395
2396
2397

2398
2399
2400
2401
2402
2403
2404
2405







-
+







** 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 */
  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 */
2467
2468
2469
2470
2471
2472
2473
2474
2475


2476
2477
2478
2479
2480
2481
2482
2483
2417
2418
2419
2420
2421
2422
2423


2424
2425

2426
2427
2428
2429
2430
2431
2432







-
-
+
+
-







  int rc = SQLITE_OK;             /* Return code */
  LogEst rSize;                   /* Number of rows in the table */
  LogEst rLogSize;                /* Logarithm of table size */
  WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */

  pNew = pBuilder->pNew;
  if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
  WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n",
                     pProbe->pTable->zName,pProbe->zName,
  WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d\n",
                     pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq));
                     pNew->u.btree.nEq, pNew->nSkip, pNew->rRun));

  assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
  assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
  if( pNew->wsFlags & WHERE_BTM_LIMIT ){
    opMask = WO_LT|WO_LE;
  }else{
    assert( pNew->u.btree.nBtm==0 );
2501
2502
2503
2504
2505
2506
2507
2508

2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524



2525
2526
2527
2528
2529
2530
2531
2532

2533
2534

2535
2536
2537
2538
2539
2540
2541
2450
2451
2452
2453
2454
2455
2456

2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470



2471
2472
2473
2474
2475
2476
2477
2478
2479
2480

2481
2482

2483
2484
2485
2486
2487
2488
2489
2490







-
+













-
-
-
+
+
+







-
+

-
+







  rSize = pProbe->aiRowLogEst[0];
  rLogSize = estLog(rSize);
  for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
    u16 eOp = pTerm->eOperator;   /* Shorthand for pTerm->eOperator */
    LogEst rCostIdx;
    LogEst nOutUnadjusted;        /* nOut before IN() and WHERE adjustments */
    int nIn = 0;
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    int nRecValid = pBuilder->nRecValid;
#endif
    if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
     && indexColumnNotNull(pProbe, saved_nEq)
    ){
      continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
    }
    if( pTerm->prereqRight & pNew->maskSelf ) continue;

    /* Do not allow the upper bound of a LIKE optimization range constraint
    ** to mix with a lower range bound from some other source */
    if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;

    /* tag-20191211-001:  Do not allow constraints from the WHERE clause to
    ** be used by the right table of a LEFT JOIN.  Only constraints in the
    ** ON clause are allowed.  See tag-20191211-002 for the vtab equivalent. */
    /* Do not allow constraints from the WHERE clause to be used by the
    ** right table of a LEFT JOIN.  Only constraints in the ON clause are
    ** allowed */
    if( (pSrc->fg.jointype & JT_LEFT)!=0
     && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
    ){
      continue;
    }

    if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
      pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
      pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE;
    }else{
      pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED;
      pBuilder->bldFlags |= SQLITE_BLDF_INDEXED;
    }
    pNew->wsFlags = saved_wsFlags;
    pNew->u.btree.nEq = saved_nEq;
    pNew->u.btree.nBtm = saved_nBtm;
    pNew->u.btree.nTop = saved_nTop;
    pNew->nLTerm = saved_nLTerm;
    if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
2562
2563
2564
2565
2566
2567
2568


2569
2570

2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589

2590
2591
2592
2593
2594
2595
2596
2597
2598
2599

2600
2601
2602
2603
2604
2605
2606
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520

2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539

2540

2541
2542
2543
2544
2545
2546
2547
2548

2549
2550
2551
2552
2553
2554
2555
2556







+
+

-
+


















-
+
-








-
+







        ** first such term in use, and sets nIn back to 0 if it is not. */
        for(i=0; i<pNew->nLTerm-1; i++){
          if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0;
        }
      }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
        /* "x IN (value, value, ...)" */
        nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
        assert( nIn>0 );  /* RHS always has 2 or more terms...  The parser
                          ** changes "x IN (?)" into "x=?". */
      }
      if( pProbe->hasStat1 && rLogSize>=10 ){
      if( pProbe->hasStat1 ){
        LogEst M, logK, safetyMargin;
        /* Let:
        **   N = the total number of rows in the table
        **   K = the number of entries on the RHS of the IN operator
        **   M = the number of rows in the table that match terms to the 
        **       to the left in the same index.  If the IN operator is on
        **       the left-most index column, M==N.
        **
        ** Given the definitions above, it is better to omit the IN operator
        ** from the index lookup and instead do a scan of the M elements,
        ** testing each scanned row against the IN operator separately, if:
        **
        **        M*log(K) < K*log(N)
        **
        ** Our estimates for M, K, and N might be inaccurate, so we build in
        ** a safety margin of 2 (LogEst: 10) that favors using the IN operator
        ** with the index, as using an index has better worst-case behavior.
        ** If we do not have real sqlite_stat1 data, always prefer to use
        ** the index.  Do not bother with this optimization on very small
        ** the index.
        ** tables (less than 2 rows) as it is pointless in that case.
        */
        M = pProbe->aiRowLogEst[saved_nEq];
        logK = estLog(nIn);
        safetyMargin = 10;  /* TUNING: extra weight for indexed IN */
        if( M + logK + safetyMargin < nIn + rLogSize ){
          WHERETRACE(0x40,
            ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n",
             saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
          pNew->wsFlags |= WHERE_IN_SEEKSCAN;
          continue;
        }else{
          WHERETRACE(0x40,
            ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n",
             saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
        }
      }
      pNew->wsFlags |= WHERE_COLUMN_IN;
2627
2628
2629
2630
2631
2632
2633
2634

2635
2636
2637
2638
2639
2640
2641
2577
2578
2579
2580
2581
2582
2583

2584
2585
2586
2587
2588
2589
2590
2591







-
+







      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
        /* 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;
2658
2659
2660
2661
2662
2663
2664
2665

2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679

2680
2681
2682
2683
2684
2685

2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
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







-
+













-
+





-
+














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







    /* At this point pNew->nOut is set to the number of rows expected to
    ** be visited by the index scan before considering term pTerm, or the
    ** values of nIn and nInMul. In other words, assuming that all 
    ** "x IN(...)" terms are replaced with "x = ?". This block updates
    ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul).  */
    assert( pNew->nOut==saved_nOut );
    if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
      /* Adjust nOut using stat4 data. Or, if there is no stat4
      /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4
      ** data, using some other estimate.  */
      whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
    }else{
      int nEq = ++pNew->u.btree.nEq;
      assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );

      assert( pNew->nOut==saved_nOut );
      if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){
        assert( (eOp & WO_IN) || nIn==0 );
        testcase( eOp & WO_IN );
        pNew->nOut += pTerm->truthProb;
        pNew->nOut -= nIn;
      }else{
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
        tRowcnt nOut = 0;
        if( nInMul==0 
         && pProbe->nSample 
         && pNew->u.btree.nEq<=pProbe->nSampleCol
         && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
         && OptimizationEnabled(db, SQLITE_Stat4)
         && OptimizationEnabled(db, SQLITE_Stat34)
        ){
          Expr *pExpr = pTerm->pExpr;
          if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
            testcase( eOp & WO_EQ );
            testcase( eOp & WO_IS );
            testcase( eOp & WO_ISNULL );
            rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
          }else{
            rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
          }
          if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
          if( rc!=SQLITE_OK ) break;          /* Jump out of the pTerm loop */
          if( nOut ){
            pNew->nOut = sqlite3LogEst(nOut);
            if( nEq==1
             /* TUNING: Mark terms as "low selectivity" if they seem likely
             ** to be true for half or more of the rows in the table.
             ** See tag-202002240-1 */
             && pNew->nOut+10 > pProbe->aiRowLogEst[0]
            ){
#if WHERETRACE_ENABLED /* 0x01 */
              if( sqlite3WhereTrace & 0x01 ){
                sqlite3DebugPrintf(
                   "STAT4 determines term has low selectivity:\n");
                sqlite3WhereTermPrint(pTerm, 999);
              }
#endif
              pTerm->wtFlags |= TERM_HIGHTRUTH;
              if( pTerm->wtFlags & TERM_HEURTRUTH ){
                /* If the term has previously been used with an assumption of
                ** higher selectivity, then set the flag to rerun the
                ** loop computations. */
                pBuilder->bldFlags2 |= SQLITE_BLDF2_2NDPASS;
              }
            }
            if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut;
            pNew->nOut -= nIn;
          }
        }
        if( nOut==0 )
#endif
        {
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2665
2666
2667
2668
2669
2670
2671

2672
2673
2674
2675
2676
2677
2678







-







      }
    }

    /* Set rCostIdx to the cost of visiting selected rows in index. Add
    ** it to pNew->rRun, which is currently set to the cost of the index
    ** seek only. Then, if this is a non-covering index, add the cost of
    ** visiting the rows in the main table.  */
    assert( pSrc->pTab->szTabRow>0 );
    rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
    pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
    if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
      pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
    }
    ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult);

2762
2763
2764
2765
2766
2767
2768
2769

2770
2771
2772
2773
2774
2775
2776
2690
2691
2692
2693
2694
2695
2696

2697
2698
2699
2700
2701
2702
2703
2704







-
+








    if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
     && pNew->u.btree.nEq<pProbe->nColumn
    ){
      whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
    }
    pNew->nOut = saved_nOut;
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    pBuilder->nRecValid = nRecValid;
#endif
  }
  pNew->prereq = saved_prereq;
  pNew->u.btree.nEq = saved_nEq;
  pNew->u.btree.nBtm = saved_nBtm;
  pNew->u.btree.nTop = saved_nTop;
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2716
2717
2718
2719
2720
2721
2722

2723

2724
2725
2726
2727
2728
2729
2730







-

-







  ** contains fewer than 2^17 rows we assume otherwise in other parts of
  ** the code). And, even if it is not, it should not be too much slower. 
  ** On the other hand, the extra seeks could end up being significantly
  ** more expensive.  */
  assert( 42==sqlite3LogEst(18) );
  if( saved_nEq==saved_nSkip
   && saved_nEq+1<pProbe->nKeyCol
   && saved_nEq==pNew->nLTerm
   && pProbe->noSkipScan==0
   && pProbe->hasStat1!=0
   && OptimizationEnabled(db, SQLITE_SkipScan)
   && pProbe->aiRowLogEst[saved_nEq+1]>=42  /* TUNING: Minimum for skip-scan */
   && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
  ){
    LogEst nIter;
    pNew->u.btree.nEq++;
    pNew->nSkip++;
2837
2838
2839
2840
2841
2842
2843
2844

2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866

2867
2868
2869
2870
2871
2872
2873
2874
2875
2876

2877
2878
2879
2880
2881
2882

2883
2884
2885
2886
2887
2888
2889
2890
2891
2763
2764
2765
2766
2767
2768
2769

2770

2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790

2791





2792
2793
2794
2795

2796
2797
2798
2799
2800


2801
2802

2803
2804
2805
2806
2807
2808
2809







-
+
-




















-
+
-
-
-
-
-




-
+




-
-
+

-







  ExprList *pOB;
  ExprList *aColExpr;
  int ii, jj;

  if( pIndex->bUnordered ) return 0;
  if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
  for(ii=0; ii<pOB->nExpr; ii++){
    Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr);
    Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
    if( NEVER(pExpr==0) ) continue;
    if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
      if( pExpr->iColumn<0 ) return 1;
      for(jj=0; jj<pIndex->nKeyCol; jj++){
        if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
      }
    }else if( (aColExpr = pIndex->aColExpr)!=0 ){
      for(jj=0; jj<pIndex->nKeyCol; jj++){
        if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
        if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
          return 1;
        }
      }
    }
  }
  return 0;
}

/* Check to see if a partial index with pPartIndexWhere can be used
** in the current query.  Return true if it can be and false if not.
*/
static int whereUsablePartialIndex(
static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
  int iTab,             /* The table for which we want an index */
  int isLeft,           /* True if iTab is the right table of a LEFT JOIN */
  WhereClause *pWC,     /* The WHERE clause of the query */
  Expr *pWhere          /* The WHERE clause from the partial index */
){
  int i;
  WhereTerm *pTerm;
  Parse *pParse = pWC->pWInfo->pParse;
  while( pWhere->op==TK_AND ){
    if( !whereUsablePartialIndex(iTab,isLeft,pWC,pWhere->pLeft) ) return 0;
    if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0;
    pWhere = pWhere->pRight;
  }
  if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
  for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
    Expr *pExpr;
    pExpr = pTerm->pExpr;
    Expr *pExpr = pTerm->pExpr;
    if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
     && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
     && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) 
    ){
      return 1;
    }
  }
  return 0;
}
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
2850
2851
2852
2853
2854
2855
2856

2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874

2875
2876

2877
2878
2879
2880
2881
2882
2883
2884







-
+

















-
+

-
+







){
  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 */
  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->fg.isIndexedBy ){
  if( pSrc->pIBIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->u2.pIBIndex;
    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 */
2988
2989
2990
2991
2992
2993
2994
2995

2996
2997
2998
2999
3000
3001
3002
2906
2907
2908
2909
2910
2911
2912

2913
2914
2915
2916
2917
2918
2919
2920







-
+







  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->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;
3038
3039
3040
3041
3042
3043
3044
3045

3046
3047
3048
3049

3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077

3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
2956
2957
2958
2959
2960
2961
2962

2963
2964

2965

2966


2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982

2983
2984
2985
2986
2987
2988
2989
2990

2991














2992

2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011

3012
3013
3014
3015
3016
3017
3018







-
+

-

-
+
-
-
















-








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

-



















-







    }
  }
#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++
      pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++
  ){
    int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0;
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC,
     && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
                                 pProbe->pPartIdxWhere)
    ){
      testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */
      continue;  /* Partial index inappropriate for this query */
    }
    if( pProbe->bNoQuery ) continue;
    rSize = pProbe->aiRowLogEst[0];
    pNew->u.btree.nEq = 0;
    pNew->u.btree.nBtm = 0;
    pNew->u.btree.nTop = 0;
    pNew->nSkip = 0;
    pNew->nLTerm = 0;
    pNew->iSortIdx = 0;
    pNew->rSetup = 0;
    pNew->prereq = mPrereq;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = pProbe;
    b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);

    /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
    assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
    if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
      /* Integer primary key index */
      pNew->wsFlags = WHERE_IPK;

      /* Full table scan */
      pNew->iSortIdx = b ? iSortIdx : 0;
      /* TUNING: Cost of full table scan is 3.0*N.  The 3.0 factor is an
      /* TUNING: Cost of full table scan is (N*3.0). */
      ** extra cost designed to discourage the use of full table scans,
      ** since index lookups have better worst-case performance if our
      ** stat guesses are wrong.  Reduce the 3.0 penalty slightly
      ** (to 2.75) if we have valid STAT4 information for the table.
      ** At 2.75, a full table scan is preferred over using an index on
      ** a column with just two distinct values where each value has about
      ** an equal number of appearances.  Without STAT4 data, we still want
      ** to use an index in that case, since the constraint might be for
      ** the scarcer of the two values, and in that case an index lookup is
      ** better.
      */
#ifdef SQLITE_ENABLE_STAT4
      pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0);
#else
      pNew->rRun = rSize + 16;
#endif
      ApplyCostMultiplier(pNew->rRun, pTab->costMult);
      whereLoopOutputAdjust(pWC, pNew, rSize);
      rc = whereLoopInsert(pBuilder, pNew);
      pNew->nOut = rSize;
      if( rc ) break;
    }else{
      Bitmask m;
      if( pProbe->isCovering ){
        pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
        m = 0;
      }else{
        m = pSrc->colUsed & pProbe->colNotIdxed;
        pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
      }

      /* Full scan via index */
      if( b
       || !HasRowid(pTab)
       || pProbe->pPartIdxWhere!=0
       || pSrc->fg.isIndexedBy
       || ( m==0
         && pProbe->bUnordered==0
         && (pProbe->szIdxRow<pTab->szTabRow)
         && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
         && sqlite3GlobalConfig.bUseCis
         && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
          )
3156
3157
3158
3159
3160
3161
3162
3163

3164
3165

3166
3167
3168
3169
3170
3171
3172

3173
3174
3175
3176
3177
3178
3179
3054
3055
3056
3057
3058
3059
3060

3061
3062

3063
3064
3065
3066
3067
3068
3069

3070
3071
3072
3073
3074
3075
3076
3077







-
+

-
+






-
+







        whereLoopOutputAdjust(pWC, pNew, rSize);
        rc = whereLoopInsert(pBuilder, pNew);
        pNew->nOut = rSize;
        if( rc ) break;
      }
    }

    pBuilder->bldFlags1 = 0;
    pBuilder->bldFlags = 0;
    rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
    if( pBuilder->bldFlags1==SQLITE_BLDF1_INDEXED ){
    if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){
      /* If a non-unique index is used, or if a prefix of the key for
      ** unique index is used (making the index functionally non-unique)
      ** then the sqlite_stat1 data becomes important for scoring the
      ** plan */
      pTab->tabFlags |= TF_StatsUsed;
    }
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    sqlite3Stat4ProbeFree(pBuilder->pRec);
    pBuilder->nRecValid = 0;
    pBuilder->pRec = 0;
#endif
  }
  return rc;
}
3213
3214
3215
3216
3217
3218
3219
3220

3221
3222
3223
3224
3225
3226
3227
3111
3112
3113
3114
3115
3116
3117

3118
3119
3120
3121
3122
3123
3124
3125







-
+







  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];
  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 
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298

3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314

3315
3316
3317
3318
3319
3320
3321
3186
3187
3188
3189
3190
3191
3192




3193




3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213







-
-
-
-
+
-
-
-
-












+







      pTerm = &pWC->a[j];
      pNew->prereq |= pTerm->prereqRight;
      assert( iTerm<pNew->nLSlot );
      pNew->aLTerm[iTerm] = pTerm;
      if( iTerm>mxTerm ) mxTerm = iTerm;
      testcase( iTerm==15 );
      testcase( iTerm==16 );
      if( pUsage[i].omit ){
        if( i<16 && ((1<<i)&mNoOmit)==0 ){
          testcase( i!=iTerm );
          pNew->u.vtab.omitMask |= 1<<iTerm;
      if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
        }else{
          testcase( i!=iTerm );
        }
      }
      if( (pTerm->eOperator & WO_IN)!=0 ){
        /* A virtual table that is constrained by an IN clause may not
        ** consume the ORDER BY clause because (1) the order of IN terms
        ** is not necessarily related to the order of output terms and
        ** (2) Multiple outputs from a single IN value will not merge
        ** together.  */
        pIdxInfo->orderByConsumed = 0;
        pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
        *pbIn = 1; assert( (mExclude & WO_IN)==0 );
      }
    }
  }
  pNew->u.vtab.omitMask &= ~mNoOmit;

  pNew->nLTerm = mxTerm+1;
  for(i=0; i<=mxTerm; i++){
    if( pNew->aLTerm[i]==0 ){
      /* The non-zero argvIdx values must be contiguous.  Raise an
      ** error if they are not */
      sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
3364
3365
3366
3367
3368
3369
3370
3371

3372
3373
3374
3375
3376
3377
3378
3256
3257
3258
3259
3260
3261
3262

3263
3264
3265
3266
3267
3268
3269
3270







-
+







  HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
  const char *zRet = 0;
  if( iCons>=0 && iCons<pIdxInfo->nConstraint ){
    CollSeq *pC = 0;
    int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset;
    Expr *pX = pHidden->pWC->a[iTerm].pExpr;
    if( pX->pLeft ){
      pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX);
      pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight);
    }
    zRet = (pC ? pC->zName : sqlite3StrBINARY);
  }
  return zRet;
}

/*
3405
3406
3407
3408
3409
3410
3411
3412

3413
3414
3415
3416
3417
3418
3419
3297
3298
3299
3300
3301
3302
3303

3304
3305
3306
3307
3308
3309
3310
3311







-
+







  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 */
  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;

3533
3534
3535
3536
3537
3538
3539
3540

3541
3542
3543
3544
3545
3546
3547
3425
3426
3427
3428
3429
3430
3431

3432
3433
3434
3435
3436
3437
3438
3439







-
+







  WhereLoop *pNew;
  WhereTerm *pTerm, *pWCEnd;
  int rc = SQLITE_OK;
  int iCur;
  WhereClause tempWC;
  WhereLoopBuilder sSubBuild;
  WhereOrSet sSum, sCur;
  SrcItem *pItem;
  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;
3589
3590
3591
3592
3593
3594
3595
3596

3597
3598
3599
3600
3601
3602
3603
3604
3481
3482
3483
3484
3485
3486
3487

3488

3489
3490
3491
3492
3493
3494
3495







-
+
-







#endif
        {
          rc = whereLoopAddBtree(&sSubBuild, mPrereq);
        }
        if( rc==SQLITE_OK ){
          rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
        }
        assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0 );
        assert( rc==SQLITE_OK || sCur.n==0 );
        testcase( rc==SQLITE_DONE );
        if( sCur.n==0 ){
          sSum.n = 0;
          break;
        }else if( once ){
          whereOrMove(&sSum, &sCur);
          once = 0;
        }else{
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
3540
3541
3542
3543
3544
3545
3546


3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562

3563
3564
3565
3566


3567
3568
3569
3570

3571
3572
3573
3574
3575
3576
3577
3578







-
-
+
+



+










-
+



-
-

+


-
+







*/
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];
  struct SrcList_item *pItem;
  struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel];
  sqlite3 *db = pWInfo->pParse->db;
  int rc = SQLITE_OK;
  WhereLoop *pNew;
  u8 priorJointype = 0;

  /* Loop over the tables in the join, from left to right */
  pNew = pBuilder->pNew;
  whereLoopInit(pNew);
  pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
  for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
    Bitmask mUnusable = 0;
    pNew->iTab = iTab;
    pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
    pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
    if( (pItem->fg.jointype & (JT_LEFT|JT_CROSS))!=0 ){
    if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
      /* This condition is true when pItem is the FROM clause term on the
      ** right-hand-side of a LEFT or CROSS JOIN.  */
      mPrereq = mPrior;
    }else{
      mPrereq = 0;
    }
    priorJointype = pItem->fg.jointype;
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pItem->pTab) ){
      SrcItem *p;
      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
3788
3789
3790
3791
3792
3793
3794
3795
3796

3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807

3808
3809
3810
3811
3812


3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823

3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834

3835
3836
3837
3838
3839
3840
3841


3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865

3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884

3885
3886
3887
3888
3889
3890
3891
3892
3893

3894
3895
3896
3897

3898
3899
3900
3901
3902
3903
3904
3905
3679
3680
3681
3682
3683
3684
3685


3686

3687
3688
3689
3690
3691
3692
3693
3694
3695

3696


3697


3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709

3710

3711
3712
3713
3714
3715
3716
3717
3718
3719

3720

3721
3722
3723
3724


3725
3726



3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746

3747

3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764

3765



3766
3767
3768
3769
3770

3771

3772


3773

3774
3775
3776
3777
3778
3779
3780







-
-
+
-









-
+
-
-

-
-
+
+










-
+
-









-
+
-




-
-
+
+
-
-
-




















-
+
-

















-
+
-
-
-





-
+
-

-
-
+
-







  testcase( nOrderBy==BMS-1 );
  if( nOrderBy>BMS-1 ) return 0;  /* Cannot optimize overly large ORDER BYs */
  isOrderDistinct = 1;
  obDone = MASKBIT(nOrderBy)-1;
  orderDistinctMask = 0;
  ready = 0;
  eqOpMask = WO_EQ | WO_IS | WO_ISNULL;
  if( wctrlFlags & (WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MAX|WHERE_ORDERBY_MIN) ){
    eqOpMask |= WO_IN;
  if( wctrlFlags & WHERE_ORDERBY_LIMIT ) eqOpMask |= WO_IN;
  }
  for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){
    if( iLoop>0 ) ready |= pLoop->maskSelf;
    if( iLoop<nLoop ){
      pLoop = pPath->aLoop[iLoop];
      if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
    }else{
      pLoop = pLast;
    }
    if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
      if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){
      if( pLoop->u.vtab.isOrdered ) obSat = obDone;
        obSat = obDone;
      }
      break;
    }else if( wctrlFlags & WHERE_DISTINCTBY ){
      pLoop->u.btree.nDistinctCol = 0;
    }else{
      pLoop->u.btree.nIdxCol = 0;
    }
    iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;

    /* Mark off any ORDER BY term X that is a column in the table of
    ** the current loop for which there is term in the WHERE
    ** clause of the form X IS NULL or X=? that reference only outer
    ** loops.
    */
    for(i=0; i<nOrderBy; i++){
      if( MASKBIT(i) & obSat ) continue;
      pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr);
      pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
      if( NEVER(pOBExpr==0) ) continue;
      if( pOBExpr->op!=TK_COLUMN ) continue;
      if( pOBExpr->iTable!=iCur ) continue;
      pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
                       ~ready, eqOpMask, 0);
      if( pTerm==0 ) continue;
      if( pTerm->eOperator==WO_IN ){
        /* IN terms are only valid for sorting in the ORDER BY LIMIT 
        ** optimization, and then only if they are actually used
        ** by the query plan */
        assert( wctrlFlags & 
        assert( wctrlFlags & WHERE_ORDERBY_LIMIT );
               (WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) );
        for(j=0; j<pLoop->nLTerm && pTerm!=pLoop->aLTerm[j]; j++){}
        if( j>=pLoop->nLTerm ) continue;
      }
      if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
        Parse *pParse = pWInfo->pParse;
        CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[i].pExpr);
        if( sqlite3ExprCollSeqMatch(pWInfo->pParse, 
                  pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){
        CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr);
        assert( pColl1 );
        if( pColl2==0 || sqlite3StrICmp(pColl1->zName, pColl2->zName) ){
          continue;
        }
        testcase( pTerm->pExpr->op==TK_IS );
      }
      obSat |= MASKBIT(i);
    }

    if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
      if( pLoop->wsFlags & WHERE_IPK ){
        pIndex = 0;
        nKeyCol = 0;
        nColumn = 1;
      }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
        return 0;
      }else{
        nKeyCol = pIndex->nKeyCol;
        nColumn = pIndex->nColumn;
        assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
        assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
                          || !HasRowid(pIndex->pTable));
        isOrderDistinct = IsUniqueIndex(pIndex)
        isOrderDistinct = IsUniqueIndex(pIndex);
                          && (pLoop->wsFlags & WHERE_SKIPSCAN)==0;
      }

      /* Loop through all columns of the index and deal with the ones
      ** that are not constrained by == or IN.
      */
      rev = revSet = 0;
      distinctColumns = 0;
      for(j=0; j<nColumn; j++){
        u8 bOnce = 1; /* True to run the ORDER BY search loop */

        assert( j>=pLoop->u.btree.nEq 
            || (pLoop->aLTerm[j]==0)==(j<pLoop->nSkip)
        );
        if( j<pLoop->u.btree.nEq && j>=pLoop->nSkip ){
          u16 eOp = pLoop->aLTerm[j]->eOperator;

          /* Skip over == and IS and ISNULL terms.  (Also skip IN terms when
          ** doing WHERE_ORDERBY_LIMIT processing).  Except, IS and ISNULL
          ** doing WHERE_ORDERBY_LIMIT processing). 
          ** terms imply that the index is not UNIQUE NOT NULL in which case
          ** the loop need to be marked as not order-distinct because it can
          ** have repeated NULL rows.
          **
          ** If the current term is a column of an ((?,?) IN (SELECT...)) 
          ** expression for which the SELECT returns more than one column,
          ** check that it is the only column used by this loop. Otherwise,
          ** if it is one of two or more, none of the columns can be
          ** considered to match an ORDER BY term.
          ** considered to match an ORDER BY term.  */
          */
          if( (eOp & eqOpMask)!=0 ){
            if( eOp & (WO_ISNULL|WO_IS) ){
              testcase( eOp & WO_ISNULL );
            if( eOp & WO_ISNULL ){
              testcase( eOp & WO_IS );
              testcase( isOrderDistinct );
              isOrderDistinct = 0;
            }
            continue;  
          }else if( ALWAYS(eOp & WO_IN) ){
            /* ALWAYS() justification: eOp is an equality operator due to the
            ** j<pLoop->u.btree.nEq constraint above.  Any equality other
3917
3918
3919
3920
3921
3922
3923
3924

3925
3926
3927
3928
3929
3930
3931
3792
3793
3794
3795
3796
3797
3798

3799
3800
3801
3802
3803
3804
3805
3806







-
+







        }

        /* Get the column number in the table (iColumn) and sort order
        ** (revIdx) for the j-th column of the index.
        */
        if( pIndex ){
          iColumn = pIndex->aiColumn[j];
          revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC;
          revIdx = pIndex->aSortOrder[j];
          if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID;
        }else{
          iColumn = XN_ROWID;
          revIdx = 0;
        }

        /* An unconstrained column that might be NULL means that this
3941
3942
3943
3944
3945
3946
3947
3948

3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968

3969
3970
3971
3972
3973
3974
3975
3976
3977
3978

3979
3980
3981

3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
3816
3817
3818
3819
3820
3821
3822

3823
3824
3825

3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840


3841

3842
3843
3844
3845
3846
3847
3848


3849

3850

3851
3852
3853
3854
3855







3856
3857
3858
3859
3860
3861
3862







-
+


-















-
-
+
-







-
-
+
-

-
+




-
-
-
-
-
-
-








        /* Find the ORDER BY term that corresponds to the j-th column
        ** of the index and mark that ORDER BY term off 
        */
        isMatch = 0;
        for(i=0; bOnce && i<nOrderBy; i++){
          if( MASKBIT(i) & obSat ) continue;
          pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr);
          pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
          testcase( wctrlFlags & WHERE_GROUPBY );
          testcase( wctrlFlags & WHERE_DISTINCTBY );
          if( NEVER(pOBExpr==0) ) continue;
          if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
          if( iColumn>=XN_ROWID ){
            if( pOBExpr->op!=TK_COLUMN ) continue;
            if( pOBExpr->iTable!=iCur ) continue;
            if( pOBExpr->iColumn!=iColumn ) continue;
          }else{
            Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr;
            if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){
              continue;
            }
          }
          if( iColumn!=XN_ROWID ){
            pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
            if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
          }
          if( wctrlFlags & WHERE_DISTINCTBY ){
            pLoop->u.btree.nDistinctCol = j+1;
          pLoop->u.btree.nIdxCol = j+1;
          }
          isMatch = 1;
          break;
        }
        if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
          /* Make sure the sort order is compatible in an ORDER BY clause.
          ** Sort order is irrelevant for a GROUP BY clause. */
          if( revSet ){
            if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){
              isMatch = 0;
            if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
            }
          }else{
            rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC);
            rev = revIdx ^ pOrderBy->a[i].sortOrder;
            if( rev ) *pRevMask |= MASKBIT(iLoop);
            revSet = 1;
          }
        }
        if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){
          if( j==pLoop->u.btree.nEq ){
            pLoop->wsFlags |= WHERE_BIGNULL_SORT;
          }else{
            isMatch = 0;
          }
        }
        if( isMatch ){
          if( iColumn==XN_ROWID ){
            testcase( distinctColumns==0 );
            distinctColumns = 1;
          }
          obSat |= MASKBIT(i);
        }else{
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
3962
3963
3964
3965
3966
3967
3968

3969

3970
3971
3972
3973
3974
3975

3976



3977
3978




3979
3980
3981
3982
3983
3984
3985







-
+
-






-
+
-
-
-


-
-
-
-







  ** Or, if the order-by clause has X terms but only the last Y 
  ** terms are out of order, then block-sorting will reduce the 
  ** sorting cost to:
  **
  **   cost = (3.0 * N * log(N)) * (Y/X)
  **
  ** The (Y/X) term is implemented using stack variable rScale
  ** below.
  ** below.  */
  */
  LogEst rScale, rSortCost;
  assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
  rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
  rSortCost = nRow + rScale + 16;

  /* Multiple by log(M) where M is the number of output rows.
  ** Use the LIMIT for M if it is smaller.  Or if this sort is for
  ** Use the LIMIT for M if it is smaller */
  ** a DISTINCT operator, M will be the number of distinct output
  ** rows, so fudge it downwards a bit.
  */
  if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
    nRow = pWInfo->iLimit;
  }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){
    /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
    ** reduces the number of output rows by a factor of 2 */
    if( nRow>10 ) nRow -= 10;  assert( 10==sqlite3LogEst(2) );
  }
  rSortCost += estLog(nRow);
  return rSortCost;
}

/*
** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4340
4341
4342
4343
4344
4345
4346





4347
4348
4349
4350
4351
4352
4353







-
-
-
-
-







            testcase( wsFlags & WHERE_COLUMN_IN );
            if( rc==pWInfo->pOrderBy->nExpr ){
              pWInfo->bOrderedInnerLoop = 1;
              pWInfo->revMask = m;
            }
          }
        }
      }else if( nLoop
            && pWInfo->nOBSat==1
            && (pWInfo->wctrlFlags & (WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX))!=0
            ){
        pWInfo->bOrderedInnerLoop = 1;
      }
    }
    if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
        && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
    ){
      Bitmask revMask = 0;
      int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, 
4528
4529
4530
4531
4532
4533
4534
4535

4536
4537
4538
4539
4540
4541
4542
4378
4379
4380
4381
4382
4383
4384

4385
4386
4387
4388
4389
4390
4391
4392







-
+







**
** 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;
  struct SrcList_item *pItem;
  WhereClause *pWC;
  WhereTerm *pTerm;
  WhereLoop *pLoop;
  int iCur;
  int j;
  Table *pTab;
  Index *pIdx;
4631
4632
4633
4634
4635
4636
4637
4638
4639
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
4481
4482
4483
4484
4485
4486
4487






















4488
4489
4490
4491
4492
4493
4494







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







  w.eCode = 1;
  w.xExprCallback = exprNodeIsDeterministic;
  w.xSelectCallback = sqlite3SelectWalkFail;
  sqlite3WalkExpr(&w, p);
  return w.eCode;
}

  
#ifdef WHERETRACE_ENABLED
/*
** Display all WhereLoops in pWInfo
*/
static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
  if( sqlite3WhereTrace ){    /* Display all of the WhereLoop objects */
    WhereLoop *p;
    int i;
    static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
                                           "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
    for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
      p->cId = zLabel[i%(sizeof(zLabel)-1)];
      sqlite3WhereLoopPrint(p, pWC);
    }
  }
}
# define WHERETRACE_ALL_LOOPS(W,C) showAllWhereLoops(W,C)
#else
# define WHERETRACE_ALL_LOOPS(W,C)
#endif

/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
** information needed to terminate the loop.  Later, the calling routine
** should invoke sqlite3WhereEnd() with the return value of this function
** in order to complete the WHERE clause processing.
**
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
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







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

-







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

-
-


-











-
+







#if defined(WHERETRACE_ENABLED)
  if( sqlite3WhereTrace & 0xffff ){
    sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
    if( wctrlFlags & WHERE_USE_LIMIT ){
      sqlite3DebugPrintf(", limit: %d", iAuxArg);
    }
    sqlite3DebugPrintf(")\n");
    if( sqlite3WhereTrace & 0x100 ){
      Select sSelect;
      memset(&sSelect, 0, sizeof(sSelect));
      sSelect.selFlags = SF_WhereBegin;
      sSelect.pSrc = pTabList;
      sSelect.pWhere = pWhere;
      sSelect.pOrderBy = pOrderBy;
      sSelect.pEList = pResultSet;
      sqlite3TreeViewSelect(0, &sSelect, 0);
    }
  }
  }
  if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
    sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n");
    sqlite3WhereClausePrint(sWLB.pWC);
  }
#endif

  if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
    rc = whereLoopAddAll(&sWLB);
    if( rc ) goto whereBeginError;

  
#ifdef SQLITE_ENABLE_STAT4
    /* If one or more WhereTerm.truthProb values were used in estimating
    ** loop parameters, but then those truthProb values were subsequently
    ** changed based on STAT4 information while computing subsequent loops,
    ** then we need to rerun the whole loop building process so that all
    ** loops will be built using the revised truthProb values. */
    if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){
      WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC);
      WHERETRACE(0xffff, 
#ifdef WHERETRACE_ENABLED
           ("**** Redo all loop computations due to"
            " TERM_HIGHTRUTH changes ****\n"));
      while( pWInfo->pLoops ){
        WhereLoop *p = pWInfo->pLoops;
        pWInfo->pLoops = p->pNextLoop;
        whereLoopDelete(db, p);
    if( sqlite3WhereTrace ){    /* Display all of the WhereLoop objects */
      WhereLoop *p;
      int i;
      static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
                                             "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
      for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
        p->cId = zLabel[i%(sizeof(zLabel)-1)];
        whereLoopPrint(p, sWLB.pWC);
      }
      rc = whereLoopAddAll(&sWLB);
      if( rc ) goto whereBeginError;
    }
#endif
    WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC);
  
    wherePathSolver(pWInfo, 0);
    if( db->mallocFailed ) goto whereBeginError;
    if( pWInfo->pOrderBy ){
       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 ){
  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);
5012
5013
5014
5015
5016
5017
5018
5019

5020
5021
5022
5023
5024
5025
5026
4820
4821
4822
4823
4824
4825
4826

4827
4828
4829
4830
4831
4832
4833
4834







-
+







      case WHERE_DISTINCT_UNORDERED: {
        sqlite3DebugPrintf("  DISTINCT=unordered");
        break;
      }
    }
    sqlite3DebugPrintf("\n");
    for(ii=0; ii<pWInfo->nLevel; ii++){
      sqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
      whereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
    }
  }
#endif

  /* Attempt to omit tables from the join that do not affect the result.
  ** For a table to not affect the result, the following must be true:
  **
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
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







-
-
+
+





-
+













-
+







  **     CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
  **     CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
  **     CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
  **
  ** then table t2 can be omitted from the following:
  **
  **     SELECT v1, v3 FROM t1 
  **       LEFT JOIN t2 ON (t1.ipk=t2.ipk)
  **       LEFT JOIN t3 ON (t1.ipk=t3.ipk)
  **       LEFT JOIN t2 USING (t1.ipk=t2.ipk)
  **       LEFT JOIN t3 USING (t1.ipk=t3.ipk)
  **
  ** or from:
  **
  **     SELECT DISTINCT v1, v3 FROM t1 
  **       LEFT JOIN t2
  **       LEFT JOIN t3 ON (t1.ipk=t3.ipk)
  **       LEFT JOIN t3 USING (t1.ipk=t3.ipk)
  */
  notReady = ~(Bitmask)0;
  if( pWInfo->nLevel>=2
   && pResultSet!=0               /* guarantees condition (1) above */
   && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
  ){
    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;
      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;
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
4902
4903
4904
4905
4906
4907
4908





4909

4910
4911
4912
4913
4914
4915
4916







-
-
-
-
-

-







        int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
        memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
      }
      pWInfo->nLevel--;
      nTabList--;
    }
  }
#if defined(WHERETRACE_ENABLED)
  if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
    sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n");
    sqlite3WhereClausePrint(sWLB.pWC);
  }
  WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
#endif
  pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;

  /* If the caller is an UPDATE or DELETE statement that is requesting
  ** to use a one-pass algorithm, determine if this is appropriate.
  **
  ** A one-pass approach can be used if the caller has requested one
  ** and either (a) the scan visits at most one row or (b) each
5148
5149
5150
5151
5152
5153
5154
5155

5156
5157
5158
5159
5160
5161
5162
4950
4951
4952
4953
4954
4955
4956

4957
4958
4959
4960
4961
4962
4963
4964







-
+








  /* 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;
    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 */
5177
5178
5179
5180
5181
5182
5183
5184

5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
4979
4980
4981
4982
4983
4984
4985

4986






4987
4988
4989
4990
4991
4992
4993







-
+
-
-
-
-
-
-







        op = OP_OpenWrite;
        pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
      };
      sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
      assert( pTabItem->iCursor==pLevel->iTabCur );
      testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
      testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
      if( pWInfo->eOnePass==ONEPASS_OFF 
      if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol<BMS && HasRowid(pTab) ){
       && pTab->nCol<BMS
       && (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
      ){
        /* If we know that only a prefix of the record will be used,
        ** it is advantageous to reduce the "column count" field in
        ** the P4 operand of the OP_OpenRead/Write opcode. */
        Bitmask b = pTabItem->colUsed;
        int n = 0;
        for(; b; b=b>>1, n++){}
        sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32);
        assert( n<=pTab->nCol );
      }
#ifdef SQLITE_ENABLE_CURSOR_HINTS
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254

5255
5256
5257
5258
5259
5260
5261
5038
5039
5040
5041
5042
5043
5044


5045
5046
5047

5048
5049
5050
5051
5052
5053
5054
5055







-
-



-
+







      assert( pIx->pSchema==pTab->pSchema );
      assert( iIndexCur>=0 );
      if( op ){
        sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
        sqlite3VdbeSetP4KeyInfo(pParse, pIx);
        if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
         && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
         && (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0
         && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
         && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
         && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
        ){
          sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ);
          sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
        }
        VdbeComment((v, "%s", pIx->zName));
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
        {
          u64 colUsed = 0;
          int ii, jj;
          for(ii=0; ii<pIx->nColumn; ii++){
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5095
5096
5097
5098
5099
5100
5101

5102
5103
5104
5105
5106
5107
5108







-







    if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
      sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
    }
  }

  /* Done. */
  VdbeModuleComment((v, "Begin WHERE-core"));
  pWInfo->iEndWhere = sqlite3VdbeCurrentAddr(v);
  return pWInfo;

  /* Jump here if malloc fails */
whereBeginError:
  if( pWInfo ){
    pParse->nQueryLoop = pWInfo->savedNQueryLoop;
    whereInfoFree(db, pWInfo);
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370

5371
5372
5373
5374
5375
5376
5377
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







-

















-
+







  Parse *pParse = pWInfo->pParse;
  Vdbe *v = pParse->pVdbe;
  int i;
  WhereLevel *pLevel;
  WhereLoop *pLoop;
  SrcList *pTabList = pWInfo->pTabList;
  sqlite3 *db = pParse->db;
  int iEnd = sqlite3VdbeCurrentAddr(v);

  /* Generate loop termination code.
  */
  VdbeModuleComment((v, "End WHERE-core"));
  for(i=pWInfo->nLevel-1; i>=0; i--){
    int addr;
    pLevel = &pWInfo->a[i];
    pLoop = pLevel->pWLoop;
    if( pLevel->op!=OP_Noop ){
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
      int addrSeek = 0;
      Index *pIdx;
      int n;
      if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
       && i==pWInfo->nLevel-1  /* Ticket [ef9318757b152e3] 2017-10-21 */
       && (pLoop->wsFlags & WHERE_INDEXED)!=0
       && (pIdx = pLoop->u.btree.pIndex)->hasStat1
       && (n = pLoop->u.btree.nDistinctCol)>0
       && (n = pLoop->u.btree.nIdxCol)>0
       && pIdx->aiRowLogEst[n]>=36
      ){
        int r1 = pParse->nMem+1;
        int j, op;
        for(j=0; j<n; j++){
          sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j);
        }
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415

5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433




5434
5435
5436
5437
5438
5439
5440
5441
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







-
-
-
-
-














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







      sqlite3VdbeResolveLabel(v, pLevel->addrCont);
      sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
      sqlite3VdbeChangeP5(v, pLevel->p5);
      VdbeCoverage(v);
      VdbeCoverageIf(v, pLevel->op==OP_Next);
      VdbeCoverageIf(v, pLevel->op==OP_Prev);
      VdbeCoverageIf(v, pLevel->op==OP_VNext);
      if( pLevel->regBignull ){
        sqlite3VdbeResolveLabel(v, pLevel->addrBignull);
        sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1);
        VdbeCoverage(v);
      }
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
      if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
#endif
    }else{
      sqlite3VdbeResolveLabel(v, pLevel->addrCont);
    }
    if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
      struct InLoop *pIn;
      int j;
      sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
      for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
        sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
        if( pIn->eEndLoopOp!=OP_Noop ){
          if( pIn->nPrefix ){
            int bEarlyOut = 
                (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
                 && (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0;
            assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
            if( pLevel->iLeftJoin ){
              /* For LEFT JOIN queries, cursor pIn->iCur may not have been
              ** opened yet. This occurs for WHERE clauses such as
              ** "a = ? AND b IN (...)", where the index is on (a, b). If
              ** the RHS of the (a=?) is NULL, then the "b IN (...)" may
              ** never have been coded, but the body of the loop run to
              ** return the null-row. So, if the cursor is not open yet,
              ** jump over the OP_Next or OP_Prev instruction about to
              ** be coded.  */
              sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, 
                  sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut);
              VdbeCoverage(v);
            }
            if( bEarlyOut ){
              sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
                  sqlite3VdbeCurrentAddr(v)+2,
                  pIn->iBase, pIn->nPrefix);
              VdbeCoverage(v);
            sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
                              sqlite3VdbeCurrentAddr(v)+2,
                              pIn->iBase, pIn->nPrefix);
            VdbeCoverage(v);
            }
          }
          sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
          VdbeCoverage(v);
          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev);
          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next);
        }
        sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
5483
5484
5485
5486
5487
5488
5489
5490

5491
5492

5493
5494
5495
5496
5497
5498
5499
5253
5254
5255
5256
5257
5258
5259

5260
5261

5262
5263
5264
5265
5266
5267
5268
5269







-
+

-
+







  ** Set it.
  */
  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;
    VdbeOp *pOp;
    Index *pIdx = 0;
    SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
    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.
5541
5542
5543
5544
5545
5546
5547

5548
5549
5550
5551

5552
5553
5554
5555

5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567

5568
5569
5570

5571
5572

5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587

5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606

5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320


5321




5322
5323
5324
5325
5326





5327
5328

5329



5330


5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341



5342

5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358




5359
5360
5361
5362
5363
5364
5365








5366
5367
5368
5369
5370
5371







+


-
-
+
-
-
-
-
+




-
-
-
-
-


-
+
-
-
-
+
-
-
+










-
-
-

-
+















-
-
-
-
+






-
-
-
-
-
-
-
-






    */
    if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
      pIdx = pLoop->u.btree.pIndex;
    }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
      pIdx = pLevel->u.pCovidx;
    }
    if( pIdx
     && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable))
     && !db->mallocFailed
    ){
      if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){
        last = iEnd;
      last = sqlite3VdbeCurrentAddr(v);
      }else{
        last = pWInfo->iEndWhere;
      }
      k = pLevel->addrBody + 1;
      k = pLevel->addrBody;
#ifdef SQLITE_DEBUG
      if( db->flags & SQLITE_VdbeAddopTrace ){
        printf("TRANSLATE opcodes in range %d..%d\n", k, last-1);
      }
      /* Proof that the "+1" on the k value above is safe */
      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);
      for(; k<last; k++, pOp++){
      assert( pOp<pLastOp || (pParse->nErr>0 && pOp==pLastOp) );
      do{
        if( pOp->p1!=pLevel->iTabCur ){
        if( pOp->p1!=pLevel->iTabCur ) continue;
          /* no-op */
        }else if( pOp->opcode==OP_Column
        if( pOp->opcode==OP_Column
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
         || pOp->opcode==OP_Offset
#endif
        ){
          int x = pOp->p2;
          assert( pIdx->pTable==pTab );
          if( !HasRowid(pTab) ){
            Index *pPk = sqlite3PrimaryKeyIndex(pTab);
            x = pPk->aiColumn[x];
            assert( x>=0 );
          }else{
            testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
            x = sqlite3StorageColumnToTable(pTab,x);
          }
          x = sqlite3TableColumnToIndex(pIdx, x);
          x = sqlite3ColumnOfIndex(pIdx, x);
          if( x>=0 ){
            pOp->p2 = x;
            pOp->p1 = pLevel->iIdxCur;
            OpcodeRewriteTrace(db, k, pOp);
          }
          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 
              || pWInfo->eOnePass );
        }else if( pOp->opcode==OP_Rowid ){
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRowid;
          OpcodeRewriteTrace(db, k, pOp);
        }else if( pOp->opcode==OP_IfNullRow ){
          pOp->p1 = pLevel->iIdxCur;
          OpcodeRewriteTrace(db, k, pOp);
        }
#ifdef SQLITE_DEBUG
        k++;
#endif
      }while( (++pOp)<pLastOp );
      }
#ifdef SQLITE_DEBUG
      if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n");
#endif
    }
  }

  /* Undo all Expr node modifications */
  while( pWInfo->pExprMods ){
    WhereExprMod *p = pWInfo->pExprMods;
    pWInfo->pExprMods = p->pNext;
    memcpy(p->pExpr, &p->orig, sizeof(p->orig));
    sqlite3DbFree(db, p);
  }

  /* Final cleanup
  */
  pParse->nQueryLoop = pWInfo->savedNQueryLoop;
  whereInfoFree(db, pWInfo);
  return;
}

Changes to src/whereInt.h.

10
11
12
13
14
15
16
17
18
19













20
21
22
23
24
25
26
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







-
-

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







**
*************************************************************************
**
** 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;
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
65
66
67
68
69
70
71


72
73
74
75
76
77

78
79
80
81
82
83
84
85







-
-






-
+







  int iIdxCur;          /* The VDBE cursor used to access pIdx */
  int addrBrk;          /* Jump here to break out of the loop */
  int addrNxt;          /* Jump here to start the next IN combination */
  int addrSkip;         /* Jump here for next iteration of skip-scan */
  int addrCont;         /* Jump here to continue with the next loop cycle */
  int addrFirst;        /* First instruction of interior of the loop */
  int addrBody;         /* Beginning of the body of this loop */
  int regBignull;       /* big-null flag reg. True if a NULL-scan is needed */
  int addrBignull;      /* Jump here for next part of big-null scan */
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
  u32 iLikeRepCntr;     /* LIKE range processing counter register (times 2) */
  int addrLikeRep;      /* LIKE range processing address */
#endif
  u8 iFrom;             /* Which entry in the FROM clause */
  u8 op, p3, p5;        /* Opcode, P3 & P5 of the opcode that ends the loop */
  int p1, p2;           /* Operands of the opcode used to end the loop */
  int p1, p2;           /* Operands of the opcode used to ends the loop */
  union {               /* Information that depends on pWLoop->wsFlags */
    struct {
      int nIn;              /* Number of entries in aInLoop[] */
      struct InLoop {
        int iCur;              /* The VDBE cursor used by this IN operator */
        int addrInTop;         /* Top of the IN loop */
        int iBase;             /* Base register of multi-key index record */
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







  LogEst rRun;          /* Cost of running each loop */
  LogEst nOut;          /* Estimated number of output rows */
  union {
    struct {               /* Information for internal btree tables */
      u16 nEq;               /* Number of equality constraints */
      u16 nBtm;              /* Size of BTM vector */
      u16 nTop;              /* Size of TOP vector */
      u16 nDistinctCol;      /* Index columns used to sort for DISTINCT */
      u16 nIdxCol;           /* Index column used for ORDER BY */
      Index *pIndex;         /* Index used, or NULL */
    } btree;
    struct {               /* Information for virtual tables */
      int idxNum;            /* Index number */
      u8 needFree;           /* True if sqlite3_free(idxStr) is needed */
      i8 isOrdered;          /* True if satisfies ORDER BY */
      u16 omitMask;          /* Terms that may be omitted */
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
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







+

-
-
+
-
-










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

-
-
-
-
-
-







  LogEst truthProb;       /* Probability of truth for this expression */
  u16 wtFlags;            /* TERM_xxx bit flags.  See below */
  u16 eOperator;          /* A WO_xx value describing <op> */
  u8 nChild;              /* Number of children that must disable us */
  u8 eMatchOp;            /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
  int iParent;            /* Disable pWC->a[iParent] when this term disabled */
  int leftCursor;         /* Cursor number of X in "X <op> <expr>" */
  int iField;             /* Field in (?,?,?) IN (SELECT...) vector */
  union {
    struct {
      int leftColumn;         /* Column number of X in "X <op> <expr>" */
    int leftColumn;         /* Column number of X in "X <op> <expr>" */
      int iField;             /* Field in (?,?,?) IN (SELECT...) vector */
    } x;                    /* Opcode other than OP_OR or OP_AND */
    WhereOrInfo *pOrInfo;   /* Extra information if (eOperator & WO_OR)!=0 */
    WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
  } u;
  Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
  Bitmask prereqAll;      /* Bitmask of tables referenced by pExpr */
};

/*
** Allowed values of WhereTerm.wtFlags
*/
#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_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(db, pExpr) */
#define TERM_VIRTUAL    0x02   /* Added by the optimizer.  Do not code */
#define TERM_CODED      0x04   /* This term is already coded */
#define TERM_COPIED     0x08   /* Has a child */
#define TERM_ORINFO     0x10   /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO    0x20   /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK      0x40   /* Used during OR-clause processing */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
#  define TERM_VNULL    0x80   /* Manufactured x>NULL or x<=NULL term */
#else
#  define TERM_VNULL    0x00   /* Disabled if not using stat3 */
#endif
#define TERM_LIKEOPT    0x100  /* Virtual terms from the LIKE optimization */
#define TERM_LIKECOND   0x200  /* Conditionally this LIKE operator term */
#define TERM_LIKE       0x400  /* The original LIKE operator */
#define TERM_IS         0x800  /* 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
#  define TERM_HIGHTRUTH  0x4000 /* Term excludes few rows */
#else
#  define TERM_HIGHTRUTH  0      /* Only used with STAT4 */
#endif

/*
** An instance of the WhereScan object is used as an iterator for locating
** terms in the WHERE clause that are useful to the query planner.
*/
struct WhereScan {
  WhereClause *pOrigWC;      /* Original, innermost WhereClause */
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
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







-
+



-
+
-




-
-
+
+
-
-







*/
struct WhereLoopBuilder {
  WhereInfo *pWInfo;        /* Information about this WHERE */
  WhereClause *pWC;         /* WHERE clause terms */
  ExprList *pOrderBy;       /* ORDER BY clause */
  WhereLoop *pNew;          /* Template WhereLoop */
  WhereOrSet *pOrSet;       /* Record best loops here, if not NULL */
#ifdef SQLITE_ENABLE_STAT4
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  UnpackedRecord *pRec;     /* Probe for stat4 (if required) */
  int nRecValid;            /* Number of valid fields currently in pRec */
#endif
  unsigned char bldFlags1;  /* First set of SQLITE_BLDF_* flags */
  unsigned int bldFlags;    /* SQLITE_BLDF_* flags */
  unsigned char bldFlags2;  /* Second set of SQLITE_BLDF_* flags */
  unsigned int iPlanLimit;  /* Search limiter */
};

/* Allowed values for WhereLoopBuider.bldFlags */
#define SQLITE_BLDF1_INDEXED  0x0001   /* An index is used */
#define SQLITE_BLDF1_UNIQUE   0x0002   /* All keys of a UNIQUE index used */
#define SQLITE_BLDF_INDEXED  0x0001   /* An index is used */
#define SQLITE_BLDF_UNIQUE   0x0002   /* All keys of a UNIQUE index used */

#define SQLITE_BLDF2_2NDPASS  0x0004   /* Second builder pass needed */

/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
** index+constraint combinations the query planner will consider for a
** particular query.  If this parameter is unlimited, then certain
** pathological queries can spend excess time in the sqlite3WhereBegin()
** routine.  The limit is high enough that is should not impact real-world
** queries.
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
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







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
















+





-


+

+

-
-
-
+
-
-

-

-

+













-
-







#ifndef SQLITE_QUERY_PLANNER_LIMIT
# define SQLITE_QUERY_PLANNER_LIMIT 20000
#endif
#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
#endif

/*
** Each instance of this object records a change to a single node
** in an expression tree to cause that node to point to a column
** of an index rather than an expression or a virtual column.  All
** such transformations need to be undone at the end of WHERE clause
** processing.
*/
typedef struct WhereExprMod WhereExprMod;
struct WhereExprMod {
  WhereExprMod *pNext;  /* Next translation on a list of them all */
  Expr *pExpr;          /* The Expr node that was transformed */
  Expr orig;            /* Original value of the Expr node */
};

/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed
** into the second half to give some continuity.
**
** An instance of this object holds the complete state of the query
** planner.
*/
struct WhereInfo {
  Parse *pParse;            /* Parsing and code generating context */
  SrcList *pTabList;        /* List of tables in the join */
  ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
  ExprList *pResultSet;     /* Result set of the query */
  Expr *pWhere;             /* The complete WHERE clause */
  LogEst iLimit;            /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
  int aiCurOnePass[2];      /* OP_OpenWrite cursors for the ONEPASS opt */
  int iContinue;            /* Jump here to continue with next record */
  int iBreak;               /* Jump here to break out of the loop */
  int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
  u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
  LogEst iLimit;            /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
  u8 nLevel;                /* Number of nested loop */
  i8 nOBSat;                /* Number of ORDER BY terms satisfied by indices */
  u8 sorted;                /* True if really sorted (not just grouped) */
  u8 eOnePass;              /* ONEPASS_OFF, or _SINGLE, or _MULTI */
  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values */
  unsigned bDeferredSeek :1;   /* Uses OP_DeferredSeek */
  unsigned untestedTerms :1;   /* Not all WHERE terms resolved by outer loop */
  unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */
  u8 bOrderedInnerLoop;     /* True if only the inner-most loop is ordered */
  unsigned sorted :1;          /* True if really sorted (not just grouped) */
  LogEst nRowOut;           /* Estimated number of output rows */
  int iTop;                 /* The very beginning of the WHERE loop */
  int iEndWhere;            /* End of the WHERE clause itself */
  WhereLoop *pLoops;        /* List of all WhereLoop objects */
  WhereExprMod *pExprMods;  /* Expression modifications */
  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
  LogEst nRowOut;           /* Estimated number of output rows */
  WhereClause sWC;          /* Decomposition of the WHERE clause */
  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
  WhereLevel a[1];          /* Information about each nest loop in WHERE */
};

/*
** Private interfaces - callable only by other where.c routines.
**
** where.c:
*/
Bitmask sqlite3WhereGetMask(WhereMaskSet*,int);
#ifdef WHERETRACE_ENABLED
void sqlite3WhereClausePrint(WhereClause *pWC);
void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm);
void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC);
#endif
WhereTerm *sqlite3WhereFindTerm(
  WhereClause *pWC,     /* The WHERE clause to be searched */
  int iCur,             /* Cursor number of LHS */
  int iColumn,          /* Column number of LHS */
  Bitmask notReady,     /* RHS must not overlap with this mask */
  u32 op,               /* Mask of WO_xx values describing operator */
536
537
538
539
540
541
542
543

544
545
546
547
548
549
550
519
520
521
522
523
524
525

526
527
528
529
530
531
532
533







-
+







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*);
void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);





/*
** Bitmasks for the operators on WhereTerm objects.  These are all
597
598
599
600
601
602
603
604
605
606
607
580
581
582
583
584
585
586











-
-
-
-
#define WHERE_ONEROW       0x00001000  /* Selects no more than one row */
#define WHERE_MULTI_OR     0x00002000  /* OR using multiple indices */
#define WHERE_AUTO_INDEX   0x00004000  /* Uses an ephemeral index */
#define WHERE_SKIPSCAN     0x00008000  /* Uses the skip-scan algorithm */
#define WHERE_UNQ_WANTED   0x00010000  /* WHERE_ONEROW would have been helpful*/
#define WHERE_PARTIALIDX   0x00020000  /* The automatic index is partial */
#define WHERE_IN_EARLYOUT  0x00040000  /* Perhaps quit IN loops early */
#define WHERE_BIGNULL_SORT 0x00080000  /* Column nEq of index is BIGNULL */
#define WHERE_IN_SEEKSCAN  0x00100000  /* Seek-scan optimization for IN */

#endif /* !defined(SQLITE_WHEREINT_H) */

Changes to src/wherecode.c.

125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
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];
    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 */
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
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







-
-
-
+
+
+












-
-
+
+

-
-
+




-
+







  }
}

/*
** Code an OP_Affinity opcode to apply the column affinity string zAff
** to the n registers starting at base. 
**
** As an optimization, SQLITE_AFF_BLOB and SQLITE_AFF_NONE entries (which
** are no-ops) at the beginning and end of zAff are ignored.  If all entries
** in zAff are SQLITE_AFF_BLOB or SQLITE_AFF_NONE, then no code gets generated.
** As an optimization, SQLITE_AFF_BLOB entries (which are no-ops) at the
** beginning and end of zAff are ignored.  If all entries in zAff are
** SQLITE_AFF_BLOB, then no code gets generated.
**
** This routine makes its own copy of zAff so that the caller is free
** to modify zAff after this routine returns.
*/
static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
  Vdbe *v = pParse->pVdbe;
  if( zAff==0 ){
    assert( pParse->db->mallocFailed );
    return;
  }
  assert( v!=0 );

  /* Adjust base and n to skip over SQLITE_AFF_BLOB and SQLITE_AFF_NONE
  ** entries at the beginning and end of the affinity string.
  /* Adjust base and n to skip over SQLITE_AFF_BLOB entries at the beginning
  ** and end of the affinity string.
  */
  assert( SQLITE_AFF_NONE<SQLITE_AFF_BLOB );
  while( n>0 && zAff[0]<=SQLITE_AFF_BLOB ){
  while( n>0 && zAff[0]==SQLITE_AFF_BLOB ){
    n--;
    base++;
    zAff++;
  }
  while( n>1 && zAff[n-1]<=SQLITE_AFF_BLOB ){
  while( n>1 && zAff[n-1]==SQLITE_AFF_BLOB ){
    n--;
  }

  /* Code the OP_Affinity opcode if there is anything left to do. */
  if( n>0 ){
    sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n);
  }
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
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







-
-
+










-
+







static Expr *removeUnindexableInClauseTerms(
  Parse *pParse,        /* The parsing context */
  int iEq,              /* Look at loop terms starting here */
  WhereLoop *pLoop,     /* The current loop */
  Expr *pX              /* The IN expression to be reduced */
){
  sqlite3 *db = pParse->db;
  Expr *pNew;
  pNew = sqlite3ExprDup(db, pX, 0);
  Expr *pNew = sqlite3ExprDup(db, pX, 0);
  if( db->mallocFailed==0 ){
    ExprList *pOrigRhs = pNew->x.pSelect->pEList;  /* Original unmodified RHS */
    ExprList *pOrigLhs = pNew->pLeft->x.pList;     /* Original unmodified LHS */
    ExprList *pRhs = 0;         /* New RHS after modifications */
    ExprList *pLhs = 0;         /* New LHS after mods */
    int i;                      /* Loop counter */
    Select *pSelect;            /* Pointer to the SELECT on the RHS */

    for(i=iEq; i<pLoop->nLTerm; i++){
      if( pLoop->aLTerm[i]->pExpr==pX ){
        int iField = pLoop->aLTerm[i]->u.x.iField - 1;
        int iField = pLoop->aLTerm[i]->iField - 1;
        if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
        pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
        pOrigRhs->a[iField].pExpr = 0;
        assert( pOrigLhs->a[iField].pExpr!=0 );
        pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
        pOrigLhs->a[iField].pExpr = 0;
      }
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
564
565
566
567
568
569
570



571
572
573
574
575
576
577







-
-
-







    VdbeCoverageIf(v, !bRev);
    assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );

    pLoop->wsFlags |= WHERE_IN_ABLE;
    if( pLevel->u.in.nIn==0 ){
      pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
    }
    if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
      pLoop->wsFlags |= WHERE_IN_EARLYOUT;
    }

    i = pLevel->u.in.nIn;
    pLevel->u.in.nIn += nEq;
    pLevel->u.in.aInLoop =
       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
    pIn = pLevel->u.in.aInLoop;
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
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







-
+


+









-
-
-
-
-
-
-
-







            int iCol = aiMap ? aiMap[iMap++] : 0;
            pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
          }
          sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
          if( i==iEq ){
            pIn->iCur = iTab;
            pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
            if( iEq>0 ){
            if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
              pIn->iBase = iReg - i;
              pIn->nPrefix = i;
              pLoop->wsFlags |= WHERE_IN_EARLYOUT;
            }else{
              pIn->nPrefix = 0;
            }
          }else{
            pIn->eEndLoopOp = OP_Noop;
          }
          pIn++;
        }
      }
      testcase( iEq>0
                && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
                && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 );
      if( iEq>0 
       && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0
      ){
        sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq);
      }
    }else{
      pLevel->u.in.nIn = 0;
    }
    sqlite3DbFree(pParse->db, aiMap);
#endif
  }
  disableTerm(pLevel, pTerm);
830
831
832
833
834
835
836
837

838
839
840
841
842
843
844
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832







-
+







** accessed through the index.  If it cannot, then set pWalker->eCode to 1.
*/
static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
  struct CCurHint *pHint = pWalker->u.pCCurHint;
  assert( pHint->pIdx!=0 );
  if( pExpr->op==TK_COLUMN
   && pExpr->iTable==pHint->iTabCur
   && sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0
   && sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn)<0
  ){
    pWalker->eCode = 1;
  }
  return WRC_Continue;
}

/*
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
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







-
+



















-
+







    if( pExpr->iTable!=pHint->iTabCur ){
      int reg = ++pWalker->pParse->nMem;   /* Register for column value */
      sqlite3ExprCode(pWalker->pParse, pExpr, reg);
      pExpr->op = TK_REGISTER;
      pExpr->iTable = reg;
    }else if( pHint->pIdx!=0 ){
      pExpr->iTable = pHint->iIdxCur;
      pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn);
      pExpr->iColumn = sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn);
      assert( pExpr->iColumn>=0 );
    }
  }else if( pExpr->op==TK_AGG_FUNCTION ){
    /* An aggregate function in the WHERE clause of a query means this must
    ** be a correlated sub-query, and expression pExpr is an aggregate from
    ** the parent context. Do not walk the function arguments in this case.
    **
    ** todo: It should be possible to replace this node with a TK_REGISTER
    ** expression, as the result of the expression must be stored in a 
    ** register at this point. The same holds for TK_AGG_COLUMN nodes. */
    rc = WRC_Prune;
  }
  return rc;
}

/*
** Insert an OP_CursorHint instruction if it is appropriate to do so.
*/
static void codeCursorHint(
  SrcItem *pTabItem,  /* FROM clause item */
  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;
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
1009







-
+







      sWalker.eCode = 0;
      sWalker.xExprCallback = codeCursorHintCheckExpr;
      sqlite3WalkExpr(&sWalker, pTerm->pExpr);
      if( sWalker.eCode ) continue;
    }

    /* If we survive all prior tests, that means this term is worth hinting */
    pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
    pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
  }
  if( pExpr!=0 ){
    sWalker.xExprCallback = codeCursorHintFixExpr;
    sqlite3WalkExpr(&sWalker, pExpr);
    sqlite3VdbeAddOp4(v, OP_CursorHint, 
                      (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0,
                      (const char*)pExpr, P4_EXPR);
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
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







-






-
+



-

-
+
-
-
-







){
  Parse *pParse = pWInfo->pParse; /* Parse context */
  Vdbe *v = pParse->pVdbe;        /* Vdbe to generate code within */

  assert( iIdxCur>0 );
  assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 );
  
  pWInfo->bDeferredSeek = 1;
  sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
  if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
   && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
  ){
    int i;
    Table *pTab = pIdx->pTable;
    u32 *ai = (u32*)sqlite3DbMallocZero(pParse->db, sizeof(u32)*(pTab->nCol+1));
    int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*(pTab->nCol+1));
    if( ai ){
      ai[0] = pTab->nCol;
      for(i=0; i<pIdx->nColumn-1; i++){
        int x1, x2;
        assert( pIdx->aiColumn[i]<pTab->nCol );
        x1 = pIdx->aiColumn[i];
        if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]+1] = i+1;
        x2 = sqlite3TableColumnToStorage(pTab, x1);
        testcase( x1!=x2 );
        if( x1>=0 ) ai[x2+1] = i+1;
      }
      sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY);
    }
  }
}

/*
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
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







-
-
-


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









-
-




-
-
-






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




-
-
-
-









-



-
+
-
-
-
-
-

+



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

+







** down through the Walker.
*/
typedef struct IdxExprTrans {
  Expr *pIdxExpr;    /* The index expression */
  int iTabCur;       /* The cursor of the corresponding table */
  int iIdxCur;       /* The cursor for the index */
  int iIdxCol;       /* The column for the index */
  int iTabCol;       /* The column for the table */
  WhereInfo *pWInfo; /* Complete WHERE clause information */
  sqlite3 *db;       /* Database connection (for malloc()) */
} IdxExprTrans;

/*
** Preserve pExpr on the WhereETrans list of the WhereInfo.
*/
static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){
  WhereExprMod *pNew;
  pNew = sqlite3DbMallocRaw(pTrans->db, sizeof(*pNew));
  if( pNew==0 ) return;
  pNew->pNext = pTrans->pWInfo->pExprMods;
  pTrans->pWInfo->pExprMods = pNew;
  pNew->pExpr = pExpr;
  memcpy(&pNew->orig, pExpr, sizeof(*pExpr));
}

/* The walker node callback used to transform matching expressions into
** a reference to an index column for an index on an expression.
**
** If pExpr matches, then transform it into a reference to the index column
** that contains the value of pExpr.
*/
static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
  IdxExprTrans *pX = p->u.pIdxTrans;
  if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
    preserveExpr(pX, pExpr);
    pExpr->affExpr = sqlite3ExprAffinity(pExpr);
    pExpr->op = TK_COLUMN;
    pExpr->iTable = pX->iIdxCur;
    pExpr->iColumn = pX->iIdxCol;
    pExpr->y.pTab = 0;
    testcase( ExprHasProperty(pExpr, EP_Skip) );
    testcase( ExprHasProperty(pExpr, EP_Unlikely) );
    ExprClearProperty(pExpr, EP_Skip|EP_Unlikely);
    return WRC_Prune;
  }else{
    return WRC_Continue;
  }
}

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* A walker node callback that translates a column reference to a table
** into a corresponding column reference of an index.
*/
static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){
  if( pExpr->op==TK_COLUMN ){
    IdxExprTrans *pX = p->u.pIdxTrans;
    if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){
      assert( pExpr->y.pTab!=0 );
      preserveExpr(pX, pExpr);
      pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn);
      pExpr->iTable = pX->iIdxCur;
      pExpr->iColumn = pX->iIdxCol;
      pExpr->y.pTab = 0;
    }
  }
  return WRC_Continue;
}
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */

/*
** For an indexes on expression X, locate every instance of expression X
** in pExpr and change that subexpression into a reference to the appropriate
** column of the index.
**
** 2019-10-24: Updated to also translate references to a VIRTUAL column in
** the table into references to the corresponding (stored) column of the
** index.
*/
static void whereIndexExprTrans(
  Index *pIdx,      /* The Index */
  int iTabCur,      /* Cursor of the table that is being indexed */
  int iIdxCur,      /* Cursor of the index itself */
  WhereInfo *pWInfo /* Transform expressions in this WHERE clause */
){
  int iIdxCol;               /* Column number of the index */
  ExprList *aColExpr;        /* Expressions that are indexed */
  Table *pTab;
  Walker w;
  IdxExprTrans x;
  aColExpr = pIdx->aColExpr;
  if( aColExpr==0 && !pIdx->bHasVCol ){
  if( aColExpr==0 ) return;  /* Not an index on expressions */
    /* The index does not reference any expressions or virtual columns
    ** so no translations are needed. */
    return;
  }
  pTab = pIdx->pTable;
  memset(&w, 0, sizeof(w));
  w.xExprCallback = whereIndexExprTransNode;
  w.u.pIdxTrans = &x;
  x.iTabCur = iTabCur;
  x.iIdxCur = iIdxCur;
  x.pWInfo = pWInfo;
  x.db = pWInfo->pParse->db;
  for(iIdxCol=0; iIdxCol<pIdx->nColumn; iIdxCol++){
    i16 iRef = pIdx->aiColumn[iIdxCol];
  for(iIdxCol=0; iIdxCol<aColExpr->nExpr; iIdxCol++){
    if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue;
    if( iRef==XN_EXPR ){
      assert( aColExpr->a[iIdxCol].pExpr!=0 );
    assert( aColExpr->a[iIdxCol].pExpr!=0 );
      x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
      if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue;
      w.xExprCallback = whereIndexExprTransNode;
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
    }else if( iRef>=0
       && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0
       && (pTab->aCol[iRef].zColl==0
           || sqlite3StrICmp(pTab->aCol[iRef].zColl, sqlite3StrBINARY)==0)
    ){
      /* Check to see if there are direct references to generated columns
      ** that are contained in the index.  Pulling the generated column
      ** out of the index is an optimization only - the main table is always
      ** available if the index cannot be used.  To avoid unnecessary
      ** complication, omit this optimization if the collating sequence for
      ** the column is non-standard */
      x.iTabCol = iRef;
      w.xExprCallback = whereIndexExprTransColumn;
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
    }else{
      continue;
    }
    x.iIdxCol = iIdxCol;
    x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
    sqlite3WalkExpr(&w, pWInfo->pWhere);
    sqlite3WalkExprList(&w, pWInfo->pOrderBy);
    sqlite3WalkExprList(&w, pWInfo->pResultSet);
  }
}

/*
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
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







-
+
















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







  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 */
  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 */

  pWC = &pWInfo->sWC;
  db = pParse->db;
  pLoop = pLevel->pWLoop;
  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  iCur = pTabItem->iCursor;
  pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
  bRev = (pWInfo->revMask>>iLevel)&1;
  VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
#if WHERETRACE_ENABLED /* 0x20800 */
  if( sqlite3WhereTrace & 0x800 ){
    sqlite3DebugPrintf("Coding level %d of %d:  notReady=%llx  iFrom=%d\n",
       iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom);
    sqlite3WhereLoopPrint(pLoop, pWC);
  }
  if( sqlite3WhereTrace & 0x20000 ){
    if( iLevel==0 ){
      sqlite3DebugPrintf("WHERE clause being coded:\n");
      sqlite3TreeViewExpr(0, pWInfo->pWhere, 0);
    }
    sqlite3DebugPrintf("All WHERE-clause terms before coding:\n");
    sqlite3WhereClausePrint(pWC);
  }
#endif

  /* Create labels for the "break" and "continue" instructions
  ** for the current loop.  Jump to addrBrk to break out of a loop.
  ** Jump to cont to go immediately to the next iteration of the
  ** loop.
  **
  ** When there is an IN operator, we also have a "addrNxt" label that
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431


1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448

1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
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







-
-
-






-


-
+
-
-










-
-
+
+
















-
+
-
-






-







    sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
    sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
    sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
                      pLoop->u.vtab.idxStr,
                      pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
    VdbeCoverage(v);
    pLoop->u.vtab.needFree = 0;
    /* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed
    ** the u.vtab.idxStr.  NULL it out to prevent a use-after-free */
    if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
    pLevel->p1 = iCur;
    pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
    pLevel->p2 = sqlite3VdbeCurrentAddr(v);
    iIn = pLevel->u.in.nIn;
    for(j=nConstraint-1; j>=0; j--){
      pTerm = pLoop->aLTerm[j];
      if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
      if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
        disableTerm(pLevel, pTerm);
      }else if( (pTerm->eOperator & WO_IN)!=0
      }else if( (pTerm->eOperator & WO_IN)!=0 ){
        && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1
      ){
        Expr *pCompare;  /* The comparison operator */
        Expr *pRight;    /* RHS of the comparison */
        VdbeOp *pOp;     /* Opcode to access the value of the IN constraint */

        /* Reload the constraint value into reg[iReg+j+2].  The same value
        ** was loaded into the same register prior to the OP_VFilter, but
        ** the xFilter implementation might have changed the datatype or
        ** encoding of the value in the register, so it *must* be reloaded. */
        assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
        if( !db->mallocFailed ){
          assert( iIn>=0 && iIn<pLevel->u.in.nIn );
          pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
          assert( iIn>0 );
          pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[--iIn].addrInTop);
          assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
          assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
          assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
          testcase( pOp->opcode==OP_Rowid );
          sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
        }

        /* Generate code that will continue to the next row if 
        ** the IN constraint is not satisfied */
        pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
        assert( pCompare!=0 || db->mallocFailed );
        if( pCompare ){
          pCompare->pLeft = pTerm->pExpr->pLeft;
          pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
          if( pRight ){
            pRight->iTable = iReg+j+2;
            sqlite3ExprIfFalse(
            sqlite3ExprIfFalse(pParse, pCompare, pLevel->addrCont, 0);
                pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
            );
          }
          pCompare->pLeft = 0;
          sqlite3ExprDelete(db, pCompare);
        }
      }
    }
    assert( iIn==0 || db->mallocFailed );
    /* These registers need to be preserved in case there is an IN operator
    ** loop.  So we could deallocate the registers here (and potentially
    ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0.  But it seems
    ** simpler and safer to simply not reuse the registers.
    **
    **    sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
    */
1658
1659
1660
1661
1662
1663
1664
1665

1666
1667
1668
1669
1670




















1671
1672
1673
1674
1675
1676
1677
1544
1545
1546
1547
1548
1549
1550

1551

1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582







-
+
-




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







    int nExtraReg = 0;           /* Number of extra registers needed */
    int op;                      /* Instruction opcode */
    char *zStartAff;             /* Affinity for start of range constraint */
    char *zEndAff = 0;           /* Affinity for end of range constraint */
    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */
    int omitTable;               /* True if we use the index only */
    int regBignull = 0;          /* big-null flag register */

    int addrSeekScan = 0;        /* Opcode of the OP_SeekScan, if any */

    pIdx = pLoop->u.btree.pIndex;
    iIdxCur = pLevel->iIdxCur;
    assert( nEq>=pLoop->nSkip );

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 
    ** query, then the caller will only allow the loop to run for
    ** a single iteration. This means that the first row returned
    ** should not have a NULL value stored in 'x'. If column 'x' is
    ** the first one after the nEq equality constraints in the index,
    ** this requires some special handling.
    */
    assert( pWInfo->pOrderBy==0
         || pWInfo->pOrderBy->nExpr==1
         || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
    if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
     && pWInfo->nOBSat>0
     && (pIdx->nKeyCol>nEq)
    ){
      assert( pLoop->nSkip==0 );
      bSeekPastNull = 1;
      nExtraReg = 1;
    }

    /* Find any inequality constraint terms for the start and end 
    ** of the range. 
    */
    j = nEq;
    if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
      pRangeStart = pLoop->aLTerm[j++];
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762

1763
1764
1765
1766
1767
1768
1769
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







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












-
-
-
-
-
-










-
+







        if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){
          bSeekPastNull = 1;
        }
      }
    }
    assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );

    /* If the WHERE_BIGNULL_SORT flag is set, then index column nEq uses
    ** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS 
    ** FIRST). In both cases separate ordered scans are made of those
    ** index entries for which the column is null and for those for which
    ** it is not. For an ASC sort, the non-NULL entries are scanned first.
    ** For DESC, NULL entries are scanned first.
    */
    if( (pLoop->wsFlags & (WHERE_TOP_LIMIT|WHERE_BTM_LIMIT))==0
     && (pLoop->wsFlags & WHERE_BIGNULL_SORT)!=0
    ){
      assert( bSeekPastNull==0 && nExtraReg==0 && nBtm==0 && nTop==0 );
      assert( pRangeEnd==0 && pRangeStart==0 );
      testcase( pLoop->nSkip>0 );
      nExtraReg = 1;
      bSeekPastNull = 1;
      pLevel->regBignull = regBignull = ++pParse->nMem;
      if( pLevel->iLeftJoin ){
        sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull);
      }
      pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse);
    }

    /* If we are doing a reverse order scan on an ascending index, or
    ** a forward order scan on a descending index, interchange the 
    ** start and end terms (pRangeStart and pRangeEnd).
    */
    if( (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);
    assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
    if( zStartAff && nTop ){
      zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]);
    }
    addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt);
    addrNxt = pLevel->addrNxt;

    testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
    testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
    startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
    endEq =   !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
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
1666
1667
1668
1669
1670
1671
1672

1673

1674


1675
1676

1677
1678
1679
1680
1681
1682
1683


1684
1685

1686

1687
1688














1689
1690
1691
1692
1693
1694
1695
1696

















1697
1698
1699
1700
1701
1702
1703







-

-

-
-
+

-







-
-
+
+
-

-


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








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







      if( sqlite3ExprIsVector(pRight)==0 ){
        disableTerm(pLevel, pRangeStart);
      }else{
        startEq = 1;
      }
      bSeekPastNull = 0;
    }else if( bSeekPastNull ){
      startEq = 0;
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      start_constraints = 1;
      nConstraint++;
    }else if( regBignull ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      startEq = 0;
      start_constraints = 1;
      nConstraint++;
    }
    codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
    if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
      /* The skip-scan logic inside the call to codeAllEqualityConstraints()
      ** above has already left the cursor sitting on the correct row,
      ** so no further seeking is needed */
    }else{
      if( regBignull ){
        sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull);
      if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
        sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur);
        VdbeComment((v, "NULL-scan pass ctr"));
      }

      op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
      assert( op!=0 );
      if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){
        assert( regBignull==0 );
        /* TUNING:  The OP_SeekScan opcode seeks to reduce the number
        ** of expensive seek operations by replacing a single seek with
        ** 1 or more step operations.  The question is, how many steps
        ** should we try before giving up and going with a seek.  The cost
        ** of a seek is proportional to the logarithm of the of the number
        ** of entries in the tree, so basing the number of steps to try
        ** on the estimated number of rows in the btree seems like a good
        ** guess. */
        addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, 
                                         (pIdx->aiRowLogEst[0]+9)/10);
        VdbeCoverage(v);
      }
      sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
      VdbeCoverage(v);
      VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
      VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
      VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
      VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
      VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
      VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );

      assert( bSeekPastNull==0 || bStopAtNull==0 );
      if( regBignull ){
        assert( bSeekPastNull==1 || bStopAtNull==1 );
        assert( bSeekPastNull==!bStopAtNull );
        assert( bStopAtNull==startEq );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
        op = aStartOp[(nConstraint>1)*4 + 2 + bRev];
        sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, 
                             nConstraint-startEq);
        VdbeCoverage(v);
        VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
        VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
        VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
        VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
        assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE);
      }
    }

    /* Load the value for the inequality constraint at the end of the
    ** range (if any).
    */
    nConstraint = nEq;
    if( pRangeEnd ){
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890


1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932

1933
1934
1935


1936
1937
1938
1939
1940
1941
1942
1943









1944


1945
1946
1947
1948
1949

1950
1951
1952
1953
1954
1955
1956
1957
1958
1959



1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980



















1981
1982
1983
1984
1985
1986
1987




1988
1989
1990
1991
1992
1993
1994

1995
1996
1997
1998
1999
2000
2001
2002
1721
1722
1723
1724
1725
1726
1727



1728
1729

1730
1731
1732
1733
1734
1735
1736
1737
1738
1739






1740
1741
1742
1743
1744
1745

1746

















1747



1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766

1767
1768
1769
1770
1771
1772

1773
1774
1775
1776
1777
1778
1779




1780
1781
1782





















1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801







1802
1803
1804
1805







1806

1807
1808
1809
1810
1811
1812
1813







-
-
-
+
+
-










-
-
-
-
-
-






-

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








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




-
+






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








      if( sqlite3ExprIsVector(pRight)==0 ){
        disableTerm(pLevel, pRangeEnd);
      }else{
        endEq = 1;
      }
    }else if( bStopAtNull ){
      if( regBignull==0 ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
        endEq = 0;
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      endEq = 0;
      }
      nConstraint++;
    }
    sqlite3DbFree(db, zStartAff);
    sqlite3DbFree(db, zEndAff);

    /* Top of the loop body */
    pLevel->p2 = sqlite3VdbeCurrentAddr(v);

    /* Check if the index cursor is past the end of the range. */
    if( nConstraint ){
      if( regBignull ){
        /* Except, skip the end-of-range check while doing the NULL-scan */
        sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3);
        VdbeComment((v, "If NULL-scan 2nd pass"));
        VdbeCoverage(v);
      }
      op = aEndOp[bRev*2 + endEq];
      sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
      testcase( op==OP_IdxGT );  VdbeCoverageIf(v, op==OP_IdxGT );
      testcase( op==OP_IdxGE );  VdbeCoverageIf(v, op==OP_IdxGE );
      testcase( op==OP_IdxLT );  VdbeCoverageIf(v, op==OP_IdxLT );
      testcase( op==OP_IdxLE );  VdbeCoverageIf(v, op==OP_IdxLE );
      if( addrSeekScan ) sqlite3VdbeJumpHere(v, addrSeekScan);
    }
    if( regBignull ){
      /* During a NULL-scan, check to see if we have reached the end of
      ** the NULLs */
      assert( bSeekPastNull==!bStopAtNull );
      assert( bSeekPastNull+bStopAtNull==1 );
      assert( nConstraint+bSeekPastNull>0 );
      sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2);
      VdbeComment((v, "If NULL-scan 1st pass"));
      VdbeCoverage(v);
      op = aEndOp[bRev*2 + bSeekPastNull];
      sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase,
                           nConstraint+bSeekPastNull);
      testcase( op==OP_IdxGT );  VdbeCoverageIf(v, op==OP_IdxGT );
      testcase( op==OP_IdxGE );  VdbeCoverageIf(v, op==OP_IdxGE );
      testcase( op==OP_IdxLT );  VdbeCoverageIf(v, op==OP_IdxLT );
      testcase( op==OP_IdxLE );  VdbeCoverageIf(v, op==OP_IdxLE );
    }


    if( (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0 ){
      sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq);
    if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
      sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
    }

    /* Seek the table cursor, if required */
    omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
           && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
    if( omitTable ){
      /* pIdx is a covering index.  No need to access the main table. */
    }else if( HasRowid(pIdx->pTable) ){
      if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) || (
          (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE) 
       && (pWInfo->eOnePass==ONEPASS_SINGLE)
      )){
        iRowidReg = ++pParse->nMem;
        sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
        sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
        VdbeCoverage(v);
      }else{
      codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
        codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
      }
    }else if( iCur!=iIdxCur ){
      Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
      iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
      for(j=0; j<pPk->nKeyCol; j++){
        k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
      }
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
                           iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
    }

    if( pLevel->iLeftJoin==0 ){
      /* If pIdx is an index on one or more expressions, then look through
      ** all the expressions in pWInfo and try to transform matching expressions
      ** into reference to index columns.  Also attempt to translate references
    /* If pIdx is an index on one or more expressions, then look through
    ** all the expressions in pWInfo and try to transform matching expressions
    ** into reference to index columns.
      ** to virtual columns in the table into references to (stored) columns
      ** of the index.
      **
      ** Do not do this for the RHS of a LEFT JOIN. This is because the 
      ** expression may be evaluated after OP_NullRow has been executed on
      ** the cursor. In this case it is important to do the full evaluation,
      ** as the result of the expression may not be NULL, even if all table
      ** column values are.  https://www.sqlite.org/src/info/7fa8049685b50b5a
      **
      ** Also, do not do this when processing one index an a multi-index
      ** OR clause, since the transformation will become invalid once we
      ** move forward to the next index.
      ** https://sqlite.org/src/info/4e8e4857d32d401f
      */
      if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
        whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
      }
  
      /* If a partial index is driving the loop, try to eliminate WHERE clause
      ** terms from the query that must be true due to the WHERE clause of
      ** the partial index.
    **
    ** Do not do this for the RHS of a LEFT JOIN. This is because the 
    ** expression may be evaluated after OP_NullRow has been executed on
    ** the cursor. In this case it is important to do the full evaluation,
    ** as the result of the expression may not be NULL, even if all table
    ** column values are.  https://www.sqlite.org/src/info/7fa8049685b50b5a
    **
    ** Also, do not do this when processing one index an a multi-index
    ** OR clause, since the transformation will become invalid once we
    ** move forward to the next index.
    ** https://sqlite.org/src/info/4e8e4857d32d401f
    */
    if( pLevel->iLeftJoin==0 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
      whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
    }

    /* If a partial index is driving the loop, try to eliminate WHERE clause
    ** terms from the query that must be true due to the WHERE clause of
    ** the partial index
      **
      ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work
      ** for a LEFT JOIN.
      */
      if( pIdx->pPartIdxWhere ){
        whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC);
      }
    */
    if( pIdx->pPartIdxWhere ){
      whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC);
    }
    }else{
      testcase( pIdx->pPartIdxWhere );
      /* The following assert() is not a requirement, merely an observation:
      ** The OR-optimization doesn't work for the right hand table of
      ** a LEFT JOIN: */
      assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 );
    }

  
    /* Record the instruction used to terminate the loop. */
    if( pLoop->wsFlags & WHERE_ONEROW ){
      pLevel->op = OP_Noop;
    }else if( bRev ){
      pLevel->op = OP_Prev;
    }else{
      pLevel->op = OP_Next;
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
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







+

















-
+







    int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
    int regRowset = 0;                        /* Register for RowSet object */
    int regRowid = 0;                         /* Register holding rowid */
    int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */
    int iRetInit;                             /* Address of regReturn init */
    int untestedTerms = 0;             /* Some terms not completely tested */
    int ii;                            /* Loop counter */
    u16 wctrlFlags;                    /* Flags for sub-WHERE clause */
    Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
    Table *pTab = pTabItem->pTab;

    pTerm = pLoop->aLTerm[0];
    assert( pTerm!=0 );
    assert( pTerm->eOperator & WO_OR );
    assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
    pOrWc = &pTerm->u.pOrInfo->wc;
    pLevel->op = OP_Return;
    pLevel->p1 = regReturn;

    /* 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 */
      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));
2148
2149
2150
2151
2152
2153
2154
2155

2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170

2171
2172
2173
2174
2175
2176
2177
2178
2179
2180



2181
2182
2183
2184
2185
2186
2187
2188
2189

2190
2191
2192
2193
2194
2195
2196
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







-
+















+







-
-
-
+
+
+








-
+







        if( &pWC->a[iTerm] == pTerm ) continue;
        testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
        testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
        if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
        if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
        testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
        pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
      }
      if( pAndExpr ){
        /* The extra 0x10000 bit on the opcode is masked off and does not
        ** become part of the new Expr.op.  However, it does make the
        ** op==TK_AND comparison inside of sqlite3PExpr() false, and this
        ** prevents sqlite3PExpr() from implementing AND short-circuit 
        ** optimization, which we do not want here. */
        pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr);
      }
    }

    /* Run a separate WHERE clause for each term of the OR clause.  After
    ** eliminating duplicates from other WHERE clauses, the action for each
    ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
    */
    wctrlFlags =  WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE);
    ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR"));
    for(ii=0; ii<pOrWc->nTerm; ii++){
      WhereTerm *pOrTerm = &pOrWc->a[ii];
      if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
        WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
        Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
        int jmp1 = 0;                   /* Address of jump operation */
        testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
               && !ExprHasProperty(pOrExpr, EP_FromJoin)
        ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
        assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 
             || ExprHasProperty(pOrExpr, EP_FromJoin) 
        );
        if( pAndExpr ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */
        ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
        WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                                      WHERE_OR_SUBCLAUSE, iCovCur);
                                      wctrlFlags, iCovCur);
        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
        if( pSubWInfo ){
          WhereLoop *pSubLoop;
          int addrExplain = sqlite3WhereExplainOneScan(
              pParse, pOrTab, &pSubWInfo->a[0], 0
          );
          sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
2213
2214
2215
2216
2217
2218
2219
2220

2221
2222
2223
2224
2225
2226
2227
2026
2027
2028
2029
2030
2031
2032

2033
2034
2035
2036
2037
2038
2039
2040







-
+







              int iPk;
              int r;

              /* Read the PK into an array of temp registers. */
              r = sqlite3GetTempRange(pParse, nPk);
              for(iPk=0; iPk<nPk; iPk++){
                int iCol = pPk->aiColumn[iPk];
                sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk);
                sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk);
              }

              /* Check if the temp table already contains this key. If so,
              ** the row has already been included in the result set and
              ** can be ignored (by jumping past the Gosub below). Otherwise,
              ** insert the key into the temp table and proceed with processing
              ** the row.
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308

2309
2310
2311
2312
2313
2314
2315
2093
2094
2095
2096
2097
2098
2099



2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117

2118
2119
2120
2121
2122
2123
2124
2125







-
-
-


















-
+







           && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex))
          ){
            assert( pSubWInfo->a[0].iIdxCur==iCovCur );
            pCov = pSubLoop->u.btree.pIndex;
          }else{
            pCov = 0;
          }
          if( sqlite3WhereUsesDeferredSeek(pSubWInfo) ){
            pWInfo->bDeferredSeek = 1;
          }

          /* Finish the loop through table entries that match term pOrTerm. */
          sqlite3WhereEnd(pSubWInfo);
          ExplainQueryPlanPop(pParse);
        }
      }
    }
    ExplainQueryPlanPop(pParse);
    pLevel->u.pCovidx = pCov;
    if( pCov ) pLevel->iIdxCur = iCovCur;
    if( pAndExpr ){
      pAndExpr->pLeft = 0;
      sqlite3ExprDelete(db, pAndExpr);
    }
    sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
    sqlite3VdbeGoto(v, pLevel->addrBrk);
    sqlite3VdbeResolveLabel(v, iLoopBody);

    if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
    if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
    if( !untestedTerms ) disableTerm(pLevel, pTerm);
  }else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */

  {
    /* Case 6:  There is no usable index.  We must do a complete
    **          scan of the entire table.
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2208
2209
2210
2211
2212
2213
2214




2215
2216
2217
2218
2219
2220
2221







-
-
-
-







#endif
      }
#ifdef WHERETRACE_ENABLED /* 0xffff */
      if( sqlite3WhereTrace ){
        VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d",
                         pWC->nTerm-j, pTerm, iLoop));
      }
      if( sqlite3WhereTrace & 0x800 ){
        sqlite3DebugPrintf("Coding auxiliary constraint:\n");
        sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
      }
#endif
      sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
      if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
      pTerm->wtFlags |= TERM_CODED;
    }
    iLoop = iNext;
  }while( iLoop>0 );
2425
2426
2427
2428
2429
2430
2431
2432

2433
2434
2435
2436
2437
2438
2439
2440
2441
2442

2443
2444
2445
2446
2447
2448
2449
2231
2232
2233
2234
2235
2236
2237

2238
2239






2240
2241

2242
2243
2244
2245
2246
2247
2248
2249







-
+

-
-
-
-
-
-


-
+







  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE, sEAlt;
    WhereTerm *pAlt;
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
    if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
    if( pTerm->leftCursor!=iCur ) continue;
    if( pTabItem->fg.jointype & JT_LEFT ) continue;
    if( pLevel->iLeftJoin ) continue;
    pE = pTerm->pExpr;
#ifdef WHERETRACE_ENABLED /* 0x800 */
    if( sqlite3WhereTrace & 0x800 ){
      sqlite3DebugPrintf("Coding transitive constraint:\n");
      sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
    }
#endif
    assert( !ExprHasProperty(pE, EP_FromJoin) );
    assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
    pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
    pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
                    WO_EQ|WO_IN|WO_IS, 0);
    if( pAlt==0 ) continue;
    if( pAlt->wtFlags & (TERM_CODED) ) continue;
    if( (pAlt->eOperator & WO_IN) 
     && (pAlt->pExpr->flags & EP_xIsSelect)
     && (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
    ){
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2275
2276
2277
2278
2279
2280
2281











2282
2283







-
-
-
-
-
-
-
-
-
-
-


      }
      assert( pTerm->pExpr );
      sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
      pTerm->wtFlags |= TERM_CODED;
    }
  }

#if WHERETRACE_ENABLED /* 0x20800 */
  if( sqlite3WhereTrace & 0x20000 ){
    sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n",
                       iLevel);
    sqlite3WhereClausePrint(pWC);
  }
  if( sqlite3WhereTrace & 0x800 ){
    sqlite3DebugPrintf("End Coding level %d:  notReady=%llx\n",
       iLevel, (u64)pLevel->notReady);
  }
#endif
  return pLevel->notReady;
}

Changes to src/whereexpr.c.

80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94







-
+







  }
  pTerm = &pWC->a[idx = pWC->nTerm++];
  if( p && ExprHasProperty(p, EP_Unlikely) ){
    pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
  }else{
    pTerm->truthProb = 1;
  }
  pTerm->pExpr = sqlite3ExprSkipCollateAndLikely(p);
  pTerm->pExpr = sqlite3ExprSkipCollate(p);
  pTerm->wtFlags = wtFlags;
  pTerm->pWC = pWC;
  pTerm->iParent = -1;
  memset(&pTerm->eOperator, 0,
         sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
  return idx;
}
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
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







+
+
+
+
+
+
+
+

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










-







  assert( TK_GE==TK_EQ+4 );
  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS;
}

/*
** Commute a comparison operator.  Expressions of the form "X op Y"
** are converted into "Y op X".
**
** If left/right precedence rules come into play when determining the
** collating sequence, then COLLATE operators are adjusted to ensure
** that the collating sequence does not change.  For example:
** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on
** the left hand side of a comparison overrides any collation sequence 
** attached to the right. For the same reason the EP_Collate flag
** is not commuted.
*/
static u16 exprCommute(Parse *pParse, Expr *pExpr){
  if( pExpr->pLeft->op==TK_VECTOR
   || pExpr->pRight->op==TK_VECTOR
   || sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) !=
      sqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft)
static void exprCommute(Parse *pParse, Expr *pExpr){
  u16 expRight = (pExpr->pRight->flags & EP_Collate);
  u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
  assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
  if( expRight==expLeft ){
    /* Either X and Y both have COLLATE operator or neither do */
    if( expRight ){
      /* Both X and Y have COLLATE operators.  Make sure X is always
      ** used by clearing the EP_Collate flag from Y. */
      pExpr->pRight->flags &= ~EP_Collate;
    }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
      /* Neither X nor Y have COLLATE operators, but X has a non-default
      ** collating sequence.  So add the EP_Collate marker on X to cause
      ** it to be searched first. */
      pExpr->pLeft->flags |= EP_Collate;
  ){
    pExpr->flags ^= EP_Commuted;
    }
  }
  SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
  if( pExpr->op>=TK_GT ){
    assert( TK_LT==TK_GT+2 );
    assert( TK_GE==TK_LE+2 );
    assert( TK_GT>TK_EQ );
    assert( TK_GT<TK_LE );
    assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
    pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
  }
  return 0;
}

/*
** Translate from TK_xx operator to WO_xx bitmask.
*/
static u16 operatorMask(int op){
  u16 c;
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
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







-

+
-
+
-
-
-
+
+
+
+

-
-
-
-
-
+
+
+
+
-
-

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







        char *zNew = pPrefix->u.zToken;
        zNew[cnt] = 0;
        for(iFrom=iTo=0; iFrom<cnt; iFrom++){
          if( zNew[iFrom]==wc[3] ) iFrom++;
          zNew[iTo++] = zNew[iFrom];
        }
        zNew[iTo] = 0;
        assert( iTo>0 );

        /* If the RHS begins with a digit or a minus sign, then the LHS must be
        /* If the LHS is not an ordinary column with TEXT affinity, then the
        ** an ordinary column (not a virtual table column) with TEXT affinity.
        ** pattern prefix boundaries (both the start and end boundaries) must
        ** not look like a number.  Otherwise the pattern might be treated as
        ** a number, which will invalidate the LIKE optimization.
        ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
        ** even though "lhs LIKE rhs" is true.  But if the RHS does not start
        ** with a digit or '-', then "lhs LIKE rhs" will always be false if
        ** the LHS is numeric and so the optimization still works.
        **
        ** Getting this right has been a persistent source of bugs in the
        ** LIKE optimization.  See, for example:
        **    2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1
        **    2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
        **    2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
        ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
        ** The RHS pattern must not be '/%' because the termination condition
        ** will then become "x<'0'" and if the affinity is numeric, will then
        ** be converted into "x<0", which is incorrect.
        **    2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
        **    2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
        */
        if( sqlite3Isdigit(zNew[0])
         || zNew[0]=='-'
         || (zNew[0]+1=='0' && iTo==1)
        ){
        if( pLeft->op!=TK_COLUMN 
         || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
         || IsVirtual(pLeft->y.pTab)  /* Value might be numeric */
        ){
          if( pLeft->op!=TK_COLUMN 
           || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
           || IsVirtual(pLeft->y.pTab)  /* Value might be numeric */
          ){
          int isNum;
          double rDummy;
          isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
          if( isNum<=0 ){
            if( iTo==1 && zNew[0]=='-' ){
              isNum = +1;
            }else{
              zNew[iTo-1]++;
              isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
              zNew[iTo-1]--;
            }
          }
          if( isNum>0 ){
            sqlite3ExprDelete(db, pPrefix);
            sqlite3ValueFree(pVal);
            return 0;
          }
        }
      }
      *ppPrefix = pPrefix;
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
378
379
380
381
382
383
384

385

386
387
388
389
390
391
392







-
+
-







    ** virtual table on their second argument, which is the same as
    ** the left-hand side operand in their in-fix form.
    **
    **       vtab_column MATCH expression
    **       MATCH(expression,vtab_column)
    */
    pCol = pList->a[1].pExpr;
    testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
    if( ExprIsVtab(pCol) ){
      for(i=0; i<ArraySize(aOp); i++){
        if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
          *peOp2 = aOp[i].eOp2;
          *ppRight = pList->a[0].pExpr;
          *ppLeft = pCol;
          return 1;
        }
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
400
401
402
403
404
405
406

407

408
409
410
411
412
413
414







-
+
-







    **      OVERLOADED(vtab_column,expression)
    **
    ** Historically, xFindFunction expected to see lower-case function
    ** names.  But for this use case, xFindFunction is expected to deal
    ** with function names in an arbitrary case.
    */
    pCol = pList->a[0].pExpr;
    testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
    if( ExprIsVtab(pCol) ){
      sqlite3_vtab *pVtab;
      sqlite3_module *pMod;
      void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
      void *pNotUsed;
      pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
      assert( pVtab!=0 );
      assert( pVtab->pModule!=0 );
420
421
422
423
424
425
426
427

428
429
430
431

432
433
434
435
436
437
438
439
423
424
425
426
427
428
429

430

431
432

433

434
435
436
437
438
439
440







-
+
-


-
+
-







        }
      }
    }
  }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
    int res = 0;
    Expr *pLeft = pExpr->pLeft;
    Expr *pRight = pExpr->pRight;
    testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
    if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
    if( ExprIsVtab(pLeft) ){
      res++;
    }
    testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
    if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
    if( pRight && ExprIsVtab(pRight) ){
      res++;
      SWAP(Expr*, pLeft, pRight);
    }
    *ppLeft = pLeft;
    *ppRight = pRight;
    if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE;
    if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT;
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
508
509
510
511
512
513
514

515
516
517
518
519
520
521







-







){
  u16 eOp = pOne->eOperator | pTwo->eOperator;
  sqlite3 *db;           /* Database connection (for malloc) */
  Expr *pNew;            /* New virtual expression */
  int op;                /* Operator for the combined expression */
  int idxNew;            /* Index in pWC of the next virtual term */

  if( (pOne->wtFlags | pTwo->wtFlags) & TERM_VNULL ) return;
  if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return;
  if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return;
  if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp
   && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return;
  assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 );
  assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 );
  if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
795
796
797
798
799
800
801
802

803
804
805
806
807
808
809
795
796
797
798
799
800
801

802
803
804
805
806
807
808
809







-
+







          ** or follwed by an inverted copy (t2.b==t1.a).  Skip this term 
          ** and use its inversion. */
          testcase( pOrTerm->wtFlags & TERM_COPIED );
          testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
          assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
          continue;
        }
        iColumn = pOrTerm->u.x.leftColumn;
        iColumn = pOrTerm->u.leftColumn;
        iCursor = pOrTerm->leftCursor;
        pLeft = pOrTerm->pExpr->pLeft;
        break;
      }
      if( i<0 ){
        /* No candidate table+column was found.  This can only occur
        ** on the second iteration */
817
818
819
820
821
822
823
824

825
826
827
828
829
830
831
817
818
819
820
821
822
823

824
825
826
827
828
829
830
831







-
+







      /* We have found a candidate table and column.  Check to see if that
      ** table and column is common to every term in the OR clause */
      okToChngToIN = 1;
      for(; i>=0 && okToChngToIN; i--, pOrTerm++){
        assert( pOrTerm->eOperator & WO_EQ );
        if( pOrTerm->leftCursor!=iCursor ){
          pOrTerm->wtFlags &= ~TERM_OR_OK;
        }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR 
        }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR 
               && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
        )){
          okToChngToIN = 0;
        }else{
          int affLeft, affRight;
          /* If the right-hand side is also a column, then the affinities
          ** of both right and left sides must be such that no type
852
853
854
855
856
857
858
859

860
861
862
863
864
865
866
852
853
854
855
856
857
858

859
860
861
862
863
864
865
866







-
+







      Expr *pLeft = 0;       /* The LHS of the IN operator */
      Expr *pNew;            /* The complete IN operator */

      for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
        if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
        assert( pOrTerm->eOperator & WO_EQ );
        assert( pOrTerm->leftCursor==iCursor );
        assert( pOrTerm->u.x.leftColumn==iColumn );
        assert( pOrTerm->u.leftColumn==iColumn );
        pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
        pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
        pLeft = pOrTerm->pExpr->pLeft;
      }
      assert( pLeft!=0 );
      pDup = sqlite3ExprDup(db, pLeft, 0);
      pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
906
907
908
909
910
911
912
913

914
915
916
917
918
919
920
906
907
908
909
910
911
912

913
914
915
916
917
918
919
920







-
+







  aff1 = sqlite3ExprAffinity(pExpr->pLeft);
  aff2 = sqlite3ExprAffinity(pExpr->pRight);
  if( aff1!=aff2
   && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
  ){
    return 0;
  }
  pColl = sqlite3ExprCompareCollSeq(pParse, pExpr);
  pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
  if( sqlite3IsBinary(pColl) ) return 1;
  return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
}

/*
** Recursively walk the expressions of a SELECT statement and generate
** a bitmask indicating which tables are used in that expression
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1004
1005
1006
1007
1008
1009
1010















































































































































































































































































1011
1012
1013
1014
1015
1016
1017







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







    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( pSel->pLimit ) 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.
**
** If the expression is of the form "<expr> <op> X" it gets commuted
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
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







-
+


-
+




-
+









-
+







  pTerm->eOperator = 0;
  if( allowedOp(op) ){
    int aiCurCol[2];
    Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
    Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
    u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;

    if( pTerm->u.x.iField>0 ){
    if( pTerm->iField>0 ){
      assert( op==TK_IN );
      assert( pLeft->op==TK_VECTOR );
      pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
      pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
    }

    if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
      pTerm->leftCursor = aiCurCol[0];
      pTerm->u.x.leftColumn = aiCurCol[1];
      pTerm->u.leftColumn = aiCurCol[1];
      pTerm->eOperator = operatorMask(op) & opMask;
    }
    if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
    if( pRight 
     && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
    ){
      WhereTerm *pNew;
      Expr *pDup;
      u16 eExtraOp = 0;        /* Extra bits for pNew->eOperator */
      assert( pTerm->u.x.iField==0 );
      assert( pTerm->iField==0 );
      if( pTerm->leftCursor>=0 ){
        int idxNew;
        pDup = sqlite3ExprDup(db, pExpr, 0);
        if( db->mallocFailed ){
          sqlite3ExprDelete(db, pDup);
          return;
        }
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
1130
1131
1132
1133
1134
1135
1136

1137
1138

1139
1140
1141
1142
1143






1144
1145
1146
1147
1148
1149
1150







-
+

-
+




-
-
-
-
-
-







          pTerm->eOperator |= WO_EQUIV;
          eExtraOp = WO_EQUIV;
        }
      }else{
        pDup = pExpr;
        pNew = pTerm;
      }
      pNew->wtFlags |= exprCommute(pParse, pDup);
      exprCommute(pParse, pDup);
      pNew->leftCursor = aiCurCol[0];
      pNew->u.x.leftColumn = aiCurCol[1];
      pNew->u.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:
  **
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534

1535
1536
1537
1538
1539
1540
1541
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







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















-
-
+







  */
  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
  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;
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
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







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







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







    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;

      prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight);
      prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
      if( (prereqExpr & prereqColumn)==0 ){
        Expr *pNewExpr;
        pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 
            0, sqlite3ExprDup(db, pRight, 0));
        if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
          ExprSetProperty(pNewExpr, EP_FromJoin);
        }
        idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
        testcase( idxNew==0 );
        pNewTerm = &pWC->a[idxNew];
        pNewTerm->prereqRight = prereqExpr;
        pNewTerm->leftCursor = pLeft->iTable;
        pNewTerm->u.leftColumn = pLeft->iColumn;
        pNewTerm->eOperator = WO_AUX;
        pNewTerm->eMatchOp = eOp2;
        markTermAsChild(pWC, idxNew, idxTerm);
        pTerm = &pWC->a[idxTerm];
        pTerm->wtFlags |= TERM_COPIED;
        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 
  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)
  && (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);
1631
1632
1633
1634
1635
1636
1637
1638

1639
1640
1641

1642
1643
1644

1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657

1658
1659
1660
1661
1662
1663

1664
1665
1666

1667
1668

1669
1670
1671




1672
1673
1674
1675
1676
1677
1678










1679
1680
1681
1682
1683
1684
1685
1686


1687
1688

1689
1690
1691
1692
1693
1694
1695
1696
1697









1698
1699
1700
1701
1702
1703





1704
1705

1706
1707

1708
1709
1710
1711
1712
1713
1714
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







-
+


-
+
-

-
+
-


-
-
-
-





-
+





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

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

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







    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
  ** expression). The WhereTerm.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
  ** This only works if the RHS is a simple SELECT, not a compound
  ** not use window functions.
  */
  else if( pExpr->op==TK_IN
  if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0
   && 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;
      pWC->a[idxNew].iField = i+1;
      exprAnalyze(pSrc, pWC, idxNew);
      markTermAsChild(pWC, idxNew, idxTerm);
    }
  }

#ifndef SQLITE_OMIT_VIRTUALTABLE
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  /* 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
  /* When sqlite_stat3 histogram data is available an operator of the
  ** not normally optimized for ordinary tables.  In other words, OP
  ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL.
  ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
  ** This information is used by the xBestIndex methods of
  ** virtual tables.  The native query optimizer does not attempt
  ** to do anything with MATCH functions.
  ** 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.
  */
  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;
  if( pExpr->op==TK_NOTNULL
   && pExpr->pLeft->op==TK_COLUMN
   && pExpr->pLeft->iColumn>=0
   && !ExprHasProperty(pExpr, EP_FromJoin)
   && OptimizationEnabled(db, SQLITE_Stat34)
  ){
    Expr *pNewExpr;
    Expr *pLeft = pExpr->pLeft;
    int idxNew;
    WhereTerm *pNewTerm;
      Bitmask prereqColumn, prereqExpr;

      prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight);
      prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
      if( (prereqExpr & prereqColumn)==0 ){
        Expr *pNewExpr;
        pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 
            0, sqlite3ExprDup(db, pRight, 0));
    pNewExpr = sqlite3PExpr(pParse, TK_GT,
                            sqlite3ExprDup(db, pLeft, 0),
        if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
          ExprSetProperty(pNewExpr, EP_FromJoin);
                            sqlite3ExprAlloc(db, TK_NULL, 0, 0));
          pNewExpr->iRightJoinTable = pExpr->iRightJoinTable;
        }
        idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
        testcase( idxNew==0 );
        pNewTerm = &pWC->a[idxNew];
        pNewTerm->prereqRight = prereqExpr;
        pNewTerm->leftCursor = pLeft->iTable;
        pNewTerm->u.x.leftColumn = pLeft->iColumn;
        pNewTerm->eOperator = WO_AUX;

    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.leftColumn = pLeft->iColumn;
      pNewTerm->eOperator = WO_GT;
        pNewTerm->eMatchOp = eOp2;
        markTermAsChild(pWC, idxNew, idxTerm);
        pTerm = &pWC->a[idxTerm];
        pTerm->wtFlags |= TERM_COPIED;
        pNewTerm->prereqAll = pTerm->prereqAll;
      }
      markTermAsChild(pWC, idxNew, idxTerm);
      pTerm = &pWC->a[idxTerm];
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
      SWAP(Expr*, pLeft, pRight);
    }
  }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#endif /* SQLITE_ENABLE_STAT3_OR_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;
1733
1734
1735
1736
1737
1738
1739
1740

1741
1742
1743
1744
1745
1746
1747
1748
1749
1441
1442
1443
1444
1445
1446
1447

1448
1449

1450
1451
1452
1453
1454
1455
1456







-
+

-







** does is make slot[] entries point to substructure within pExpr.
**
** In the previous sentence and in the diagram, "slot[]" refers to
** the WhereClause.a[] array.  The slot[] array grows as needed to contain
** all terms of the WHERE clause.
*/
void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
  Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr);
  Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
  pWC->op = op;
  assert( pE2!=0 || pExpr==0 );
  if( pE2==0 ) return;
  if( pE2->op!=op ){
    whereClauseInsert(pWC, pExpr, 0);
  }else{
    sqlite3WhereSplit(pWC, pE2->pLeft, op);
    sqlite3WhereSplit(pWC, pE2->pRight, op);
  }
1810
1811
1812
1813
1814
1815
1816
1817

1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1517
1518
1519
1520
1521
1522
1523

1524
1525
1526

1527
1528
1529
1530
1531
1532
1533







-
+


-







  }else if( ExprHasProperty(p, EP_xIsSelect) ){
    if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
    mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
  }else if( p->x.pList ){
    mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
  }
#ifndef SQLITE_OMIT_WINDOWFUNC
  if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && p->y.pWin ){
  if( p->op==TK_FUNCTION && p->y.pWin ){
    mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition);
    mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy);
    mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter);
  }
#endif
  return mask;
}
Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
  return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0;
}
1860
1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872
1873
1874
1566
1567
1568
1569
1570
1571
1572

1573
1574
1575
1576
1577
1578
1579
1580







-
+







** 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 */
  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;
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1595
1596
1597
1598
1599
1600
1601



1602
1603
1604







-
-
-



    if( pColRef==0 ) return;
    pColRef->iTable = pItem->iCursor;
    pColRef->iColumn = k++;
    pColRef->y.pTab = pTab;
    pRhs = sqlite3PExpr(pParse, TK_UPLUS, 
        sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
    pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
    if( pItem->fg.jointype & JT_LEFT ){
      sqlite3SetJoinExpr(pTerm, pItem->iCursor);
    }
    whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
  }
}

Changes to src/window.c.

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







-











-
-







** selectWindowRewriteExprCb() by selectWindowRewriteEList().
*/
typedef struct WindowRewrite WindowRewrite;
struct WindowRewrite {
  Window *pWin;
  SrcList *pSrc;
  ExprList *pSub;
  Table *pTab;
  Select *pSubSelect;             /* Current sub-select, if any */
};

/*
** Callback function used by selectWindowRewriteEList(). If necessary,
** this function appends to the output expression-list and updates 
** expression (*ppExpr) in place.
*/
static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
  struct WindowRewrite *p = pWalker->u.pRewrite;
  Parse *pParse = pWalker->pParse;
  assert( p!=0 );
  assert( p->pWin!=0 );

  /* If this function is being called from within a scalar sub-select
  ** that used by the SELECT statement being processed, only process
  ** TK_COLUMN expressions that refer to it (the outer SELECT). Do
  ** not process aggregates or window functions at all, as they belong
  ** to the scalar sub-select.  */
  if( p->pSubSelect ){
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
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







-
+



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

-







-
+

-
-

-
+







        for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
          if( pExpr->y.pWin==pWin ){
            assert( pWin->pOwner==pExpr );
            return WRC_Prune;
          }
        }
      }
      /* no break */ deliberate_fall_through
      /* Fall through.  */

    case TK_AGG_FUNCTION:
    case TK_COLUMN: {
      int iCol = -1;
      if( p->pSub ){
        int i;
        for(i=0; i<p->pSub->nExpr; i++){
          if( 0==sqlite3ExprCompare(0, p->pSub->a[i].pExpr, pExpr, -1) ){
            iCol = i;
            break;
          }
        }
      }
      if( iCol<0 ){
        Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
      Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
        if( pDup && pDup->op==TK_AGG_FUNCTION ) pDup->op = TK_FUNCTION;
        p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
      p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
      }
      if( p->pSub ){
        int f = pExpr->flags & EP_Collate;
        assert( ExprHasProperty(pExpr, EP_Static)==0 );
        ExprSetProperty(pExpr, EP_Static);
        sqlite3ExprDelete(pParse->db, pExpr);
        ExprClearProperty(pExpr, EP_Static);
        memset(pExpr, 0, sizeof(Expr));

        pExpr->op = TK_COLUMN;
        pExpr->iColumn = (iCol<0 ? p->pSub->nExpr-1: iCol);
        pExpr->iColumn = p->pSub->nExpr-1;
        pExpr->iTable = p->pWin->iEphCsr;
        pExpr->y.pTab = p->pTab;
        pExpr->flags = f;
      }
      if( pParse->db->mallocFailed ) return WRC_Abort;

      break;
    }

    default: /* no-op */
      break;
  }

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893

894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915

916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947

948
949
950
951
952
953
954
955
956
957
958

959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984



985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001


1002
1003
1004
1005
1006
1007
1008


1009
1010
1011
1012
1013
1014
1015
1016
1017
1018

1019
1020
1021
1022

1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041

1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056

1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067


1068
1069
1070
1071
1072
1073

1074





1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
835
836
837
838
839
840
841

842
843
844
845
846

847
848
849
850
851
852

853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870

871

872
873
874
875
876
877













878

879
880
881
882
883
884

















885
886
887
888
889
890
891
892
893

894
895
896
897
898
899
900
901
902
903
904

905
906











907
908
909
910
911


912
913
914
915



916
917
918


919
920
921
922

923
924
925
926
927
928
929
930


931
932
933
934
935
936
937


938
939
940
941
942
943
944
945




946




947

948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964

965
966
967
968
969
970
971



972
973

974
975

976






977
978



979
980






981
982
983
984
985
986
987
988
989
990
991

992
993






994












995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008







-





-






-


















-
+
-






-
-
-
-
-
-
-
-
-
-
-
-
-

-
+





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-









-
+










-
+

-
-
-
-
-
-
-
-
-
-
-





-
-




-
-
-
+
+
+
-
-




-








-
-
+
+





-
-
+
+






-
-
-
-
+
-
-
-
-
+
-

















-
+






-
-
-


-


-
+
-
-
-
-
-
-


-
-
-
+
+
-
-
-
-
-
-
+

+
+
+
+
+




-


-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-







-







** appending the new one.
*/
static void selectWindowRewriteEList(
  Parse *pParse, 
  Window *pWin,
  SrcList *pSrc,
  ExprList *pEList,               /* Rewrite expressions in this list */
  Table *pTab,
  ExprList **ppSub                /* IN/OUT: Sub-select expression-list */
){
  Walker sWalker;
  WindowRewrite sRewrite;

  assert( pWin!=0 );
  memset(&sWalker, 0, sizeof(Walker));
  memset(&sRewrite, 0, sizeof(WindowRewrite));

  sRewrite.pSub = *ppSub;
  sRewrite.pWin = pWin;
  sRewrite.pSrc = pSrc;
  sRewrite.pTab = pTab;

  sWalker.pParse = pParse;
  sWalker.xExprCallback = selectWindowRewriteExprCb;
  sWalker.xSelectCallback = selectWindowRewriteSelectCb;
  sWalker.u.pRewrite = &sRewrite;

  (void)sqlite3WalkExprList(&sWalker, pEList);

  *ppSub = sRewrite.pSub;
}

/*
** Append a copy of each expression in expression-list pAppend to
** expression list pList. Return a pointer to the result list.
*/
static ExprList *exprListAppendList(
  Parse *pParse,          /* Parsing context */
  ExprList *pList,        /* List to which to append. Might be NULL */
  ExprList *pAppend,      /* List of values to append. Might be NULL */
  ExprList *pAppend       /* List of values to append. Might be NULL */
  int bIntToNull
){
  if( pAppend ){
    int i;
    int nInit = pList ? pList->nExpr : 0;
    for(i=0; i<pAppend->nExpr; i++){
      Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
      assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) );
      if( bIntToNull && pDup ){
        int iDummy;
        Expr *pSub;
        for(pSub=pDup; ExprHasProperty(pSub, EP_Skip); pSub=pSub->pLeft){
          assert( pSub );
        }
        if( sqlite3ExprIsInteger(pSub, &iDummy) ){
          pSub->op = TK_NULL;
          pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
          pSub->u.zToken = 0;
        }
      }
      pList = sqlite3ExprListAppend(pParse, pList, pDup);
      if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
      if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
    }
  }
  return pList;
}

/*
** When rewriting a query, if the new subquery in the FROM clause
** contains TK_AGG_FUNCTION nodes that refer to an outer query,
** then we have to increase the Expr->op2 values of those nodes
** due to the extra subquery layer that was added.
**
** See also the incrAggDepth() routine in resolve.c
*/
static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_AGG_FUNCTION
   && pExpr->op2>=pWalker->walkerDepth
  ){
    pExpr->op2++;
  }
  return WRC_Continue;
}

/*
** If the SELECT statement passed as the second argument does not invoke
** any SQL window functions, this function is a no-op. Otherwise, it 
** rewrites the SELECT statement so that window function xStep functions
** are invoked in the correct order as described under "SELECT REWRITING"
** at the top of this file.
*/
int sqlite3WindowRewrite(Parse *pParse, Select *p){
  int rc = SQLITE_OK;
  if( p->pWin && p->pPrior==0 && (p->selFlags & SF_WinRewrite)==0 ){
  if( p->pWin && p->pPrior==0 ){
    Vdbe *v = sqlite3GetVdbe(pParse);
    sqlite3 *db = pParse->db;
    Select *pSub = 0;             /* The subquery */
    SrcList *pSrc = p->pSrc;
    Expr *pWhere = p->pWhere;
    ExprList *pGroupBy = p->pGroupBy;
    Expr *pHaving = p->pHaving;
    ExprList *pSort = 0;

    ExprList *pSublist = 0;       /* Expression list for sub-query */
    Window *pMWin = p->pWin;      /* Main window object */
    Window *pMWin = p->pWin;      /* Master window object */
    Window *pWin;                 /* Window object iterator */
    Table *pTab;
    Walker w;

    u32 selFlags = p->selFlags;

    pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ){
      return sqlite3ErrorToParser(db, SQLITE_NOMEM);
    }
    sqlite3AggInfoPersistWalkerInit(&w, pParse);
    sqlite3WalkSelect(&w, p);

    p->pSrc = 0;
    p->pWhere = 0;
    p->pGroupBy = 0;
    p->pHaving = 0;
    p->selFlags &= ~SF_Aggregate;
    p->selFlags |= SF_WinRewrite;

    /* Create the ORDER BY clause for the sub-select. This is the concatenation
    ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
    ** redundant, remove the ORDER BY from the parent SELECT.  */
    pSort = exprListAppendList(pParse, 0, pMWin->pPartition, 1);
    pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
    if( pSort && p->pOrderBy && p->pOrderBy->nExpr<=pSort->nExpr ){
    pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
    pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
    if( pSort && p->pOrderBy ){
      int nSave = pSort->nExpr;
      pSort->nExpr = p->pOrderBy->nExpr;
      if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
        sqlite3ExprListDelete(db, p->pOrderBy);
        p->pOrderBy = 0;
      }
      pSort->nExpr = nSave;
    }

    /* Assign a cursor number for the ephemeral table used to buffer rows.
    ** The OpenEphemeral instruction is coded later, after it is known how
    ** many columns the table will have.  */
    pMWin->iEphCsr = pParse->nTab++;
    pParse->nTab += 3;

    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist);
    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist);
    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
    pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);

    /* Append the PARTITION BY and ORDER BY expressions to the to the 
    ** sub-select expression list. They are required to figure out where 
    ** boundaries for partitions and sets of peer rows lie.  */
    pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
    pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
    pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
    pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);

    /* Append the arguments passed to each window function to the
    ** sub-select expression list. Also allocate two registers for each
    ** window function - one for the accumulator, another for interim
    ** results.  */
    for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
      ExprList *pArgs = pWin->pOwner->x.pList;
      if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
        selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
        pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
      pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
        pWin->bExprArgs = 1;
      }else{
        pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
        pSublist = exprListAppendList(pParse, pSublist, pArgs, 0);
      pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
      }
      if( pWin->pFilter ){
        Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
        pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
      }
      pWin->regAccum = ++pParse->nMem;
      pWin->regResult = ++pParse->nMem;
      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
    }

    /* If there is no ORDER BY or PARTITION BY clause, and the window
    ** function accepts zero arguments, and there are no other columns
    ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
    ** that pSublist is still NULL here. Add a constant expression here to 
    ** keep everything legal in this case. 
    */
    if( pSublist==0 ){
      pSublist = sqlite3ExprListAppend(pParse, 0, 
        sqlite3Expr(db, TK_INTEGER, "0")
          sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
      );
    }

    pSub = sqlite3SelectNew(
        pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
    );
    SELECTTRACE(1,pParse,pSub,
       ("New window-function subquery in FROM clause of (%u/%p)\n",
       p->selId, p));
    p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
    if( p->pSrc ){
      Table *pTab2;
      p->pSrc->a[0].pSelect = pSub;
      sqlite3SrcListAssignCursors(pParse, p->pSrc);
      pSub->selFlags |= SF_Expanded;
      if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
      pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
      pSub->selFlags |= (selFlags & SF_Aggregate);
      if( pTab2==0 ){
        /* Might actually be some other kind of error, but in that case
        ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get
        ** the correct error message regardless. */
        rc = SQLITE_NOMEM;
      }else{
        memcpy(pTab, pTab2, sizeof(Table));
        pTab->tabFlags |= TF_Ephemeral;
        p->pSrc->a[0].pTab = pTab;
        pSub->selFlags |= SF_Expanded;
        p->selFlags &= ~SF_Aggregate;
        pTab = pTab2;
        memset(&w, 0, sizeof(w));
        w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
        w.xSelectCallback = sqlite3WalkerDepthIncrease;
        w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
        sqlite3WalkSelect(&w, pSub);
        sqlite3SelectPrep(pParse, pSub, 0);
      }

      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
    }else{
      sqlite3SelectDelete(db, pSub);
    }
    if( db->mallocFailed ) rc = SQLITE_NOMEM;
    sqlite3DbFree(db, pTab);
  }

  if( rc ){
    if( pParse->nErr==0 ){
      assert( pParse->db->mallocFailed );
      sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
    }
  }
  return rc;
}

/*
** Unlink the Window object from the Select to which it is attached,
** if it is attached.
*/
void sqlite3WindowUnlinkFromSelect(Window *p){
  if( p->ppThis ){
    *p->ppThis = p->pNextWin;
    if( p->pNextWin ) p->pNextWin->ppThis = p->ppThis;
    p->ppThis = 0;
  }
}

/*
** Free the Window object passed as the second argument.
*/
void sqlite3WindowDelete(sqlite3 *db, Window *p){
  if( p ){
    sqlite3WindowUnlinkFromSelect(p);
    sqlite3ExprDelete(db, p->pFilter);
    sqlite3ExprListDelete(db, p->pPartition);
    sqlite3ExprListDelete(db, p->pOrderBy);
    sqlite3ExprDelete(db, p->pEnd);
    sqlite3ExprDelete(db, p->pStart);
    sqlite3DbFree(db, p->zName);
    sqlite3DbFree(db, p->zBase);
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
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







+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+

-
+
-
-






-
+
-
-
-
+
-
-
-
-
-
-
-









-
+
-
-



-
-
-
-
-








/*
** Attach window object pWin to expression p.
*/
void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
  if( p ){
    assert( p->op==TK_FUNCTION );
    /* This routine is only called for the parser.  If pWin was not
    ** allocated due to an OOM, then the parser would fail before ever
    ** invoking this routine */
    assert( pWin );
    p->y.pWin = pWin;
    ExprSetProperty(p, EP_WinFunc);
    pWin->pOwner = p;
    if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){
      sqlite3ErrorMsg(pParse,
          "DISTINCT is not supported for window functions"
    if( ALWAYS(pWin) ){
      p->y.pWin = pWin;
      ExprSetProperty(p, EP_WinFunc);
      pWin->pOwner = p;
      if( p->flags & EP_Distinct ){
        sqlite3ErrorMsg(pParse,
           "DISTINCT is not supported for window functions");
      );
      }
    }
  }else{
    sqlite3WindowDelete(pParse->db, pWin);
  }
}

/*
** 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
** Return 0 if the two window objects are identical, or non-zero otherwise.
** 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.
** Identical window objects can be processed in a single scan.
*/
int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){
int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
  int res;
  if( NEVER(p1==0) || NEVER(p2==0) ) return 1;
  if( p1->eFrmType!=p2->eFrmType ) return 1;
  if( p1->eStart!=p2->eStart ) return 1;
  if( p1->eEnd!=p2->eEnd ) return 1;
  if( p1->eExclude!=p2->eExclude ) return 1;
  if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
  if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
  if( (res = sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1)) ){
  if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
    return res;
  }
  if( (res = sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1)) ){
  if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
    return res;
  }
  if( bFilter ){
    if( (res = sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1)) ){
      return res;
    }
  }
  return 0;
}


/*
** This is called by code in select.c before it calls sqlite3WhereBegin()
** to begin iterating through the sub-query results. It is used to allocate
** and initialize registers and cursors used by sqlite3WindowCodeStep().
*/
void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
  int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr;
  Window *pMWin = pSelect->pWin;
  Window *pWin;
  Vdbe *v = sqlite3GetVdbe(pParse);

  sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr);
  sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
  sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
  sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);

  /* Allocate registers to use for PARTITION BY values, if any. Initialize
  ** said registers to NULL.  */
  if( pMWin->pPartition ){
    int nExpr = pMWin->pPartition->nExpr;
    pMWin->regPart = pParse->nMem+1;
    pParse->nMem += nExpr;
    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1);
1399
1400
1401
1402
1403
1404
1405
1406
1407


1408
1409
1410
1411
1412
1413
1414
1253
1254
1255
1256
1257
1258
1259


1260
1261
1262
1263
1264
1265
1266
1267
1268







-
-
+
+







      */
      ExprList *pList = pWin->pOwner->x.pList;
      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
      pWin->csrApp = pParse->nTab++;
      pWin->regApp = pParse->nMem+1;
      pParse->nMem += 3;
      if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
        assert( pKeyInfo->aSortFlags[0]==0 );
        pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
        assert( pKeyInfo->aSortOrder[0]==0 );
        pKeyInfo->aSortOrder[0] = 1;
      }
      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
      sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
    }
    else if( p->zName==nth_valueName || p->zName==first_valueName ){
      /* Allocate two registers at pWin->regApp. These will be used to
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615

1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627

1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
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







-




















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




















-
+





-





-
+


-
-
-
-
-
-







    VdbeCoverage(v);
    assert( eCond==0 || eCond==1 || eCond==2 );
    VdbeCoverageIf(v, eCond==0);
    VdbeCoverageIf(v, eCond==1);
    VdbeCoverageIf(v, eCond==2);
  }
  sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
  sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC);
  VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */
  VdbeCoverageNeverNullIf(v, eCond==1); /*   the OP_MustBeInt */
  VdbeCoverageNeverNullIf(v, eCond==2);
  VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */
  VdbeCoverageNeverNullIf(v, eCond==4); /*   the OP_Ge */
  sqlite3MayAbort(pParse);
  sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
  sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
  sqlite3ReleaseTempReg(pParse, regZero);
}

/*
** Return the number of arguments passed to the window-function associated
** with the object passed as the only argument to this function.
*/
static int windowArgCount(Window *pWin){
  ExprList *pList = pWin->pOwner->x.pList;
  return (pList ? pList->nExpr : 0);
}

typedef struct WindowCodeArg WindowCodeArg;
typedef struct WindowCsrAndReg WindowCsrAndReg;

/*
** See comments above struct WindowCodeArg.
*/
struct WindowCsrAndReg {
  int csr;                        /* Cursor number */
  int reg;                        /* First in array of peer values */
};

/*
** A single instance of this structure is allocated on the stack by 
** sqlite3WindowCodeStep() and a pointer to it passed to the various helper
** routines. This is to reduce the number of arguments required by each
** helper function.
**
** regArg:
**   Each window function requires an accumulator register (just as an
**   ordinary aggregate function does). This variable is set to the first
**   in an array of accumulator registers - one for each window function
**   in the WindowCodeArg.pMWin list.
**
** eDelete:
**   The window functions implementation sometimes caches the input rows
**   that it processes in a temporary table. If it is not zero, this
**   variable indicates when rows may be removed from the temp table (in
**   order to reduce memory requirements - it would always be safe just
**   to leave them there). Possible values for eDelete are:
**
**      WINDOW_RETURN_ROW:
**        An input row can be discarded after it is returned to the caller.
**
**      WINDOW_AGGINVERSE:
**        An input row can be discarded after the window functions xInverse()
**        callbacks have been invoked in it.
**
**      WINDOW_AGGSTEP:
**        An input row can be discarded after the window functions xStep()
**        callbacks have been invoked in it.
**
** start,current,end
**   Consider a window-frame similar to the following:
**
**     (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING)
**
**   The windows functions implmentation caches the input rows in a temp
**   table, sorted by "a, b" (it actually populates the cache lazily, and
**   aggressively removes rows once they are no longer required, but that's
**   a mere detail). It keeps three cursors open on the temp table. One
**   (current) that points to the next row to return to the query engine
**   once its window function values have been calculated. Another (end)
**   points to the next row to call the xStep() method of each window function
**   on (so that it is 2 groups ahead of current). And a third (start) that
**   points to the next row to call the xInverse() method of each window
**   function on.
**
**   Each cursor (start, current and end) consists of a VDBE cursor
**   (WindowCsrAndReg.csr) and an array of registers (starting at
**   WindowCodeArg.reg) that always contains a copy of the peer values 
**   read from the corresponding cursor.
**
**   Depending on the window-frame in question, all three cursors may not
**   be required. In this case both WindowCodeArg.csr and reg are set to
**   0.
*/
struct WindowCodeArg {
  Parse *pParse;             /* Parse context */
  Window *pMWin;             /* First in list of functions being processed */
  Vdbe *pVdbe;               /* VDBE object */
  int addrGosub;             /* OP_Gosub to this address to return one row */
  int regGosub;              /* Register used with OP_Gosub(addrGosub) */
  int regArg;                /* First in array of accumulator registers */
  int eDelete;               /* See above */

  WindowCsrAndReg start;
  WindowCsrAndReg current;
  WindowCsrAndReg end;
};

/*
** Generate VM code to read the window frames peer values from cursor csr into
** an array of registers starting at reg.
*/
static void windowReadPeerValues(
  WindowCodeArg *p,
  int csr,
  int reg
){
  Window *pMWin = p->pMWin;
  ExprList *pOrderBy = pMWin->pOrderBy;
  if( pOrderBy ){
    Vdbe *v = sqlite3GetVdbe(p->pParse);
    ExprList *pPart = pMWin->pPartition;
    int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
    int i;
    for(i=0; i<pOrderBy->nExpr; i++){
      sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
    }
  }
}

/*
** Generate VM code to invoke either xStep() (if bInverse is 0) or 
** xInverse (if bInverse is non-zero) for each window function in the 
** linked list starting at pMWin. Or, for built-in window functions
** that do not use the standard function API, generate the required
** inline VM code.
**
** If argument csr is greater than or equal to 0, then argument reg is
** the first register in an array of registers guaranteed to be large
** enough to hold the array of arguments for each function. In this case
** the arguments are extracted from the current row of csr into the
** array of registers before invoking OP_AggStep or OP_AggInverse
**
** Or, if csr is less than zero, then the array of registers at reg is
** already populated with all columns from the current row of the sub-query.
**
** If argument regPartSize is non-zero, then it is a register containing the
** number of rows in the current partition.
*/
static void windowAggStep(
  WindowCodeArg *p,
  Parse *pParse, 
  Window *pMWin,                  /* Linked list of window functions */
  int csr,                        /* Read arguments from this cursor */
  int bInverse,                   /* True to invoke xInverse instead of xStep */
  int reg                         /* Array of registers */
){
  Parse *pParse = p->pParse;
  Vdbe *v = sqlite3GetVdbe(pParse);
  Window *pWin;
  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
    FuncDef *pFunc = pWin->pFunc;
    int regArg;
    int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
    int nArg = windowArgCount(pWin);
    int i;

    assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );

    /* All OVER clauses in the same window function aggregate step must
    ** be the same. */
    assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)!=1 );

    for(i=0; i<nArg; i++){
      if( i!=1 || pFunc->zName!=nth_valueName ){
        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
      }else{
        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
      }
    }
1666
1667
1668
1669
1670
1671
1672
1673
1674


1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713





















1714
1715
1716
1717
1718
1719
1720






















1721
1722
1723
1724
1725
1726
1727
1410
1411
1412
1413
1414
1415
1416


1417
1418
1419
1420
1421
1422
1423
1424
















1425
1426
1427
1428
1429
1430
1431
1432
1433
1434



1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495







-
-
+
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-










-
-
-




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







      );
      assert( bInverse==0 || bInverse==1 );
      sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
    }else if( pFunc->xSFunc!=noopStepFunc ){
      int addrIf = 0;
      if( pWin->pFilter ){
        int regTmp;
        assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
        assert( pWin->bExprArgs || nArg  ||pWin->pOwner->x.pList==0 );
        assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
        assert( nArg || pWin->pOwner->x.pList==0 );
        regTmp = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
        addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
        VdbeCoverage(v);
        sqlite3ReleaseTempReg(pParse, regTmp);
      }
      
      if( pWin->bExprArgs ){
        int iStart = sqlite3VdbeCurrentAddr(v);
        VdbeOp *pOp, *pEnd;

        nArg = pWin->pOwner->x.pList->nExpr;
        regArg = sqlite3GetTempRange(pParse, nArg);
        sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);

        pEnd = sqlite3VdbeGetOp(v, -1);
        for(pOp=sqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){
          if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){
            pOp->p1 = csr;
          }
        }
      }
      if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
        CollSeq *pColl;
        assert( nArg>0 );
        pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
        sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
      }
      sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, 
                        bInverse, regArg, pWin->regAccum);
      sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
      sqlite3VdbeChangeP5(v, (u8)nArg);
      if( pWin->bExprArgs ){
        sqlite3ReleaseTempRange(pParse, regArg, nArg);
      }
      if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
    }
  }
}

typedef struct WindowCodeArg WindowCodeArg;
typedef struct WindowCsrAndReg WindowCsrAndReg;
struct WindowCsrAndReg {
  int csr;
  int reg;
};

struct WindowCodeArg {
  Parse *pParse;
  Window *pMWin;
  Vdbe *pVdbe;
  int regGosub;
  int addrGosub;
  int regArg;
  int eDelete;

  WindowCsrAndReg start;
  WindowCsrAndReg current;
  WindowCsrAndReg end;
};

/*
** Values that may be passed as the second argument to windowCodeOp().
*/
#define WINDOW_RETURN_ROW 1
#define WINDOW_AGGINVERSE 2
#define WINDOW_AGGSTEP    3

/*
** Generate VM code to read the window frames peer values from cursor csr into
** an array of registers starting at reg.
*/
static void windowReadPeerValues(
  WindowCodeArg *p,
  int csr,
  int reg
){
  Window *pMWin = p->pMWin;
  ExprList *pOrderBy = pMWin->pOrderBy;
  if( pOrderBy ){
    Vdbe *v = sqlite3GetVdbe(p->pParse);
    ExprList *pPart = pMWin->pPartition;
    int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
    int i;
    for(i=0; i<pOrderBy->nExpr; i++){
      sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
    }
  }
}

/*
** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
** (bFin==1) for each window function in the linked list starting at
** pMWin. Or, for built-in window-functions that do not use the standard
** API, generate the equivalent VM code.
*/
1775
1776
1777
1778
1779
1780
1781
1782

1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1543
1544
1545
1546
1547
1548
1549

1550
1551




1552
1553
1554
1555
1556
1557
1558







-
+

-
-
-
-







  int regRowid = 0;               /* AggStep rowid value */
  int regPeer = 0;                /* AggStep peer values */

  int nPeer;
  int lblNext;
  int lblBrk;
  int addrNext;
  int csr;
  int csr = pMWin->csrApp;

  VdbeModuleComment((v, "windowFullScan begin"));

  assert( pMWin!=0 );
  csr = pMWin->csrApp;
  nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);

  lblNext = sqlite3VdbeMakeLabel(pParse);
  lblBrk = sqlite3VdbeMakeLabel(pParse);

  regCRowid = sqlite3GetTempReg(pParse);
  regRowid = sqlite3GetTempReg(pParse);
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
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







-
+














-







      VdbeCoverageEqNe(v);
    }else{
      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext);
    }
    if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
  }

  windowAggStep(p, pMWin, csr, 0, p->regArg);
  windowAggStep(pParse, pMWin, csr, 0, p->regArg);

  sqlite3VdbeResolveLabel(v, lblNext);
  sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
  VdbeCoverage(v);
  sqlite3VdbeJumpHere(v, addrNext-1);
  sqlite3VdbeJumpHere(v, addrNext+1);
  sqlite3ReleaseTempReg(pParse, regRowid);
  sqlite3ReleaseTempReg(pParse, regCRowid);
  if( nPeer ){
    sqlite3ReleaseTempRange(pParse, regPeer, nPeer);
    sqlite3ReleaseTempRange(pParse, regCPeer, nPeer);
  }

  windowAggFinal(p, 1);
  VdbeModuleComment((v, "windowFullScan end"));
}

/*
** Invoke the sub-routine at regGosub (generated by code in select.c) to
** return the current row of Window.iEphCsr. If all window functions are
** aggregate window functions that use the standard API, a single
** OP_Gosub instruction is all that this routine generates. Extra VM code
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1712
1713
1714
1715
1716
1717
1718

1719
1720
1721
1722
1723
1724
1725







-







static int windowInitAccum(Parse *pParse, Window *pMWin){
  Vdbe *v = sqlite3GetVdbe(pParse);
  int regArg;
  int nArg = 0;
  Window *pWin;
  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
    FuncDef *pFunc = pWin->pFunc;
    assert( pWin->regAccum );
    sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
    nArg = MAX(nArg, windowArgCount(pWin));
    if( pMWin->regStartRowid==0 ){
      if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
        sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
        sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
      }
2026
2027
2028
2029
2030
2031
2032
2033

2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051



2052
2053
2054
2055
2056
2057
2058
2059





2060
2061
2062
2063
2064
2065


2066
2067
2068
2069




2070
2071
2072
2073


2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086

2087
2088
2089
2090

2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101

2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168

2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191

2192

2193
2194
2195
2196
2197
2198
2199
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







-
+
-



-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+



-
-
-
-
-
+
+
+
+
+



-
-
-
+
+
-
-
-
-
+
+
+
+


-
-
+
+








-



-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-

-





+


-
-



















+

+







    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
  }
}

/*
** This function is called as part of generating VM programs for RANGE
** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
** the ORDER BY term in the window, and that argument op is OP_Ge, it generates
** the ORDER BY term in the window, it generates code equivalent to:
** code equivalent to:
**
**   if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
**
** The value of parameter op may also be OP_Gt or OP_Le. In these cases the
** operator in the above pseudo-code is replaced with ">" or "<=", respectively.
**
** If the sort-order for the ORDER BY term in the window is DESC, then the
** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is
** subtracted. And the comparison operator is inverted to - ">=" becomes "<=",
** ">" becomes "<", and so on. So, with DESC sort order, if the argument op
** is OP_Ge, the generated code is equivalent to:
**
**   if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl;
**
** A special type of arithmetic is used such that if csr1.peerVal is not
** a numeric type (real or integer), then the result of the addition addition
** or subtraction is a a copy of csr1.peerVal.
** A special type of arithmetic is used such that if csr.peerVal is not
** a numeric type (real or integer), then the result of the addition is
** a copy of csr1.peerVal.
*/
static void windowCodeRangeTest(
  WindowCodeArg *p, 
  int op,                         /* OP_Ge, OP_Gt, or OP_Le */
  int csr1,                       /* Cursor number for cursor 1 */
  int regVal,                     /* Register containing non-negative number */
  int csr2,                       /* Cursor number for cursor 2 */
  int lbl                         /* Jump destination if condition is true */
  int op,                          /* OP_Ge or OP_Gt */
  int csr1, 
  int regVal, 
  int csr2,
  int lbl
){
  Parse *pParse = p->pParse;
  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 reg1 = sqlite3GetTempReg(pParse);
  int reg2 = sqlite3GetTempReg(pParse);
  int regString = ++pParse->nMem;           /* Reg. for constant value '' */
  int arith = OP_Add;                       /* OP_Add or OP_Subtract */
  int addrGe;                               /* Jump destination */
  CollSeq *pColl;
  int arith = OP_Add;
  int addrGe;

  int regString = ++pParse->nMem;

  assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
  assert( pOrderBy && pOrderBy->nExpr==1 );
  if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
  assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 );
  if( p->pMWin->pOrderBy->a[0].sortOrder ){
    switch( op ){
      case OP_Ge: op = OP_Le; break;
      case OP_Gt: op = OP_Lt; break;
      default: assert( op==OP_Le ); op = OP_Ge; break;
    }
    arith = OP_Subtract;
  }

  /* Read the peer-value from each cursor into a register */
  windowReadPeerValues(p, csr1, reg1);
  windowReadPeerValues(p, csr2, reg2);

  VdbeModuleComment((v, "CodeRangeTest: if( R%d %s R%d %s R%d ) goto lbl",
  /* Check if the peer value for csr1 value is a text or blob by comparing
      reg1, (arith==OP_Add ? "+" : "-"), regVal,
      ((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2
  ));

  ** it to the smallest possible string - ''. If it is, jump over the
  /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1).
  ** This block adds (or subtracts for DESC) the numeric value in regVal
  ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob),
  ** then leave reg1 as it is. In pseudo-code, this is implemented as:
  **
  **   if( reg1>='' ) goto addrGe;
  **   reg1 = reg1 +/- regVal
  **   addrGe:
  **
  ** Since all strings and blobs are greater-than-or-equal-to an empty string,
  ** the add/subtract is skipped for these, as required. If reg1 is a NULL,
  ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */
  ** then the arithmetic is performed, but since adding or subtracting from
  ** NULL is always NULL anyway, this case is handled as required too.  */
  sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
  addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
  VdbeCoverage(v);
  sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
  sqlite3VdbeJumpHere(v, addrGe);

  /* If the BIGNULL flag is set for the ORDER BY, then it is required to 
  ** consider NULL values to be larger than all other values, instead of 
  ** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this
  ** (and adding that capability causes a performance regression), so
  ** instead if the BIGNULL flag is set then cases where either reg1 or
  ** reg2 are NULL are handled separately in the following block. The code
  ** generated is equivalent to:
  **
  **   if( reg1 IS NULL ){
  **     if( op==OP_Ge ) goto lbl;
  **     if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl;
  **     if( op==OP_Le && reg2 IS NULL ) goto lbl;
  **   }else if( reg2 IS NULL ){
  **     if( op==OP_Le ) goto lbl;
  **   }
  **
  ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is 
  ** not taken, control jumps over the comparison operator coded below this
  ** block.  */
  if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){
    /* This block runs if reg1 contains a NULL. */
    int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v);
    switch( op ){
      case OP_Ge: 
        sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); 
        break;
      case OP_Gt: 
        sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); 
        VdbeCoverage(v); 
        break;
      case OP_Le: 
        sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); 
        VdbeCoverage(v); 
        break;
      default: assert( op==OP_Lt ); /* no-op */ break;
    }
    sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);

    /* This block runs if reg1 is not NULL, but reg2 is. */
    sqlite3VdbeJumpHere(v, addr);
    sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v);
    if( op==OP_Gt || op==OP_Ge ){
      sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1);
    }
  }

  /* 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);

  sqlite3ReleaseTempReg(pParse, reg1);
  sqlite3ReleaseTempReg(pParse, reg2);

  VdbeModuleComment((v, "CodeRangeTest: end"));
}

/*
** Helper function for sqlite3WindowCodeStep(). Each call to this function
** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE 
** operation. Refer to the header comment for sqlite3WindowCodeStep() for
** details.
*/
static int windowCodeOp(
 WindowCodeArg *p,                /* Context object */
 int op,                          /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */
 int regCountdown,                /* Register for OP_IfPos countdown */
 int jumpOnEof                    /* Jump here if stepped cursor reaches EOF */
){
  int csr, reg;
  Parse *pParse = p->pParse;
  Window *pMWin = p->pMWin;
  int ret = 0;
  Vdbe *v = p->pVdbe;
  int addrIf = 0; 
  int addrContinue = 0;
  int addrGoto = 0;
  int bPeer = (pMWin->eFrmType!=TK_ROWS);

  int lblDone = sqlite3VdbeMakeLabel(pParse);
  int addrNextRange = 0;

  /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
  ** starts with UNBOUNDED PRECEDING. */
2218
2219
2220
2221
2222
2223
2224
2225

2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267

2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279

2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297

2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312


2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
1899
1900
1901
1902
1903
1904
1905

1906
1907
1908
1909
1910
1911
1912
1913
1914



















1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928

1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940

1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958

1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991

1992
1993
1994
1995
1996
1997
1998
1999





2000
2001
2002

2003
2004
2005
2006
2007
2008
2009







-
+








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-














-
+











-
+

















-
+















+
+















-








-
-
-
-
-



-







        }
      }else{
        windowCodeRangeTest(
            p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone
        );
      }
    }else{
      sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, lblDone, 1);
      addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
      VdbeCoverage(v);
    }
  }

  if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){
    windowAggFinal(p, 0);
  }
  addrContinue = sqlite3VdbeCurrentAddr(v);

  /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or
  ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the 
  ** start cursor does not advance past the end cursor within the 
  ** temporary table. It otherwise might, if (a>b).  */
  if( pMWin->eStart==pMWin->eEnd && regCountdown
   && pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE
  ){
    int regRowid1 = sqlite3GetTempReg(pParse);
    int regRowid2 = sqlite3GetTempReg(pParse);
    sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
    sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
    sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
    VdbeCoverage(v);
    sqlite3ReleaseTempReg(pParse, regRowid1);
    sqlite3ReleaseTempReg(pParse, regRowid2);
    assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING );
  }

  switch( op ){
    case WINDOW_RETURN_ROW:
      csr = p->current.csr;
      reg = p->current.reg;
      windowReturnOneRow(p);
      break;

    case WINDOW_AGGINVERSE:
      csr = p->start.csr;
      reg = p->start.reg;
      if( pMWin->regStartRowid ){
        assert( pMWin->regEndRowid );
        sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
      }else{
        windowAggStep(p, pMWin, csr, 1, p->regArg);
        windowAggStep(pParse, pMWin, csr, 1, p->regArg);
      }
      break;

    default:
      assert( op==WINDOW_AGGSTEP );
      csr = p->end.csr;
      reg = p->end.reg;
      if( pMWin->regStartRowid ){
        assert( pMWin->regEndRowid );
        sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
      }else{
        windowAggStep(p, pMWin, csr, 0, p->regArg);
        windowAggStep(pParse, pMWin, csr, 0, p->regArg);
      }
      break;
  }

  if( op==p->eDelete ){
    sqlite3VdbeAddOp1(v, OP_Delete, csr);
    sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
  }

  if( jumpOnEof ){
    sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2);
    VdbeCoverage(v);
    ret = sqlite3VdbeAddOp0(v, OP_Goto);
  }else{
    sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
    VdbeCoverage(v);
    if( bPeer ){
      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblDone);
      addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
    }
  }

  if( bPeer ){
    int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
    int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0);
    windowReadPeerValues(p, csr, regTmp);
    windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue);
    sqlite3ReleaseTempRange(pParse, regTmp, nReg);
  }

  if( addrNextRange ){
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
  }
  sqlite3VdbeResolveLabel(v, lblDone);
  if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
  if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
  return ret;
}


/*
** Allocate and return a duplicate of the Window object indicated by the
** third argument. Set the Window.pOwner field of the new object to
** pOwner.
*/
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
  Window *pNew = 0;
  if( ALWAYS(p) ){
    pNew = sqlite3DbMallocZero(db, sizeof(Window));
    if( pNew ){
      pNew->zName = sqlite3DbStrDup(db, p->zName);
      pNew->zBase = sqlite3DbStrDup(db, p->zBase);
      pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
      pNew->pFunc = p->pFunc;
      pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
      pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
      pNew->eFrmType = p->eFrmType;
      pNew->eEnd = p->eEnd;
      pNew->eStart = p->eStart;
      pNew->eExclude = p->eExclude;
      pNew->regResult = p->regResult;
      pNew->regAccum = p->regAccum;
      pNew->iArgCol = p->iArgCol;
      pNew->iEphCsr = p->iEphCsr;
      pNew->bExprArgs = p->bExprArgs;
      pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
      pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
      pNew->pOwner = pOwner;
      pNew->bImplicitFrame = p->bImplicitFrame;
    }
  }
  return pNew;
}

/*
** Return a copy of the linked list of Window objects passed as the
2662
2663
2664
2665
2666
2667
2668
2669

2670
2671
2672
2673
2674
2675
2676
2319
2320
2321
2322
2323
2324
2325

2326
2327
2328
2329
2330
2331
2332
2333







-
+







**       }
**       Insert new row into eph table.
**       if( first row of partition ){
**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
**         regEnd = <expr2>
**         regStart = <expr1>
**       }else{
**         while( (csrEnd.key + regEnd) <= csrCurrent.key ){
**         if( (csrEnd.key + regEnd) <= csrCurrent.key ){
**           AGGSTEP
**         }
**         while( (csrStart.key + regStart) < csrCurrent.key ){
**           AGGINVERSE
**         }
**         RETURN_ROW
**       }
2735
2736
2737
2738
2739
2740
2741


2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408


2409
2410
2411
2412
2413
2414
2415







+
+








-
-







  int csrInput = p->pSrc->a[0].iCursor;     /* Cursor of sub-select */
  int nInput = p->pSrc->a[0].pTab->nCol;    /* Number of cols returned by sub */
  int iInput;                               /* To iterate through sub cols */
  int addrNe;                     /* Address of OP_Ne */
  int addrGosubFlush = 0;         /* Address of OP_Gosub to flush: */
  int addrInteger = 0;            /* Address of OP_Integer */
  int addrEmpty;                  /* Address of OP_Rewind in flush: */
  int regStart = 0;               /* Value of <expr> PRECEDING */
  int regEnd = 0;                 /* Value of <expr> FOLLOWING */
  int regNew;                     /* Array of registers holding new input row */
  int regRecord;                  /* regNew array in record form */
  int regRowid;                   /* Rowid for regRecord in eph table */
  int regNewPeer = 0;             /* Peer values for new row (part of regNew) */
  int regPeer = 0;                /* Peer values for current row */
  int regFlushPart = 0;           /* Register for "Gosub flush_partition" */
  WindowCodeArg s;                /* Context object for sub-routines */
  int lblWhereEnd;                /* Label just before sqlite3WhereEnd() code */
  int regStart = 0;               /* Value of <expr> PRECEDING */
  int regEnd = 0;                 /* Value of <expr> FOLLOWING */

  assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT 
       || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED 
  );
  assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT 
       || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING 
  );
2875
2876
2877
2878
2879
2880
2881
2882

2883
2884
2885
2886

2887
2888
2889

2890
2891
2892
2893
2894
2895
2896
2532
2533
2534
2535
2536
2537
2538

2539
2540
2541
2542

2543
2544
2545

2546
2547
2548
2549
2550
2551
2552
2553







-
+



-
+


-
+







  VdbeCoverageNeverNull(v);

  /* This block is run for the first row of each partition */
  s.regArg = windowInitAccum(pParse, pMWin);

  if( regStart ){
    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
    windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE?3:0));
    windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
  }
  if( regEnd ){
    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
    windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE?3:0));
    windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
  }

  if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){
  if( pMWin->eStart==pMWin->eEnd && regStart ){
    int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
    int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
    VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */
    VdbeCoverageNeverNullIf(v, op==OP_Le); /*   values previously checked */
    windowAggFinal(&s, 0);
    sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
    VdbeCoverageNeverTaken(v);

Changes to test/affinity2.test.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23







-







#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is type affinity in comparison operations.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix affinity2

do_execsql_test affinity2-100 {
  CREATE TABLE t1(
    xi INTEGER,
    xr REAL,
    xb BLOB,
    xn NUMERIC,
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
54
55
56
57
58
59
60










































































61







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  SELECT rowid, xn==xt, xn==xb, xn==+xt FROM t1 ORDER BY rowid;
} {1 1 1 1 2 1 1 1 3 1 1 1}

do_execsql_test affinity2-300 {
  SELECT rowid, xt==+xi, xt==xi, xt==xb FROM t1 ORDER BY rowid;
} {1 1 1 0 2 1 1 1 3 0 1 1}

#-------------------------------------------------------------------------
do_execsql_test 400 {
  CREATE TABLE ttt(c0, c1);
  CREATE INDEX ii ON ttt(CAST(c0 AS NUMERIC)); 
  INSERT INTO ttt VALUES('abc', '-1');
}
do_execsql_test 410 {
  SELECT * FROM ttt WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid; 
} {abc -1}
do_execsql_test 420 {
  SELECT * FROM ttt INDEXED BY ii WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid;
} {abc -1}

do_execsql_test 430 {
  CREATE TABLE t3(a, b, c INTEGER);
  CREATE INDEX t3ac ON t3(a, c-1);
  INSERT INTO t3 VALUES(1, 1, 1);
  INSERT INTO t3 VALUES(2, 1, 0);
  INSERT INTO t3 VALUES(3, 1, 1);
  INSERT INTO t3 VALUES(4, 1, 0);
  INSERT INTO t3 VALUES(5, 1, 1);
}
do_execsql_test 440 {
  SELECT * FROM t3 WHERE c='0' ORDER BY a;
} {2 1 0 4 1 0}

# 2019-08-22 ticket https://sqlite.org/src/info/d99f1ffe836c591ac57f
# False positive in sqlite3ExprNeedsNoAffinityChange()
#
do_execsql_test 500 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 TEXT UNIQUE, c1);
  INSERT INTO t0(c0) VALUES (-1);
  SELECT quote(- x'ce'), quote(t0.c0), quote(- x'ce' >= t0.c0) FROM t0;
} {0 '-1' 1}
do_execsql_test 501 {
  SELECT * FROM t0 WHERE - x'ce' >= t0.c0;
} {-1 {}}
do_execsql_test 502 {
  SELECT quote(+-+x'ce'), quote(t0.c0), quote(+-+x'ce' >= t0.c0) FROM t0;
} {0 '-1' 1}
do_execsql_test 503 {
  SELECT * FROM t0 WHERE +-+x'ce' >= t0.c0;
} {-1 {}}
do_execsql_test 504 {
  SELECT quote(- 'ce'), quote(t0.c0), quote(- 'ce' >= t0.c0) FROM t0;
} {0 '-1' 1}
do_execsql_test 505 {
  SELECT * FROM t0 WHERE - 'ce' >= t0.c0;
} {-1 {}}
do_execsql_test 506 {
  SELECT quote(+-+'ce'), quote(t0.c0), quote(+-+'ce' >= t0.c0) FROM t0;
} {0 '-1' 1}
do_execsql_test 507 {
  SELECT * FROM t0 WHERE +-+'ce' >= t0.c0;
} {-1 {}}
 
# 2019-08-30 ticket https://www.sqlite.org/src/info/40812aea1fde9594
#
# Due to some differences in floating point computations, these tests do not
# work under valgrind.
#
if {![info exists ::G(valgrind)]} {
  do_execsql_test 600 {
    DROP TABLE IF EXISTS t0;
    CREATE TABLE t0(c0 REAL UNIQUE);
    INSERT INTO t0(c0) VALUES (3175546974276630385);
    SELECT 3175546974276630385 < c0 FROM t0;
  } {1}
  do_execsql_test 601 {
    SELECT 1 FROM t0 WHERE 3175546974276630385 < c0;
  } {1}
}

finish_test

Changes to test/affinity3.test.

68
69
70
71
72
73
74
75
76
77
78




79
80
81
82
83
84
85
68
69
70
71
72
73
74




75
76
77
78
79
80
81
82
83
84
85







-
-
-
-
+
+
+
+







  INSERT INTO data VALUES('4','xyz');
  CREATE VIEW idmap as
      SELECT * FROM map_integer
      UNION SELECT * FROM map_text;
  CREATE TABLE mzed AS SELECT * FROM idmap;
}

#do_execsql_test affinity3-210 {
  #PRAGMA automatic_index=ON;
  #SELECT * FROM data JOIN idmap USING(id);
#} {1 abc a 4 xyz e}
do_execsql_test affinity3-210 {
  PRAGMA automatic_index=ON;
  SELECT * FROM data JOIN idmap USING(id);
} {1 abc a 4 xyz e}
do_execsql_test affinity3-220 {
  SELECT * FROM data JOIN mzed USING(id);
} {1 abc a 4 xyz e}

do_execsql_test affinity3-250 {
  PRAGMA automatic_index=OFF;
  SELECT * FROM data JOIN idmap USING(id);

Changes to test/aggnested.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

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
-
+


















-







# 2012-08-23
# 2012 August 23
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for processing aggregate queries with 
# subqueries in which the subqueries hold the aggregate functions
# or in which the subqueries are themselves aggregate queries
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix aggnested

do_test aggnested-1.1 {
  db eval {
    CREATE TABLE t1(a1 INTEGER);
    INSERT INTO t1 VALUES(1), (2), (3);
    CREATE TABLE t2(b1 INTEGER);
    INSERT INTO t2 VALUES(4), (5);
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
228
229
230
231
232
233
234

235



236








































































237







-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_test aggnested-3.16 {
  db eval {
    SELECT max(value1), (SELECT sum(value2=value1) FROM t2)
      FROM t1
     GROUP BY id1;
  }
} {12 2 34 4}

 
# 2019-08-31
# Problem found by dbsqlfuzz
#

do_execsql_test aggnested-4.1 {
  DROP TABLE IF EXISTS aa;
  DROP TABLE IF EXISTS bb;
  CREATE TABLE aa(x INT);  INSERT INTO aa(x) VALUES(123);
  CREATE TABLE bb(y INT);  INSERT INTO bb(y) VALUES(456);
  SELECT (SELECT sum(x+(SELECT y)) FROM bb) FROM aa;
} {579}
do_execsql_test aggnested-4.2 {
  SELECT (SELECT sum(x+y) FROM bb) FROM aa;
} {579}
do_execsql_test aggnested-4.3 {
  DROP TABLE IF EXISTS tx;
  DROP TABLE IF EXISTS ty;
  CREATE TABLE tx(x INT);
  INSERT INTO tx VALUES(1),(2),(3),(4),(5);
  CREATE TABLE ty(y INT);
  INSERT INTO ty VALUES(91),(92),(93);
  SELECT min((SELECT count(y) FROM ty)) FROM tx;
} {3}
do_execsql_test aggnested-4.4 {
  SELECT max((SELECT a FROM (SELECT count(*) AS a FROM ty) AS s)) FROM tx;
} {3}

#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 5.0 {
  CREATE TABLE x1(a, b);
  INSERT INTO x1 VALUES(1, 2);
  CREATE TABLE x2(x);
  INSERT INTO x2 VALUES(NULL), (NULL), (NULL);
}

# At one point, aggregate "total()" in the query below was being processed
# as part of the outer SELECT, not as part of the sub-select with no FROM
# clause.
do_execsql_test 5.1 {
  SELECT ( SELECT total( (SELECT b FROM x1) ) ) FROM x2;
} {2.0 2.0 2.0}

do_execsql_test 5.2 {
  SELECT ( SELECT total( (SELECT 2 FROM x1) ) ) FROM x2;
} {2.0 2.0 2.0}

do_execsql_test 5.3 {
  CREATE TABLE t1(a);
  CREATE TABLE t2(b);
}

do_execsql_test 5.4 {
  SELECT(
    SELECT max(b) LIMIT (
      SELECT total( (SELECT a FROM t1) )
    )
  )
  FROM t2;
} {{}}

do_execsql_test 5.5 {
  CREATE TABLE a(b);
  WITH c AS(SELECT a)
    SELECT(SELECT(SELECT group_concat(b, b)
          LIMIT(SELECT 0.100000 *
            AVG(DISTINCT(SELECT 0 FROM a ORDER BY b, b, b))))
        FROM a GROUP BY b,
        b, b) FROM a EXCEPT SELECT b FROM a ORDER BY b,
    b, b;
}


 

finish_test

Changes to test/alter.test.

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
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







-
+












-
+







  }
} {1 18 2 9}

#--------------------------------------------------------------------------
# alter-9.X - Special test: Make sure the sqlite_rename_column() and
# rename_table() functions do not crash when handed bad input.
#
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_test alter-9.1 {
  execsql {SELECT SQLITE_RENAME_COLUMN(0,0,0,0,0,0,0,0,0)}
} {{}}
foreach {tn sql} {
    1 { SELECT SQLITE_RENAME_TABLE(0,0,0,0,0,0,0) }
    2 { SELECT SQLITE_RENAME_TABLE(10,20,30,40,50,60,70) }
    3 { SELECT SQLITE_RENAME_TABLE('foo','foo','foo','foo','foo','foo','foo') }
} {
  do_test alter-9.2.$tn {
    catch { execsql $sql }
  } 1
}
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0

# If the INTERNAL_FUNCTIONS test-control is disabled (which is the default),
# then the sqlite_rename_table() SQL function is not accessible to ordinary SQL.
#
do_catchsql_test alter-9.3 {
  SELECT sqlite_rename_table(0,0,0,0,0,0,0);
} {1 {no such function: sqlite_rename_table}}
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
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







-
















+







  }
} {t3102a_rename t3102b_rename t3102c}

# Ticket #3651
do_test alter-14.1 {
  catchsql {
    CREATE TABLE t3651(a UNIQUE);
    INSERT INTO t3651 VALUES(5);
    ALTER TABLE t3651 ADD COLUMN b UNIQUE;
  }
} {1 {Cannot add a UNIQUE column}}
do_test alter-14.2 {
  catchsql {
    ALTER TABLE t3651 ADD COLUMN b PRIMARY KEY;
  }
} {1 {Cannot add a PRIMARY KEY column}}


#-------------------------------------------------------------------------
# Test that it is not possible to use ALTER TABLE on any system table.
#
set system_table_list {1 sqlite_master}
catchsql ANALYZE
ifcapable analyze { lappend system_table_list 2 sqlite_stat1 }
ifcapable stat3   { lappend system_table_list 3 sqlite_stat3 }
ifcapable stat4   { lappend system_table_list 4 sqlite_stat4 }

foreach {tn tbl} $system_table_list {
  do_test alter-15.$tn.1 {
    catchsql "ALTER TABLE $tbl RENAME TO xyz"
  } [list 1 "table $tbl may not be altered"]

899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
899
900
901
902
903
904
905












906







-
-
-
-
-
-
-
-
-
-
-
-

    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/alter3.test.

50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65







-

+







# This procedure returns the value of the file-format in file 'test.db'.
# 
proc get_file_format {{fname test.db}} {
  return [hexio_get_int [hexio_read $fname 44 4]]
}

do_test alter3-1.1 {
  sqlite3_db_config db LEGACY_FILE_FORMAT 1
  execsql {
    PRAGMA legacy_file_format=ON;
    CREATE TABLE abc(a, b, c);
    SELECT sql FROM sqlite_master;
  }
} {{CREATE TABLE abc(a, b, c)}}
do_test alter3-1.2 {
  execsql {ALTER TABLE abc ADD d INTEGER;}
  execsql {
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
112
113
114
115
116
117
118

119
120
121
122
123
124
125







-







    DROP TABLE t3; 
  }
} {}

do_test alter3-2.1 {
  execsql {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1,2);
  }
  catchsql {
    ALTER TABLE t1 ADD c PRIMARY KEY;
  }
} {1 {Cannot add a PRIMARY KEY column}}
do_test alter3-2.2 {
  catchsql {
195
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209







-

+







  } {11}
}

do_test alter3-4.1 {
  db close
  forcedelete test.db
  set ::DB [sqlite3 db test.db]
  sqlite3_db_config db LEGACY_FILE_FORMAT 1
  execsql {
    PRAGMA legacy_file_format=ON;
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 100);
    INSERT INTO t1 VALUES(2, 300);
    SELECT * FROM t1;
  }
} {1 100 2 300}
do_test alter3-4.1 {

Changes to test/alter4.test.

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
119
120
121
122
123
124
125

126
127
128
129
130
131
132







-







    DROP TABLE t3; 
  }
} {}

do_test alter4-2.1 {
  execsql {
    CREATE TABLE temp.t1(a, b);
    INSERT INTO t1 VALUES(1,2);
  }
  catchsql {
    ALTER TABLE t1 ADD c PRIMARY KEY;
  }
} {1 {Cannot add a PRIMARY KEY column}}
do_test alter4-2.2 {
  catchsql {
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
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







-

+












-







# does not corrupt DESC indexes.
#
# Ticket https://www.sqlite.org/src/tktview/f68bf68513a1c
#
do_test alter4-10.1 {
  db close
  sqlite3 db :memory:
  sqlite3_db_config db LEGACY_FILE_FORMAT 1
  db eval {
    PRAGMA legacy_file_format=on;
    CREATE TABLE t1(a,b,c);
    CREATE INDEX t1a ON t1(a DESC);
    INSERT INTO t1 VALUES(1,2,3);
    INSERT INTO t1 VALUES(2,3,4);
    ALTER TABLE t1 ADD COLUMN d;
    PRAGMA integrity_check;
  }
} {ok}

reset_db
do_execsql_test alter4-11.0 {
  CREATE TABLE t1(c INTEGER PRIMARY KEY, d);
  INSERT INTO t1(c,d) VALUES(1,2);
  PRAGMA foreign_keys = on;
  ALTER TABLE t1 ADD COLUMN e;
}

do_execsql_test alter4-11.1 {
  ALTER TABLE t1 ADD COLUMN f REFERENCES t1;
}

Changes to test/alterauth2.test.

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
91
92
93
94
95
96
97

















98







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  {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
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 {
612
613
614
615
616
617
618
619

620
621
622
623
624
625
626
614
615
616
617
618
619
620

621
622
623
624
625
626
627
628







-
+







    ALTER TABLE x1 RENAME COLUMN t TO ttt;
  } "1 {error in trigger tr1: $error}"
}

#-------------------------------------------------------------------------
# Passing invalid parameters directly to sqlite_rename_column().
#
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_execsql_test 14.1 {
  CREATE TABLE ddd(sql, type, object, db, tbl, icol, znew, bquote);
  INSERT INTO ddd VALUES(
      'CREATE TABLE x1(i INTEGER, t TEXT)',
      'table', 'x1', 'main', 'x1', -1, 'zzz', 0
  ), (
      'CREATE TABLE x1(i INTEGER, t TEXT)',
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651







-
+







} {}

do_execsql_test 14.2 {
  SELECT 
  sqlite_rename_column(sql, type, object, db, tbl, icol, znew, bquote, 0)
  FROM ddd;
} {{} {} {} {}}
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0

# If the INTERNAL_FUNCTIONS test-control is disabled (which is the default)
# then the sqlite_rename_table() SQL function is not accessible to
# ordinary SQL.
#
do_catchsql_test 14.3 {
  SELECT sqlite_rename_column(0,0,0,0,0,0,0,0,0);
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
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))}}

#-------------------------------------------------------------------------
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}
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 22.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, othername, extra AS (c + 1));
  ALTER TABLE t1 RENAME a to othername;
  SELECT sql FROM sqlite_schema;
} {
  {CREATE TABLE t1(othername, b)}
  {CREATE TABLE t2(c, othername, extra AS (c + 1))}
}


finish_test

Deleted 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

Deleted 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
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































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 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}}

# 2021-04-06 dbsqlfuzz crash-331c5c29bb76257b198f1318eef3288f9624c8ce
reset_db
do_execsql_test 7.0 {
  CREATE TABLE t1(a, b, c, PRIMARY KEY(a COLLATE nocase, a)) WITHOUT ROWID;
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
}
do_execsql_test 7.1 {
  ALTER TABLE t1 DROP COLUMN c;                
}
do_execsql_test 7.2 {
  SELECT sql FROM sqlite_schema;
} {{CREATE TABLE t1(a, b, PRIMARY KEY(a COLLATE nocase, a)) WITHOUT ROWID}}
do_execsql_test 7.3 {
  SELECT * FROM t1;
} {1 2 4 5}

foreach {tn wo} {
  1 {}
  2 {WITHOUT ROWID}
} {
  reset_db
  do_execsql_test 9.$tn.0 "
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) $wo;
  "
  do_execsql_test 9.$tn.1 {
    WITH s(i) AS (
        SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000
    )
    INSERT INTO t1(a, b, c) SELECT i, 123, 456 FROM s;
  }
  do_execsql_test 9.$tn.2 {
    ALTER TABLE t1 DROP COLUMN b;
  }

  do_execsql_test 9.$tn.3 {
    SELECT count(*), c FROM t1 GROUP BY c;
  } {50000 456}
}

finish_test

Deleted 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
215
216
217
218
219
220
221
222






























































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 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-52436-31752 The column is a PRIMARY KEY or part of one.
#
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"
}
do_atdc_error_test 2.1.2 {
  CREATE TABLE x1(a,b,c,d,e, PRIMARY KEY(b,c,d));
} { 
  ALTER TABLE x1 DROP COLUMN c
} {
  cannot drop PRIMARY KEY column: "c"
}

# 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-47838-03249 The column is named in a table or column
# CHECK constraint not associated with the column being dropped.
#
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.
#

# STALE-EVIDENCE: 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
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}}
} {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 {error in index t2expr after rename: no such column: t2.b}}
} {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}
}

Deleted 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.

236
237
238
239
240
241
242
243

244
245
246
247
248
249

250
251
252
253
254
255
256
236
237
238
239
240
241
242

243
244
245
246
247
248

249
250
251
252
253
254
255
256







-
+





-
+







    ), (
        'main', 'CREATE TABLE x1(i INTEGER, t TEXT)', NULL, 'eee', 0
    ), (
        'main', NULL, 'ddd', 'eee', 0
    );
  } {}
  
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
  do_execsql_test 7.2 {
    SELECT 
    sqlite_rename_table(db, 0, 0, sql, zOld, zNew, bTemp)
    FROM ddd;
  } {{} {} {}}
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
}

#-------------------------------------------------------------------------
#
reset_db
forcedelete test.db2
do_execsql_test 8.1 {
538
539
540
541
542
543
544
545

546
547
548
549

550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573

574
575
576
577

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
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








-
+



-
+
-
-
-
-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+



-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-

  sqlite3_db_config db DEFENSIVE 1

  do_execsql_test 16.0 {
    CREATE VIRTUAL TABLE y1 USING fts3;
  }

  do_catchsql_test 16.10 {
  do_catchsql_test 16.1 {
    INSERT INTO y1_segments VALUES(1, X'1234567890');
  } {1 {table y1_segments may not be modified}}

  do_catchsql_test 16.20 {
  do_catchsql_test 16.2 {
    DROP TABLE y1_segments;
  } {1 {table y1_segments may not be dropped}}

  do_catchsql_test 16.20 {
    ALTER TABLE y1_segments RENAME TO abc;
  } {1 {table y1_segments may not be altered}}
  sqlite3_db_config db DEFENSIVE 0
  do_catchsql_test 16.22 {
    ALTER TABLE y1_segments RENAME TO abc;
  } {0 {}}
  sqlite3_db_config db DEFENSIVE 1
  do_catchsql_test 16.23 {
    CREATE TABLE y1_segments AS SELECT * FROM abc;
  } {1 {object name reserved for internal use: y1_segments}}
  do_catchsql_test 16.24 {
    CREATE VIEW y1_segments AS SELECT * FROM abc;
  } {1 {object name reserved for internal use: y1_segments}}
  sqlite3_db_config db DEFENSIVE 0
  do_catchsql_test 16.25 {
    ALTER TABLE abc RENAME TO y1_segments;
  } {0 {}}
  sqlite3_db_config db DEFENSIVE 1

  do_execsql_test 16.30 {
  do_execsql_test 16.3 {
    ALTER TABLE y1 RENAME TO z1;
  }

  do_execsql_test 16.40 {
  do_execsql_test 16.4 {
    SELECT * FROM z1_segments;
  }
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 17.0 {
  CREATE TABLE sqlite1234 (id integer);
  ALTER TABLE sqlite1234 RENAME TO User;
  SELECT name, sql FROM sqlite_master WHERE sql IS NOT NULL;
} {
  User {CREATE TABLE "User" (id integer)}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 18.1.0 {
  CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0)) WITHOUT ROWID;
}
do_execsql_test 18.1.1 {
  ALTER TABLE t0 RENAME COLUMN c0 TO c1;
}
do_execsql_test 18.1.2 {
  SELECT sql FROM sqlite_master;
} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1)) WITHOUT ROWID}}

reset_db
do_execsql_test 18.2.0 {
  CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0));
}
do_execsql_test 18.2.1 {
  ALTER TABLE t0 RENAME COLUMN c0 TO c1;
}
do_execsql_test 18.2.2 {
  SELECT sql FROM sqlite_master;
} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}}

# 2020-02-23 ticket f50af3e8a565776b
reset_db
do_execsql_test 19.100 {
  CREATE TABLE t1(x);
  CREATE VIEW t2 AS SELECT 1 FROM t1, (t1 AS a0, t1);
  ALTER TABLE t1 RENAME TO t3;
  SELECT sql FROM sqlite_master;
} {{CREATE TABLE "t3"(x)} {CREATE VIEW t2 AS SELECT 1 FROM "t3", ("t3" AS a0, "t3")}}
do_execsql_test 19.110 {
  INSERT INTO t3(x) VALUES(123);
  SELECT * FROM t2;
} {1}
do_execsql_test 19.120 {
  INSERT INTO t3(x) VALUES('xyz');
  SELECT * FROM t2;
} {1 1 1 1 1 1 1 1}

# Ticket 4722bdab08cb14
reset_db
do_execsql_test 20.0 {
  CREATE TABLE a(a);
  CREATE VIEW b AS SELECT(SELECT *FROM c JOIN a USING(d, a, a, a) JOIN a) IN();
}
do_execsql_test 20.1 {
  ALTER TABLE a RENAME a TO e;
} {}

reset_db
do_execsql_test 21.0 {
  CREATE TABLE a(b);
  CREATE VIEW c AS 
      SELECT NULL INTERSECT 
      SELECT NULL ORDER BY
      likelihood(NULL, (d, (SELECT c)));
} {}
do_catchsql_test 21.1 {
  SELECT likelihood(NULL, (d, (SELECT c)));
} {1 {second argument to likelihood() must be a constant between 0.0 and 1.0}}
do_catchsql_test 21.2 {
  SELECT * FROM c;
} {1 {1st ORDER BY term does not match any column in the result set}}

do_catchsql_test 21.3 {
  ALTER TABLE a RENAME TO e;
} {1 {error in view c: 1st ORDER BY term does not match any column in the result set}}

# After forum thread https://sqlite.org/forum/forumpost/ddbe1c7efa
# Ensure that PRAGMA schema_version=N causes a full schema reload.
#
reset_db
do_execsql_test 22.0 {
  CREATE TABLE t1(a INT, b TEXT NOT NULL);
  INSERT INTO t1 VALUES(1,2),('a','b');
  BEGIN;
  PRAGMA writable_schema=ON;
  UPDATE sqlite_schema SET sql='CREATE TABLE t1(a INT, b TEXT)' WHERE name LIKE 't1';
  PRAGMA schema_version=1234;
  COMMIT;
  PRAGMA integrity_check;
} {ok}
do_execsql_test 22.1 {
  ALTER TABLE t1 ADD COLUMN c INT DEFAULT 78;
  SELECT * FROM t1;
} {1 2 78 a b 78}

#-------------------------------------------------------------------------
reset_db
db collate compare64 compare64

do_execsql_test 23.1 {
  CREATE TABLE gigo(a text);
  CREATE TABLE idx(x text COLLATE compare64);
  CREATE VIEW v1 AS SELECT * FROM idx WHERE x='abc';
}
db close
sqlite3 db test.db

do_execsql_test 23.2 {
  alter table gigo rename to ggiiggoo;
  alter table idx rename to idx2;
}

do_execsql_test 23.3 {
  SELECT sql FROM sqlite_master;
} {
  {CREATE TABLE "ggiiggoo"(a text)} 
  {CREATE TABLE "idx2"(x text COLLATE compare64)}
  {CREATE VIEW v1 AS SELECT * FROM "idx2" WHERE x='abc'}
}

do_execsql_test 23.4 {
  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/altertab2.test.

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
334
335
336
337
338
339
340

341
342
343
344





345
346
347
348
349




350
351




352








-
+



-
-
-
-
-
+




-
-
-
-
+
+
-
-
-
-

-
do_catchsql_test 8.2 {
  ALTER TABLE t1 RENAME a TO aaa;
} {1 {error in trigger tr after rename: no such column: a}}
do_execsql_test 8.3 {
  INSERT INTO t3 VALUES(4, 5, 6);
}

do_execsql_test 8.4 {
do_execsql_test 8.1 {
  CREATE TABLE t4(a, b);
  CREATE VIEW v4 AS SELECT * FROM t4 WHERE (a=1 AND 0) OR b=2;
}

# Branches of an expression tree that are optimized out by the AND 
# optimization are renamed.
#
do_execsql_test 8.5 {
do_execsql_test 8.2 {
  ALTER TABLE t4 RENAME a TO c;
  SELECT sql FROM sqlite_master WHERE name = 'v4'
} {{CREATE VIEW v4 AS SELECT * FROM t4 WHERE (c=1 AND 0) OR b=2}}

# 2019-06-10 https://www.sqlite.org/src/info/533010b8cacebe82
reset_db
do_catchsql_test 8.6 {
  CREATE TABLE t0(c0);
finish_test

  CREATE INDEX i0 ON t0(LIKELIHOOD(1,2) AND 0);
  ALTER TABLE t0 RENAME TO t1;
  SELECT sql FROM sqlite_master WHERE name='i0';
} {1 {error in index i0: second argument to likelihood() must be a constant between 0.0 and 1.0}}

finish_test

Changes to test/altertab3.test.

75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89







-
+








do_execsql_test 3.1 {
  ALTER TABLE t1 RENAME b TO bbb;
}

do_execsql_test 3.2 {
  SELECT sql FROM sqlite_master WHERE name = 'v1'
} {{CREATE VIEW v1 AS SELECT * FROM t1 WHERE a=1 OR (b IN ())}}
} {{CREATE VIEW v1 AS SELECT * FROM t1 WHERE a=1 OR (bbb IN ())}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t3(e, f);
  CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
138
139
140
141
142
143
144


























































145



































































































































































































146










147

























































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
  );
}

do_execsql_test 6.1 {
  ALTER TABLE Table0 RENAME Col0 TO Col0;
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.1.0 {
  CREATE TABLE t1(a,b,c);
  CREATE TRIGGER AFTER INSERT ON t1 BEGIN
    SELECT a, rank() OVER w1 FROM t1
    WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1);
  END;
}

do_execsql_test 7.1.2 {
  ALTER TABLE t1 RENAME TO t1x;
  SELECT sql FROM sqlite_master;
} {
  {CREATE TABLE "t1x"(a,b,c)}
  {CREATE TRIGGER AFTER INSERT ON "t1x" BEGIN
    SELECT a, rank() OVER w1 FROM "t1x"
    WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1);
  END}
}

do_execsql_test 7.2.1 {
  DROP TRIGGER after;
  CREATE TRIGGER AFTER INSERT ON t1x BEGIN
    SELECT a, rank() OVER w1 FROM t1x
    WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1 ORDER BY d);
  END;
}

do_catchsql_test 7.2.2 {
  ALTER TABLE t1x RENAME TO t1;
} {1 {error in trigger AFTER: no such column: d}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 8.0 {
  CREATE TABLE t0(c0);
  CREATE INDEX i0 ON t0('1' IN ());
}
do_execsql_test 8.1 {
  ALTER TABLE t0 RENAME TO t1;
  SELECT sql FROM sqlite_master;
} {
  {CREATE TABLE "t1"(c0)}
  {CREATE INDEX i0 ON "t1"('1' IN ())}
}
do_execsql_test 8.2.1 {
  CREATE TABLE t2 (c0);
  CREATE INDEX i2 ON t2((LIKELIHOOD(c0, 100) IN ()));
  ALTER TABLE t2 RENAME COLUMN c0 TO c1;
}
do_execsql_test 8.2.2 {
  SELECT sql FROM sqlite_master WHERE tbl_name = 't2';
} {
  {CREATE TABLE t2 (c1)} 
  {CREATE INDEX i2 ON t2((LIKELIHOOD(c0, 100) IN ()))}
}
do_test 8.2.3 {
finish_test
  sqlite3 db2 test.db
  db2 eval { INSERT INTO t2 VALUES (1), (2), (3) }
  db close
} {}
db2 close

#-------------------------------------------------------------------------
reset_db
do_execsql_test 9.1 {
  CREATE TABLE t1(a,b,c);
  CREATE TRIGGER AFTER INSERT ON t1 WHEN new.a NOT NULL BEGIN
    SELECT true WHERE (SELECT a, b FROM (t1)) IN ();
  END;
}
do_execsql_test 9.2 {
  ALTER TABLE t1 RENAME TO t1x;
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 10.1 {
  CREATE TABLE t1(a, b, c);
  CREATE TABLE t2(a, b, c);
  CREATE VIEW v1 AS SELECT * FROM t1 WHERE (
    SELECT t1.a FROM t1, t2
  ) IN () OR t1.a=5;
}

do_execsql_test 10.2 {
  ALTER TABLE t2 RENAME TO t3;
  SELECT sql FROM sqlite_master WHERE name='v1';
} {
  {CREATE VIEW v1 AS SELECT * FROM t1 WHERE (
    SELECT t1.a FROM t1, t2
  ) IN () OR t1.a=5}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 11.1 {
  CREATE TABLE t1(
      a,b,c,d,e,f,g,h,j,jj,jjb,k,aa,bb,cc,dd,ee DEFAULT 3.14,
      ff DEFAULT('hiccup'),Wg NOD NULL DEFAULT(false)
  );

  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 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;
} {}

do_execsql_test 11.4 {
  ALTER TABLE t1 RENAME TO t1x;
  SELECT sql FROM sqlite_master WHERE name = 'b';
} {
{CREATE TRIGGER b AFTER INSERT ON "t1x" WHEN new.a BEGIN
    SELECT a, sum() w3 FROM "t1x" 
    WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM "t1x"));
  END}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 12.1 {
CREATE TABLE t1(a,b,c,d,e,f,g,h,j,jj,Zjj,k,aQ,bb,cc,dd,ee DEFAULT 3.14,
ff DEFAULT('hiccup'),gg NOD NULL DEFAULT(false));
CREATE TRIGGER AFTER INSERT ON t1 WHEN new.a NOT NULL BEGIN

SELECT b () OVER , dense_rank() OVER d, d () OVER w1
FROM t1
WINDOW
w1 AS
( w1 ORDER BY d
ROWS BETWEEN 2 NOT IN(SELECT a, sum(d) w2,max(d)OVER FROM t1
WINDOW
w1 AS
(PARTITION BY d
ROWS BETWEEN '' PRECEDING AND false FOLLOWING),
d AS
(PARTITION BY b ORDER BY d
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
) PRECEDING AND 1 FOLLOWING),
w2 AS
(PARTITION BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
w3 AS
(PARTITION BY b ORDER BY d
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
;
SELECT a, sum(d) w2,max(d)OVER FROM t1
WINDOW
w1 AS
(PARTITION BY d
ROWS BETWEEN '' PRECEDING AND false FOLLOWING),
d AS
(PARTITION BY b ORDER BY d
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
;

END;
}

do_execsql_test 12.2 {
  ALTER TABLE t1 RENAME TO t1x;
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 13.1 {
  CREATE TABLE t1(a);
  CREATE TRIGGER r1 INSERT ON t1 BEGIN
    SELECT a(*) OVER (ORDER BY (SELECT 1)) FROM t1;
  END;
}

do_execsql_test 13.2 {
  ALTER TABLE t1 RENAME TO t1x;
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 14.1 {
  CREATE TABLE t1(a);
  CREATE TABLE t2(b);
  CREATE TRIGGER AFTER INSERT ON t1 BEGIN
    SELECT sum() FILTER (WHERE (SELECT sum() FILTER (WHERE 0)) AND a);
  END;
}

do_catchsql_test 14.2 {
  ALTER TABLE t1 RENAME TO t1x;
} {1 {error in trigger AFTER: no such column: a}}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 16.1 {
  CREATE TABLE t1(x);
  CREATE TRIGGER AFTER INSERT ON t1 BEGIN
    SELECT (WITH t2 AS (WITH t3 AS (SELECT true)
          SELECT * FROM t3 ORDER BY true COLLATE nocase)
        SELECT 11);

    WITH t4 AS (SELECT * FROM t1) SELECT 33;
  END;
}
do_execsql_test 16.2 {
  ALTER TABLE t1 RENAME TO t1x;
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 17.1 {
  CREATE TABLE t1(a,b,c);
  CREATE TRIGGER AFTER INSERT ON t1 WHEN new.a NOT NULL BEGIN
    SELECT a () FILTER (WHERE a>0) FROM t1;
  END;
}

do_execsql_test 17.2 {
  ALTER TABLE t1 RENAME TO t1x;
  ALTER TABLE t1x RENAME a TO aaa;
  SELECT sql FROM sqlite_master WHERE type='trigger';
} {
{CREATE TRIGGER AFTER INSERT ON "t1x" WHEN new.aaa NOT NULL BEGIN
    SELECT a () FILTER (WHERE aaa>0) FROM "t1x";
  END}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 18.1 {
  CREATE TABLE t1(a,b);
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
    SELECT a, b FROM t1
    INTERSECT SELECT b,a FROM t1
    ORDER BY b IN (
        SELECT a UNION SELECT b
        FROM t1
        ORDER BY b COLLATE nocase
        )
    ;
  END;
}

do_catchsql_test 18.2 {
    SELECT a, b FROM t1
    INTERSECT 
    SELECT b,a FROM t1
    ORDER BY b IN (
        SELECT a UNION SELECT b
        FROM t1
        ORDER BY b COLLATE nocase
        );
} {1 {1st ORDER BY term does not match any column in the result set}}

do_catchsql_test 18.3 {
  ALTER TABLE t1 RENAME TO t1x;
} {1 {error in trigger r1: 1st ORDER BY term does not match any column in the result set}}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 19.0 {
  CREATE TABLE a(a,h CONSTRAINT a UNIQUE ON CONFLICT FAIL,CONSTRAINT a);
}

foreach {tn v res} {
  1 {
    CREATE VIEW q AS SELECT 123
    
      WINDOW x AS (
        RANGE BETWEEN UNBOUNDED PRECEDING AND INDEXED() OVER(
          PARTITION BY ( WITH x AS(VALUES(col1)) VALUES(453) )
        )
      FOLLOWING
    ) 
  } {1 {error in view q: no such column: col1}}

  2 {
    CREATE VIEW q AS SELECT
    CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(RIGHT
    AS)AS)AS)AS)AS)AS)AS)AS)AS)AS)AS)WINDOW x AS(RANGE BETWEEN UNBOUNDED
    PRECEDING AND INDEXED(*)OVER(PARTITION BY
    CROSS,CROSS,NATURAL,sqlite_master(*)OVER a,(WITH a AS(VALUES(LEFT)UNION
    VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT)UNION
    VALUES(LEFT)UNION VALUES(LEFT))VALUES(LEFT))IN
    STORED,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT)*LEFT FOLLOWING)ORDER BY
    LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT LIMIT
    LEFT,INDEXED(*)OVER(PARTITION BY
    CROSS,CROSS,CROSS,LEFT,INDEXED(*)OVER(PARTITION BY
    CROSS,CROSS,CROSS),INDEXED(*)OVER(PARTITION BY
    LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT),
    LEFT,LEFT,INNER,CROSS,CROSS,CROSS,INNER,NATURAL ORDER BY
    OUTER,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,INNER,
    INNER,INNER NULLS LAST GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED
    FOLLOWING); 
  } {1 {error in view q: no such column: LEFT}}

  3 {
    CREATE VIEW q AS SELECT 99 WINDOW x AS (RANGE BETWEEN UNBOUNDED PRECEDING
    AND count(*)OVER(PARTITION BY (WITH a AS(VALUES(2),(x3))VALUES(0)))
    FOLLOWING)ORDER BY x2,sum(1)OVER(PARTITION BY avg(5)OVER(PARTITION BY x1));
  } {1 {error in view q: no such column: x3}}
} {
  do_execsql_test 19.$tn.1 "
    DROP VIEW IF EXISTS q;
    $v
  " {}

  do_catchsql_test 19.$tn.2 {
    ALTER TABLE a RENAME TO g;
  } $res
}

# Verify that the "if( pParse->nErr ) return WRC_Abort" at the top of the
# renameUnmapSelectCb() routine in alter.c (2019-12-04) is really required.
#
sqlite3 db :memory:
do_catchsql_test 20.10 {
  CREATE TABLE s(a, b, c);
  CREATE INDEX k ON s( (WITH s AS( SELECT * ) VALUES(2) ) IN () );
  ALTER TABLE s RENAME a TO a2;
} {1 {error in index k: no tables specified}}

#------------------------------------------------------------------------
#
reset_db
do_execsql_test 21.1 {
  CREATE TABLE s(col);
  CREATE VIEW v AS SELECT ( 
    WITH x(a) AS(SELECT * FROM s) VALUES(RIGHT) 
  ) IN() ; 
  CREATE TABLE a(a);
  ALTER TABLE a RENAME a TO b;
}

#------------------------------------------------------------------------
#
reset_db
do_execsql_test 22.1 {
  CREATE TABLE t1(a);
  CREATE VIEW v2(b) AS SELECT * FROM v2;
}

do_catchsql_test 22.2 {
  ALTER TABLE t1 RENAME TO t4;
} {1 {error in view v2: view v2 is circularly defined}}

do_execsql_test 22.3 {
  DROP VIEW v2;
  CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) SELECT * FROM t3;
}

do_catchsql_test 22.4 {
  ALTER TABLE t1 RENAME TO t4;
} {1 {error in view v2: view v2 is circularly defined}}

do_execsql_test 22.5 {
  DROP VIEW v2;
  CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) VALUES(1);
}

do_catchsql_test 22.6 {
  ALTER TABLE t1 RENAME TO t4;
} {0 {}}

#------------------------------------------------------------------------
#
reset_db
do_execsql_test 23.1 {
  CREATE TABLE t1(x);
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
    UPDATE t1 SET (c,d)=((SELECT 1 FROM t1 JOIN t2 ON b=x),1);
  END;
}

do_catchsql_test 23.2 {
  ALTER TABLE t1 RENAME TO t1x;
} {1 {error in trigger r1: no such table: main.t2}}

#------------------------------------------------------------------------
#
reset_db
do_execsql_test 23.1 {
  CREATE TABLE v0 (a);
  CREATE VIEW v2 (v3) AS 
    WITH x1 AS (SELECT * FROM v2) 
    SELECT v3 AS x, v3 AS y FROM v2; 
}

do_catchsql_test 23.2 {
  SELECT * FROM v2
} {1 {view v2 is circularly defined}}

db close
sqlite3 db test.db

do_catchsql_test 23.3 {
  ALTER TABLE v0 RENAME TO t3 ;
} {1 {error in view v2: view v2 is circularly defined}}

#------------------------------------------------------------------------
#
reset_db
do_execsql_test 24.1 {
  CREATE TABLE v0 (v1); 
  CREATE TABLE v2 (v3 INTEGER UNIQUE ON CONFLICT ABORT); 
  CREATE TRIGGER x AFTER INSERT ON v2 WHEN ( 
      ( SELECT v1 AS PROMO_REVENUE FROM v2 JOIN v0 USING ( VALUE ) ) AND 0 ) 
  BEGIN 
    DELETE FROM v2; 
  END; 
}
do_catchsql_test 24.2 {
  ALTER TABLE v0 RENAME TO x ;
} {1 {error in trigger x: cannot join using column VALUE - column not present in both tables}}

do_execsql_test 24.3 {
  DROP TRIGGER x;
  CREATE TRIGGER x AFTER INSERT ON v2 WHEN (
    0 AND (SELECT rowid FROM v0)
  ) BEGIN
    DELETE FROM v2;
  END;
}

do_execsql_test 24.4 {
  ALTER TABLE v0 RENAME TO xyz;
  SELECT sql FROM sqlite_master WHERE type='trigger'
} {{CREATE TRIGGER x AFTER INSERT ON v2 WHEN (
    0 AND (SELECT rowid FROM "xyz")
  ) BEGIN
    DELETE FROM v2;
  END}}

#------------------------------------------------------------------------
#
reset_db
do_execsql_test 25.1 {
  CREATE TABLE t1(a, b, c);
  CREATE TABLE t2(a, b, c);
  CREATE TRIGGER ttt AFTER INSERT ON t1 BEGIN
    UPDATE t1 SET a=t2.a FROM t2 WHERE t1.a=t2.a; 
  END;
}
#do_execsql_test 25.2 {
#  ALTER TABLE t2 RENAME COLUMN a TO aaa;
#}

#------------------------------------------------------------------------
#
reset_db
do_execsql_test 26.1 {
  CREATE TABLE t1(x);

  CREATE TABLE t3(y);
  CREATE TABLE t4(z);

  CREATE TRIGGER tr1 INSERT ON t3 BEGIN
    UPDATE t3 SET y=z FROM (SELECT z FROM t4);
  END;

  CREATE TRIGGER tr2 INSERT ON t3 BEGIN
    UPDATE t3 SET y=abc FROM (SELECT x AS abc FROM t1);
  END;
}

do_execsql_test 26.2 {
  ALTER TABLE t1 RENAME TO t2;
}

do_execsql_test 26.3 {
  ALTER TABLE t2 RENAME x TO xx;
}

do_execsql_test 26.4 {
  SELECT sql FROM sqlite_schema WHERE name='tr2'
} {
{CREATE TRIGGER tr2 INSERT ON t3 BEGIN
    UPDATE t3 SET y=abc FROM (SELECT xx AS abc FROM "t2");
  END}
}

# 2020-11-02 OSSFuzz 
#
reset_db
do_execsql_test 26.5 {
  CREATE TABLE t1(xx);
  CREATE TRIGGER xx INSERT ON t1 BEGIN
     UPDATE t1 SET xx=xx FROM(SELECT xx);
  END;
} {}
do_catchsql_test 26.6 {
  ALTER TABLE t1 RENAME TO t2;
} {1 {error in trigger xx: ambiguous column name: xx}}


finish_test

Changes to test/analyze.test.

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
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







-
+

















-
+
+

-
-
-
+
+
+
-
+









-
+

-
-
-
+
+
+
-
+









-
+

-
-
-
+
+
+
-
+







  sqlite3 db test.db
  execsql {
    SELECT * FROM t4 WHERE x=1234;
  }
} {}

# Verify that DROP TABLE and DROP INDEX remove entries from the 
# sqlite_stat1 and sqlite_stat4 tables.
# sqlite_stat1, sqlite_stat3 and sqlite_stat4 tables.
#
do_test analyze-5.0 {
  execsql {
    DELETE FROM t3;
    DELETE FROM t4;
    INSERT INTO t3 VALUES(1,2,3,4);
    INSERT INTO t3 VALUES(5,6,7,8);
    INSERT INTO t3 SELECT a+8, b+8, c+8, d+8 FROM t3;
    INSERT INTO t3 SELECT a+16, b+16, c+16, d+16 FROM t3;
    INSERT INTO t3 SELECT a+32, b+32, c+32, d+32 FROM t3;
    INSERT INTO t3 SELECT a+64, b+64, c+64, d+64 FROM t3;
    INSERT INTO t4 SELECT a, b, c FROM t3;
    ANALYZE;
    SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
    SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
  }
} {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
ifcapable stat4 {
ifcapable stat4||stat3 {
  ifcapable stat4 {set stat sqlite_stat4} else {set stat sqlite_stat3}
  do_test analyze-5.1 {
    execsql {
      SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
      SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
    execsql "
      SELECT DISTINCT idx FROM $stat ORDER BY 1;
      SELECT DISTINCT tbl FROM $stat ORDER BY 1;
    }
    "
  } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
}
do_test analyze-5.2 {
  execsql {
    DROP INDEX t3i2;
    SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
    SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
  }
} {t3i1 t3i3 t4i1 t4i2 t3 t4}
ifcapable stat4 {
ifcapable stat4||stat3 {
  do_test analyze-5.3 {
    execsql {
      SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
      SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
    execsql "
      SELECT DISTINCT idx FROM $stat ORDER BY 1;
      SELECT DISTINCT tbl FROM $stat ORDER BY 1;
    }
    "
  } {t3i1 t3i3 t4i1 t4i2 t3 t4}
}
do_test analyze-5.4 {
  execsql {
    DROP TABLE t3;
    SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
    SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
  }
} {t4i1 t4i2 t4}
ifcapable stat4 {
ifcapable stat4||stat3 {
  do_test analyze-5.5 {
    execsql {
      SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
      SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
    execsql "
      SELECT DISTINCT idx FROM $stat ORDER BY 1;
      SELECT DISTINCT tbl FROM $stat ORDER BY 1;
    }
    "
  } {t4i1 t4i2 t4}
}

# This test corrupts the database file so it must be the last test
# in the series.
#
do_test analyze-5.99 {

Changes to test/analyze3.test.

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
14
15
16
17
18
19
20

21










22
23
24
25
26
27
28







-
+
-
-
-
-
-
-
-
-
-
-







# instead of literal constant arguments.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix analyze3

ifcapable !stat4 {
ifcapable !stat4&&!stat3 {
  finish_test
  return
}

# This test cannot be run with the sqlite3_prepare() permutation, as it
# tests that stat4 data can be used to influence the plans of queries
# based on bound variable values. And this is not possible when using
# sqlite3_prepare() - as queries cannot be internally re-prepared after
# binding values are available.
if {[permutation]=="prepare"} {
  finish_test
  return
}

#----------------------------------------------------------------------
# Test Organization:
#
106
107
108
109
110
111
112

113




114
115
116
117
118
119
120
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114







+
-
+
+
+
+







    execsql { INSERT INTO t1 VALUES($i+100, $i) }
  }
  execsql {
    COMMIT;
    ANALYZE;
  }

  ifcapable stat4 {
  execsql { SELECT count(*)>0 FROM sqlite_stat4; }
    execsql { SELECT count(*)>0 FROM sqlite_stat4; }
  } else {
    execsql { SELECT count(*)>0 FROM sqlite_stat3; }
  }
} {1}

do_execsql_test analyze3-1.1.x {
  SELECT count(*) FROM t1 WHERE x>200 AND x<300;
  SELECT count(*) FROM t1 WHERE x>0 AND x<1100;
} {99 1000}

Changes to test/analyze5.test.

13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27







-
+







# in this file is the use of the sqlite_stat4 histogram data on tables
# with many repeated values and only a few distinct values.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !stat4 {
ifcapable !stat4&&!stat3 {
  finish_test
  return
}

set testprefix analyze5

proc eqp {sql {db db}} {
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
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







+
-
-
-
+
+
+
+
+
+
+
+




+
-
-
-
-
+
+
+
+
+
+
+
+
+

+
-
-
-
+
+
+
+
+
+
+
+







    CREATE INDEX t1v ON t1(v);  -- mixed case text
    CREATE INDEX t1w ON t1(w);  -- integers 0, 1, 2 and a few NULLs
    CREATE INDEX t1x ON t1(x);  -- integers 1, 2, 3 and many NULLs
    CREATE INDEX t1y ON t1(y);  -- integers 0 and very few 1s
    CREATE INDEX t1z ON t1(z);  -- integers 0, 1, 2, and 3
    ANALYZE;
  }
  ifcapable stat4 {
  db eval {
    SELECT DISTINCT lindex(test_decode(sample),0) 
      FROM sqlite_stat4 WHERE idx='t1u' ORDER BY nlt;
    db eval {
      SELECT DISTINCT lindex(test_decode(sample),0) 
        FROM sqlite_stat4 WHERE idx='t1u' ORDER BY nlt;
    }
  } else {
    db eval {
      SELECT sample FROM sqlite_stat3 WHERE idx='t1u' ORDER BY nlt;
    }
  }
} {alpha bravo charlie delta}

do_test analyze5-1.1 {
  ifcapable stat4 {
  db eval {
    SELECT DISTINCT lower(lindex(test_decode(sample), 0)) 
      FROM sqlite_stat4 WHERE idx='t1v' ORDER BY 1
  }
    db eval {
      SELECT DISTINCT lower(lindex(test_decode(sample), 0)) 
        FROM sqlite_stat4 WHERE idx='t1v' ORDER BY 1
    }
  } else {
    db eval {
      SELECT lower(sample) FROM sqlite_stat3 WHERE idx='t1v' ORDER BY 1
    }
  }
} {alpha bravo charlie delta}
ifcapable stat4 {
do_test analyze5-1.2 {
  db eval {SELECT idx, count(*) FROM sqlite_stat4 GROUP BY 1 ORDER BY 1}
} {t1t 8 t1u 8 t1v 8 t1w 8 t1x 8 t1y 9 t1z 8}
  do_test analyze5-1.2 {
    db eval {SELECT idx, count(*) FROM sqlite_stat4 GROUP BY 1 ORDER BY 1}
  } {t1t 8 t1u 8 t1v 8 t1w 8 t1x 8 t1y 9 t1z 8}
} else {
  do_test analyze5-1.2 {
    db eval {SELECT idx, count(*) FROM sqlite_stat3 GROUP BY 1 ORDER BY 1}
  } {t1t 4 t1u 4 t1v 4 t1w 4 t1x 4 t1y 2 t1z 4}
}

# Verify that range queries generate the correct row count estimates
#
foreach {testid where index rows} {
    1  {z>=0 AND z<=0}       t1z  400
    2  {z>=1 AND z<=1}       t1z  300
    3  {z>=2 AND z<=2}       t1z  175

Changes to test/analyze6.test.

13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27







-
+







# in this file a corner-case query planner optimization involving the
# join order of two tables of different sizes.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !stat4 {
ifcapable !stat4&&!stat3 {
  finish_test
  return
}

set testprefix analyze6

proc eqp {sql {db db}} {

Changes to test/analyze7.test.

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
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







-
+
















-
+












} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
do_test analyze7-3.1 {
  execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;}
} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
do_test analyze7-3.2.1 {
  execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;}
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
ifcapable stat4 {
ifcapable stat4||stat3 {
  # If ENABLE_STAT4 is defined, SQLite comes up with a different estimated
  # row count for (c=2) than it does for (c=?).
  do_test analyze7-3.2.2 {
    execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
  } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
} else {
  # If ENABLE_STAT4 is not defined, the expected row count for (c=2) is the
  # same as that for (c=?).
  do_test analyze7-3.2.3 {
    execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
  } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
}
do_test analyze7-3.3 {
  execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123}
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}

ifcapable {!stat4} {
ifcapable {!stat4 && !stat3} {
  do_test analyze7-3.4 {
    execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123}
  } {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
  do_test analyze7-3.5 {
    execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123}
  } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
}
do_test analyze7-3.6 {
  execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND d=123 AND b=123}
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)*/}

finish_test

Changes to test/analyze8.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
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












-
+





-
+







# 2011 August 13
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements tests for SQLite library.  The focus of the tests
# in this file is testing the capabilities of sqlite_stat4.
# in this file is testing the capabilities of sqlite_stat3.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !stat4 {
ifcapable !stat4&&!stat3 {
  finish_test
  return
}

set testprefix analyze8

proc eqp {sql {db db}} {

Added test/analyzeA.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2013 August 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 automated tests used to verify that the current build
# (which must be either ENABLE_STAT3 or ENABLE_STAT4) works with both stat3
# and stat4 data.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix analyzeA

ifcapable !stat4&&!stat3 {
  finish_test
  return
}

# Populate the stat3 table according to the current contents of the db
#
proc populate_stat3 {{bDropTable 1}} {
  # Open a second connection on database "test.db" and run ANALYZE. If this
  # is an ENABLE_STAT3 build, this is all that is required to create and
  # populate the sqlite_stat3 table. 
  # 
  sqlite3 db2 test.db
  execsql { ANALYZE }

  # Now, if this is an ENABLE_STAT4 build, create and populate the 
  # sqlite_stat3 table based on the stat4 data gathered by the ANALYZE
  # above. Then drop the sqlite_stat4 table.
  #
  ifcapable stat4 {
    db2 func lindex lindex
    execsql {
      PRAGMA writable_schema = on;
      CREATE TABLE sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample);
      INSERT INTO sqlite_stat3 
      SELECT DISTINCT tbl, idx, 
        lindex(neq,0), lindex(nlt,0), lindex(ndlt,0), test_extract(sample, 0)
      FROM sqlite_stat4;
    } db2
    if {$bDropTable} { execsql {DROP TABLE sqlite_stat4} db2 }
    execsql { PRAGMA writable_schema = off }
  }

  # Modify the database schema cookie to ensure that the other connection
  # reloads the schema.
  #
  execsql {
    CREATE TABLE obscure_tbl_nm(x);
    DROP TABLE obscure_tbl_nm;
  } db2
  db2 close
}

# Populate the stat4 table according to the current contents of the db
#
proc populate_stat4 {{bDropTable 1}} {
  sqlite3 db2 test.db
  execsql { ANALYZE }

  ifcapable stat3 {
    execsql {
      PRAGMA writable_schema = on;
      CREATE TABLE sqlite_stat4(tbl,idx,neq,nlt,ndlt,sample);
      INSERT INTO sqlite_stat4 
      SELECT tbl, idx, neq, nlt, ndlt, sqlite_record(sample) 
      FROM sqlite_stat3;
    } db2
    if {$bDropTable} { execsql {DROP TABLE sqlite_stat3} db2 }
    execsql { PRAGMA writable_schema = off }
  }
 
  # Modify the database schema cookie to ensure that the other connection
  # reloads the schema.
  #
  execsql {
    CREATE TABLE obscure_tbl_nm(x);
    DROP TABLE obscure_tbl_nm;
  } db2
  db2 close
}

# Populate the stat4 table according to the current contents of the db.
# Leave deceptive data in the stat3 table. This data should be ignored
# in favour of that from the stat4 table.
#
proc populate_both {} {
  ifcapable stat4 { populate_stat3 0 }
  ifcapable stat3 { populate_stat4 0 }

  sqlite3 db2 test.db
  execsql {
    PRAGMA writable_schema = on;
    UPDATE sqlite_stat3 SET idx = 
      CASE idx WHEN 't1b' THEN 't1c' ELSE 't1b'
    END;
    PRAGMA writable_schema = off;
    CREATE TABLE obscure_tbl_nm(x);
    DROP TABLE obscure_tbl_nm;
  } db2
  db2 close
}

foreach {tn analyze_cmd} {
  1 populate_stat4 
  2 populate_stat3
  3 populate_both
} {
  reset_db
  do_test 1.$tn.1 {
    execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT) }
    for {set i 0} {$i < 100} {incr i} {
      set c [expr int(pow(1.1,$i)/100)]
      set b [expr 125 - int(pow(1.1,99-$i))/100]
      execsql {INSERT INTO t1 VALUES($i, $b, $c)}
    }
  } {}

  execsql { CREATE INDEX t1b ON t1(b) }
  execsql { CREATE INDEX t1c ON t1(c) }
  $analyze_cmd

  do_execsql_test 1.$tn.2.1 { SELECT count(*) FROM t1 WHERE b=31 } 1
  do_execsql_test 1.$tn.2.2 { SELECT count(*) FROM t1 WHERE c=0  } 49
  do_execsql_test 1.$tn.2.3 { SELECT count(*) FROM t1 WHERE b=125  } 49
  do_execsql_test 1.$tn.2.4 { SELECT count(*) FROM t1 WHERE c=16  } 1

  do_eqp_test 1.$tn.2.5 {
    SELECT * FROM t1 WHERE b = 31 AND c = 0;
  } {SEARCH TABLE t1 USING INDEX t1b (b=?)}
  do_eqp_test 1.$tn.2.6 {
    SELECT * FROM t1 WHERE b = 125 AND c = 16;
  } {SEARCH TABLE t1 USING INDEX t1c (c=?)}

  do_execsql_test 1.$tn.3.1 { 
    SELECT count(*) FROM t1 WHERE b BETWEEN 0 AND 50
  } {6}
  do_execsql_test 1.$tn.3.2 { 
    SELECT count(*) FROM t1 WHERE c BETWEEN 0 AND 50
  } {90}
  do_execsql_test 1.$tn.3.3 { 
    SELECT count(*) FROM t1 WHERE b BETWEEN 75 AND 125
  } {90}
  do_execsql_test 1.$tn.3.4 { 
    SELECT count(*) FROM t1 WHERE c BETWEEN 75 AND 125
  } {6}

  do_eqp_test 1.$tn.3.5 {
    SELECT * FROM t1 WHERE b BETWEEN 0 AND 50 AND c BETWEEN 0 AND 50
  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}

  do_eqp_test 1.$tn.3.6 {
    SELECT * FROM t1 WHERE b BETWEEN 75 AND 125 AND c BETWEEN 75 AND 125
  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}

  do_eqp_test 1.$tn.3.7 {
    SELECT * FROM t1 WHERE b BETWEEN +0 AND +50 AND c BETWEEN +0 AND +50
  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}

  do_eqp_test 1.$tn.3.8 {
    SELECT * FROM t1
     WHERE b BETWEEN cast('0' AS int) AND cast('50.0' AS real)
       AND c BETWEEN cast('0' AS numeric) AND cast('50.0' AS real)
  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}

  do_eqp_test 1.$tn.3.9 {
    SELECT * FROM t1 WHERE b BETWEEN +75 AND +125 AND c BETWEEN +75 AND +125
  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}

  do_eqp_test 1.$tn.3.10 {
    SELECT * FROM t1
     WHERE b BETWEEN cast('75' AS int) AND cast('125.0' AS real)
       AND c BETWEEN cast('75' AS numeric) AND cast('125.0' AS real)
  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
}

finish_test

Added test/analyzeB.test.











































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2013 August 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 automated tests used to verify that the sqlite_stat3
# functionality is working. The tests in this file are based on a subset
# of the sqlite_stat4 tests in analyze9.test.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix analyzeB

ifcapable !stat3 {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a TEXT, b TEXT); 
  INSERT INTO t1 VALUES('(0)', '(0)');
  INSERT INTO t1 VALUES('(1)', '(1)');
  INSERT INTO t1 VALUES('(2)', '(2)');
  INSERT INTO t1 VALUES('(3)', '(3)');
  INSERT INTO t1 VALUES('(4)', '(4)');
  CREATE INDEX i1 ON t1(a, b);
} {}


do_execsql_test 1.1 {
  ANALYZE;
} {}

do_execsql_test 1.2 {
  SELECT tbl,idx,nEq,nLt,nDLt,quote(sample) FROM sqlite_stat3;
} {
  t1 i1 1 0 0 '(0)'
  t1 i1 1 1 1 '(1)'
  t1 i1 1 2 2 '(2)'
  t1 i1 1 3 3 '(3)'
  t1 i1 1 4 4 '(4)'
}

if {[permutation] != "utf16"} {
  do_execsql_test 1.3 {
    SELECT tbl,idx,nEq,nLt,nDLt,quote(sample) FROM sqlite_stat3;
  } {
    t1 i1 1 0 0 '(0)'
    t1 i1 1 1 1 '(1)'
    t1 i1 1 2 2 '(2)'
    t1 i1 1 3 3 '(3)'
    t1 i1 1 4 4 '(4)'
  }
}


#-------------------------------------------------------------------------
# This is really just to test SQL user function "test_decode".
#
reset_db
do_execsql_test 2.1 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1(a) VALUES('some text');
  INSERT INTO t1(a) VALUES(14);
  INSERT INTO t1(a) VALUES(NULL);
  INSERT INTO t1(a) VALUES(22.0);
  INSERT INTO t1(a) VALUES(x'656667');
  CREATE INDEX i1 ON t1(a, b, c);
  ANALYZE;
  SELECT quote(sample) FROM sqlite_stat3;
} {
  NULL 14 22.0 {'some text'} X'656667' 
}

#-------------------------------------------------------------------------
# 
reset_db
do_execsql_test 3.1 {
  CREATE TABLE t2(a, b);
  CREATE INDEX i2 ON t2(a, b);
  BEGIN;
}

do_test 3.2 {
  for {set i 0} {$i < 1000} {incr i} {
    set a [expr $i / 10]
    set b [expr int(rand() * 15.0)]
    execsql { INSERT INTO t2 VALUES($a, $b) }
  }
  execsql COMMIT
} {}

db func lindex lindex

# Each value of "a" occurs exactly 10 times in the table.
#
do_execsql_test 3.3.1 {
  SELECT count(*) FROM t2 GROUP BY a;
} [lrange [string repeat "10 " 100] 0 99]

# The first element in the "nEq" list of all samples should therefore be 10.
#
do_execsql_test 3.3.2 {
  ANALYZE;
  SELECT nEq FROM sqlite_stat3;
} [lrange [string repeat "10 " 100] 0 23]

#-------------------------------------------------------------------------
# 
do_execsql_test 3.4 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  INSERT INTO t1 VALUES(1, 1, 'one-a');
  INSERT INTO t1 VALUES(11, 1, 'one-b');
  INSERT INTO t1 VALUES(21, 1, 'one-c');
  INSERT INTO t1 VALUES(31, 1, 'one-d');
  INSERT INTO t1 VALUES(41, 1, 'one-e');
  INSERT INTO t1 VALUES(51, 1, 'one-f');
  INSERT INTO t1 VALUES(61, 1, 'one-g');
  INSERT INTO t1 VALUES(71, 1, 'one-h');
  INSERT INTO t1 VALUES(81, 1, 'one-i');
  INSERT INTO t1 VALUES(91, 1, 'one-j');
  INSERT INTO t1 SELECT a+1,2,'two' || substr(c,4) FROM t1;
  INSERT INTO t1 SELECT a+2,3,'three'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
  INSERT INTO t1 SELECT a+3,4,'four'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
  INSERT INTO t1 SELECT a+4,5,'five'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
  INSERT INTO t1 SELECT a+5,6,'six'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';	
  CREATE INDEX t1b ON t1(b);
  ANALYZE;
  SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND 60;
} {three-d three-e three-f}


#-------------------------------------------------------------------------
# These tests verify that the sample selection for stat3 appears to be 
# working as designed.
#

reset_db
db func lindex lindex
db func lrange lrange

do_execsql_test 4.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a, b, c);
  CREATE INDEX i1 ON t1(c, b, a);
}


proc insert_filler_rows_n {iStart args} {
  set A(-ncopy) 1
  set A(-nval) 1

  foreach {k v} $args {
    if {[info exists A($k)]==0} { error "no such option: $k" }
    set A($k) $v
  }
  if {[llength $args] % 2} {
    error "option requires an argument: [lindex $args end]"
  }

  for {set i 0} {$i < $A(-nval)} {incr i} {
    set iVal [expr $iStart+$i]
    for {set j 0} {$j < $A(-ncopy)} {incr j} {
      execsql { INSERT INTO t1 VALUES($iVal, $iVal, $iVal) }
    }
  }
}

do_test 4.1 {
  execsql { BEGIN }
  insert_filler_rows_n  0  -ncopy 10 -nval 19
  insert_filler_rows_n 20  -ncopy  1 -nval 100

  execsql {
    INSERT INTO t1(c, b, a) VALUES(200, 1, 'a');
    INSERT INTO t1(c, b, a) VALUES(200, 1, 'b');
    INSERT INTO t1(c, b, a) VALUES(200, 1, 'c');

    INSERT INTO t1(c, b, a) VALUES(200, 2, 'e');
    INSERT INTO t1(c, b, a) VALUES(200, 2, 'f');

    INSERT INTO t1(c, b, a) VALUES(201, 3, 'g');
    INSERT INTO t1(c, b, a) VALUES(201, 4, 'h');

    ANALYZE;
    SELECT count(*) FROM sqlite_stat3;
    SELECT count(*) FROM t1;
  }
} {24 297}

do_execsql_test 4.2 {
  SELECT neq, nlt, ndlt, sample FROM sqlite_stat3 ORDER BY rowid LIMIT 16;
} {
  10 0 0 0
  10 10 1 1
  10 20 2 2
  10 30 3 3
  10 40 4 4
  10 50 5 5
  10 60 6 6
  10 70 7 7
  10 80 8 8
  10 90 9 9
  10 100 10 10
  10 110 11 11
  10 120 12 12
  10 130 13 13
  10 140 14 14
  10 150 15 15
}

do_execsql_test 4.3 {
  SELECT neq, nlt, ndlt, sample FROM sqlite_stat3
  ORDER BY rowid DESC LIMIT 2;
} {
  2 295 120 201
  5 290 119 200
}

do_execsql_test 4.4 { SELECT count(DISTINCT c) FROM t1 WHERE c<201 } 120
do_execsql_test 4.5 { SELECT count(DISTINCT c) FROM t1 WHERE c<200 } 119

reset_db
do_test 4.7 {
  execsql { 
    BEGIN;
    CREATE TABLE t1(o,t INTEGER PRIMARY KEY);
    CREATE INDEX i1 ON t1(o);
  }
  for {set i 0} {$i<10000} {incr i [expr (($i<1000)?1:10)]} {
    execsql { INSERT INTO t1 VALUES('x', $i) }
  }
  execsql {
    COMMIT;
    ANALYZE;
    SELECT count(*) FROM sqlite_stat3;
  }
} {1}
do_execsql_test 4.8 {
  SELECT sample FROM sqlite_stat3;
} {x}


#-------------------------------------------------------------------------
# The following would cause a crash at one point.
#
reset_db
do_execsql_test 5.1 {
  PRAGMA encoding = 'utf-16';
  CREATE TABLE t0(v);
  ANALYZE;
}

#-------------------------------------------------------------------------
# This was also crashing (corrupt sqlite_stat3 table).
#
reset_db
do_execsql_test 6.1 {
  CREATE TABLE t1(a, b);
  CREATE INDEX i1 ON t1(a);
  CREATE INDEX i2 ON t1(b);
  INSERT INTO t1 VALUES(1, 1);
  INSERT INTO t1 VALUES(2, 2);
  INSERT INTO t1 VALUES(3, 3);
  INSERT INTO t1 VALUES(4, 4);
  INSERT INTO t1 VALUES(5, 5);
  ANALYZE;
  PRAGMA writable_schema = 1;
  CREATE TEMP TABLE x1 AS
    SELECT tbl,idx,neq,nlt,ndlt,sample FROM sqlite_stat3
    ORDER BY (rowid%5), rowid;
  DELETE FROM sqlite_stat3;
  INSERT INTO sqlite_stat3 SELECT * FROM x1;
  PRAGMA writable_schema = 0;
  ANALYZE sqlite_master;
}
do_execsql_test 6.2 {
  SELECT * FROM t1 WHERE a = 'abc';
}

#-------------------------------------------------------------------------
# The following tests experiment with adding corrupted records to the
# 'sample' column of the sqlite_stat3 table.
#
reset_db
sqlite3_db_config_lookaside db 0 0 0

do_execsql_test 7.1 {
  CREATE TABLE t1(a, b);
  CREATE INDEX i1 ON t1(a, b);
  INSERT INTO t1 VALUES(1, 1);
  INSERT INTO t1 VALUES(2, 2);
  INSERT INTO t1 VALUES(3, 3);
  INSERT INTO t1 VALUES(4, 4);
  INSERT INTO t1 VALUES(5, 5);
  ANALYZE;
  UPDATE sqlite_stat3 SET sample = X'' WHERE rowid = 1;
  ANALYZE sqlite_master;
}

do_execsql_test 7.2 {
  UPDATE sqlite_stat3 SET sample = X'FFFF';
  ANALYZE sqlite_master;
  SELECT * FROM t1 WHERE a = 1;
} {1 1}

do_execsql_test 7.3 {
  ANALYZE;
  UPDATE sqlite_stat3 SET neq = '0 0 0';
  ANALYZE sqlite_master;
  SELECT * FROM t1 WHERE a = 1;
} {1 1}

do_execsql_test 7.4 {
  ANALYZE;
  UPDATE sqlite_stat3 SET ndlt = '0 0 0';
  ANALYZE sqlite_master;
  SELECT * FROM t1 WHERE a = 3;
} {3 3}

do_execsql_test 7.5 {
  ANALYZE;
  UPDATE sqlite_stat3 SET nlt = '0 0 0';
  ANALYZE sqlite_master;
  SELECT * FROM t1 WHERE a = 5;
} {5 5}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 8.1 {
  CREATE TABLE t1(x TEXT);
  CREATE INDEX i1 ON t1(x);
  INSERT INTO t1 VALUES('1');
  INSERT INTO t1 VALUES('2');
  INSERT INTO t1 VALUES('3');
  INSERT INTO t1 VALUES('4');
  ANALYZE;
}
do_execsql_test 8.2 {
  SELECT * FROM t1 WHERE x = 3;
} {3}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 9.1 {
  CREATE TABLE t1(a, b, c, d, e);
  CREATE INDEX i1 ON t1(a, b, c, d);
  CREATE INDEX i2 ON t1(e);
}
do_test 9.2 {
  execsql BEGIN;
  for {set i 0} {$i < 100} {incr i} {
    execsql "INSERT INTO t1 VALUES('x', 'y', 'z', $i, [expr $i/2])"
  }
  for {set i 0} {$i < 20} {incr i} {
    execsql "INSERT INTO t1 VALUES('x', 'y', 'z', 101, $i)"
  }
  for {set i 102} {$i < 200} {incr i} {
    execsql "INSERT INTO t1 VALUES('x', 'y', 'z', $i, [expr $i/2])"
  }
  execsql COMMIT
  execsql ANALYZE
} {}

do_eqp_test 9.3.1 {
  SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=101 AND e=5;
} {/t1 USING INDEX i1/}
do_eqp_test 9.3.2 {
  SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=99 AND e=5;
} {/t1 USING INDEX i1/}

set value_d [expr 101]
do_eqp_test 9.4.1 {
  SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=$value_d AND e=5
} {/t1 USING INDEX i1/}
set value_d [expr 99]
do_eqp_test 9.4.2 {
  SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=$value_d AND e=5
} {/t1 USING INDEX i1/}

#-------------------------------------------------------------------------
# Check that the planner takes stat3 data into account when considering
# "IS NULL" and "IS NOT NULL" constraints.
#
do_execsql_test 10.1.1 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a, b);
  CREATE INDEX t3a ON t3(a);
  CREATE INDEX t3b ON t3(b);
}
do_test 10.1.2 {
  for {set i 1} {$i < 100} {incr i} {
    if {$i>90} { set a $i } else { set a NULL }
    set b [expr $i % 5]
    execsql "INSERT INTO t3 VALUES($a, $b)"
  }
  execsql ANALYZE
} {}
do_eqp_test 10.1.3 {
  SELECT * FROM t3 WHERE a IS NULL AND b = 2
} {/t3 USING INDEX t3b/}
do_eqp_test 10.1.4 {
  SELECT * FROM t3 WHERE a IS NOT NULL AND b = 2
} {/t3 USING INDEX t3a/}

#-------------------------------------------------------------------------
# Check that stat3 data is used correctly with non-default collation
# sequences.
#
foreach {tn schema} {
  1 {
    CREATE TABLE t4(a COLLATE nocase, b);
    CREATE INDEX t4a ON t4(a);
    CREATE INDEX t4b ON t4(b);
  }
  2 {
    CREATE TABLE t4(a, b);
    CREATE INDEX t4a ON t4(a COLLATE nocase);
    CREATE INDEX t4b ON t4(b);
  }
} {
  drop_all_tables
  do_test 11.$tn.1 { execsql $schema } {}

  do_test 11.$tn.2 {
    for {set i 0} {$i < 100} {incr i} {
      if { ($i % 10)==0 } { set a ABC } else { set a DEF }
      set b [expr $i % 5]
        execsql { INSERT INTO t4 VALUES($a, $b) }
    }
    execsql ANALYZE
  } {}

  do_eqp_test 11.$tn.3 {
    SELECT * FROM t4 WHERE a = 'def' AND b = 3;
  } {/t4 USING INDEX t4b/}

  if {$tn==1} {
    set sql "SELECT * FROM t4 WHERE a = 'abc' AND b = 3;"
    do_eqp_test 11.$tn.4 $sql {/t4 USING INDEX t4a/}
  } else {

    set sql "SELECT * FROM t4 WHERE a = 'abc' COLLATE nocase AND b = 3;"
    do_eqp_test 11.$tn.5 $sql {/t4 USING INDEX t4a/}

    set sql "SELECT * FROM t4 WHERE a COLLATE nocase = 'abc' AND b = 3;"
    do_eqp_test 11.$tn.6 $sql {/t4 USING INDEX t4a/}
  }
}

#-------------------------------------------------------------------------
# Test that nothing untoward happens if the stat3 table contains entries
# for indexes that do not exist. Or NULL values in the idx column.
# Or NULL values in any of the other columns.
#
drop_all_tables
do_execsql_test 15.1 {
  CREATE TABLE x1(a, b, UNIQUE(a, b));
  INSERT INTO x1 VALUES(1, 2);
  INSERT INTO x1 VALUES(3, 4);
  INSERT INTO x1 VALUES(5, 6);
  ANALYZE;
  INSERT INTO sqlite_stat3 VALUES(NULL, NULL, NULL, NULL, NULL, NULL);
}
db close
sqlite3 db test.db
do_execsql_test 15.2 { SELECT * FROM x1 } {1 2 3 4 5 6}

do_execsql_test 15.3 {
  INSERT INTO sqlite_stat3 VALUES(42, 42, 42, 42, 42, 42);
}
db close
sqlite3 db test.db
do_execsql_test 15.4 { SELECT * FROM x1 } {1 2 3 4 5 6}

do_execsql_test 15.5 {
  UPDATE sqlite_stat1 SET stat = NULL;
}
db close
sqlite3 db test.db
do_execsql_test 15.6 { SELECT * FROM x1 } {1 2 3 4 5 6}

do_execsql_test 15.7 {
  ANALYZE;
  UPDATE sqlite_stat1 SET tbl = 'no such tbl';
}
db close
sqlite3 db test.db
do_execsql_test 15.8 { SELECT * FROM x1 } {1 2 3 4 5 6}

do_execsql_test 15.9 {
  ANALYZE;
  UPDATE sqlite_stat3 SET neq = NULL, nlt=NULL, ndlt=NULL;
}
db close
sqlite3 db test.db
do_execsql_test 15.10 { SELECT * FROM x1 } {1 2 3 4 5 6}

# This is just for coverage....
do_execsql_test 15.11 {
  ANALYZE;
  UPDATE sqlite_stat1 SET stat = stat || ' unordered';
}
db close
sqlite3 db test.db
do_execsql_test 15.12 { SELECT * FROM x1 } {1 2 3 4 5 6}

#-------------------------------------------------------------------------
# Test that allocations used for sqlite_stat3 samples are included in
# the quantity returned by SQLITE_DBSTATUS_SCHEMA_USED.
#
set one [string repeat x 1000]
set two [string repeat x 2000]
do_test 16.1 {
  reset_db
  execsql {
    CREATE TABLE t1(a, UNIQUE(a));
    INSERT INTO t1 VALUES($one);
    ANALYZE;
  }
  set nByte [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]

  reset_db
  execsql {
    CREATE TABLE t1(a, UNIQUE(a));
    INSERT INTO t1 VALUES($two);
    ANALYZE;
  }
  set nByte2 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]

  expr {$nByte2 > $nByte+950 && $nByte2 < $nByte+1050}
} {1}

#-------------------------------------------------------------------------
# Test that stat3 data may be used with partial indexes.
#
do_test 17.1 {
  reset_db
  execsql {
    CREATE TABLE t1(a, b, c, d);
    CREATE INDEX i1 ON t1(a, b) WHERE d IS NOT NULL;
    INSERT INTO t1 VALUES(-1, -1, -1, NULL);
    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
  }

  for {set i 0} {$i < 32} {incr i} {
    execsql { INSERT INTO t1 VALUES($i%2, $b, $i/2, 'abc') }
  }
  execsql {ANALYZE main.t1}
} {}

do_catchsql_test 17.1.2 {
  ANALYZE temp.t1;
} {1 {no such table: temp.t1}}

do_eqp_test 17.2 {
  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
} {/USING INDEX i1/}
do_eqp_test 17.3 {
  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
} {/USING INDEX i1/}

do_execsql_test 17.4 {
  CREATE INDEX i2 ON t1(c) WHERE d IS NOT NULL;
  ANALYZE main.i2;
}
do_eqp_test 17.5 {
  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
} {/USING INDEX i1/}
do_eqp_test 17.6 {
  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0 AND b=0 AND c=10;
} {/USING INDEX i2/}

#-------------------------------------------------------------------------
#
do_test 18.1 {
  reset_db
  execsql {
    CREATE TABLE t1(a, b);
    CREATE INDEX i1 ON t1(a, b);
  }
  for {set i 0} {$i < 9} {incr i} {
    execsql {
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
      INSERT INTO t1 VALUES($i, 0);
    }
  }
  execsql ANALYZE
  execsql { SELECT count(*) FROM sqlite_stat3 }
} {9}

#-------------------------------------------------------------------------
# For coverage.
#
ifcapable view {
  do_test 19.1 {
    reset_db 
    execsql {
      CREATE TABLE t1(x, y);
      CREATE INDEX i1 ON t1(x, y);
      CREATE VIEW v1 AS SELECT * FROM t1;
      ANALYZE;
    }
  } {}
}
ifcapable auth {
  proc authproc {op args} {
    if {$op == "SQLITE_ANALYZE"} { return "SQLITE_DENY" }
    return "SQLITE_OK"
  }
  do_test 19.2 {
    reset_db 
    db auth authproc
    execsql {
      CREATE TABLE t1(x, y);
      CREATE VIEW v1 AS SELECT * FROM t1;
    }
    catchsql ANALYZE
  } {1 {not authorized}}
}

#-------------------------------------------------------------------------
#
reset_db
proc r {args} { expr rand() }
db func r r
db func lrange lrange
do_test 20.1 {
  execsql {
    CREATE TABLE t1(a,b,c,d);
    CREATE INDEX i1 ON t1(a,b,c,d);
  }
  for {set i 0} {$i < 16} {incr i} {
    execsql {
      INSERT INTO t1 VALUES($i, r(), r(), r());
      INSERT INTO t1 VALUES($i, $i,  r(), r());
      INSERT INTO t1 VALUES($i, $i,  $i,  r());
      INSERT INTO t1 VALUES($i, $i,  $i,  $i);
      INSERT INTO t1 VALUES($i, $i,  $i,  $i);
      INSERT INTO t1 VALUES($i, $i,  $i,  r());
      INSERT INTO t1 VALUES($i, $i,  r(), r());
      INSERT INTO t1 VALUES($i, r(), r(), r());
    }
  }
} {}
do_execsql_test 20.2 { ANALYZE }
for {set i 0} {$i<16} {incr i} {
    set val $i
    do_execsql_test 20.3.$i {
      SELECT count(*) FROM sqlite_stat3 WHERE sample=$val
    } {1}
}

finish_test

Changes to test/analyzeC.test.

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
127
128
129
130
131
132
133














134
135
136
137
138
139
140







-
-
-
-
-
-
-
-
-
-
-
-
-
-







  ANALYZE sqlite_master;
  SELECT count(a) FROM t1;
} {6}
do_execsql_test 4.3 {
  EXPLAIN QUERY PLAN
  SELECT count(a) FROM t1;
} {/.*INDEX t1ca.*/}

# 2019-08-15.
# Ticket https://www.sqlite.org/src/tktview/e4598ecbdd18bd82945f602901
# The sz=N parameter in the sqlite_stat1 table needs to have a value of
# 2 or more to avoid a division by zero in the query planner.
#
do_execsql_test 4.4 {
  DROP TABLE IF EXISTS t44;
  CREATE TABLE t44(a PRIMARY KEY);
  INSERT INTO sqlite_stat1 VALUES('t44',null,'sz=0');
  ANALYZE sqlite_master;
  SELECT 0 FROM t44 WHERE a IN(1,2,3);
} {}



# The sz=NNN parameter works even if there is other extraneous text
# in the sqlite_stat1.stat column.
#
do_execsql_test 5.0 {
  DELETE FROM sqlite_stat1;

Deleted test/analyzeG.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
























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020-02-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.
#
#***********************************************************************
# Tests for functionality related to ANALYZE.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !stat4 {
  finish_test
  return
}
set testprefix analyzeG

proc do_scan_order_test {tn sql expect} {
  uplevel [list do_test $tn [subst -nocommands {
    set res ""
    db eval "explain query plan $sql" {
      lappend res [set detail]
    }
    set res
  }] [list {*}$expect]]
}

#-------------------------------------------------------------------------
# Test cases 1.* seek to verify that even if an index is not used, its
# stat4 data may be used by the planner to estimate the number of
# rows that match an unindexed constraint on the same column.
#
do_execsql_test 1.0 {
  PRAGMA automatic_index = 0;
  CREATE TABLE t1(a, x);
  CREATE TABLE t2(b, y);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
  )
  INSERT INTO t1 SELECT (i%50), NULL FROM s;
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
  )
  INSERT INTO t2 SELECT (CASE WHEN i<95 THEN 44 ELSE i END), NULL FROM s;
}

# Join tables t1 and t2. Both contain 100 rows. (a=44) matches 2 rows
# in "t1", (b=44) matches 95 rows in table "t2". But the planner doesn't
# know this, so it has no preference as to which order the tables are
# scanned in. In practice this means that tables are scanned in the order
# they are specified in in the FROM clause.
do_scan_order_test 1.1.1 {
  SELECT * FROM t1, t2 WHERE a=44 AND b=44;
} {
  {SCAN TABLE t1} {SCAN TABLE t2}
}
do_scan_order_test 1.1.2 {
  SELECT * FROM t2, t1 WHERE a=44 AND b=44 
} {
  {SCAN TABLE t2} {SCAN TABLE t1} 
}

do_execsql_test 1.2 {
  CREATE INDEX t2b ON t2(b);
  ANALYZE;
}

# Now, with the ANALYZE data, the planner knows that (b=44) matches a 
# large number of rows. So it elects to scan table "t1" first, regardless
# of the order in which the tables are specified in the FROM clause.
do_scan_order_test 1.3.1 {
  SELECT * FROM t1, t2 WHERE a=44 AND b=44;
} {
  {SCAN TABLE t1} {SCAN TABLE t2}
}
do_scan_order_test 1.3.2 {
  SELECT * FROM t2, t1 WHERE a=44 AND b=44 
} {
  {SCAN TABLE t1} {SCAN TABLE t2} 
}


finish_test

Changes to test/atof1.test.

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
52
53
54
55
56
57
58
























59
60







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


      db eval {SELECT CAST(quote($x) AS real) c} {}
      puts "OUT:   $b [format %.32e $c]"
    }
    set y
  } {1}
}

# 2020-01-08 ticket 9eda2697f5cc1aba
# When running sqlite3AtoF() on a blob with an odd number of bytes using
# UTF16, ignore the last byte so that the string has an integer number of
# UTF16 code points.
#
reset_db
do_execsql_test atof1-2.10 {
  PRAGMA encoding = 'UTF16be';
  CREATE TABLE t1(a, b);
  INSERT INTO t1(rowid,a) VALUES (1,x'00'),(2,3);
  SELECT substr(a,',') is true FROM t1 ORDER BY rowid;
} {0 1}
do_execsql_test atof1-2.20 {
  SELECT substr(a,',') is true FROM t1 ORDER BY rowid DESC;
} {1 0}
do_execsql_test atof1-2.30 {
  CREATE INDEX i1 ON t1(a);
  SELECT count(*) FROM t1 WHERE substr(a,',');
} {1}
# 2020-08-27 OSSFuzz find related to the above.
do_execsql_test atof1-2.40 {
  SELECT randomblob(0) - 1;
} {-1}


finish_test

Changes to test/atrc.c.

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85







-
+







  sqlite3_str *pUndo        /* Append SQL to undo the rename here */
){
  sqlite3_stmt *pStmt;
  int rc;
  int cnt = 0;

  rc = sqlite3_prepare_v2(db,
         "SELECT name FROM sqlite_schema WHERE type='table'"
         "SELECT name FROM sqlite_master WHERE type='table'"
         " AND name NOT LIKE 'sqlite_%';",
         -1, &pStmt, 0);
  if( rc ) return rc;
  while( sqlite3_step(pStmt)==SQLITE_ROW ){
    const char *zTab = (const char*)sqlite3_column_text(pStmt, 0);
    char *zNewTab;
    char zPrefix[2];

Changes to test/attach.test.

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
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







-
-
+
+
+
+








-
-
+
+
+
+







  }
} {1 {database db5 is already in use}}
do_test attach-1.14 {
  catchsql {
    ATTACH 'test.db' as db9;
  }
} {1 {database db9 is already in use}}
do_catchsql_test attach-1.15 {
  ATTACH 'test.db' as main;
do_test attach-1.15 {
  catchsql {
    ATTACH 'test.db' as main;
  }
} {1 {database main is already in use}}
ifcapable tempdb {
  do_test attach-1.16 {
    catchsql {
      ATTACH 'test.db' as temp;
    }
  } {1 {database temp is already in use}}
}
do_catchsql_test attach-1.17 {
  ATTACH 'test.db' as MAIN;
do_test attach-1.17 {
  catchsql {
    ATTACH 'test.db' as MAIN;
  }
} {1 {database MAIN is already in use}}
do_test attach-1.18 {
  catchsql {
    ATTACH 'test.db' as db10;
    ATTACH 'test.db' as db11;
  }
} {0 {}}
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
226
227
228
229
230
231
232

233
234
235
236
237
238
239







-







  }
} {1 {no such database: db12}}
do_test attach-1.26 {
  catchsql {
    DETACH main;
  }
} {1 {cannot detach database main}}


ifcapable tempdb {
  do_test attach-1.27 {
    catchsql {
      DETACH Temp;
    }
  } {1 {cannot detach database Temp}}
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
909
910
911
912
913
914
915















916







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  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

Changes to test/attach4.test.

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
111
112
113
114
115
116
117



















118








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
  }
  set L
} $files

db close
foreach {name f} $files { forcedelete $f }

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  ATTACH DATABASE '' AS aux;
  CREATE TABLE IF NOT EXISTS aux.t1(a, b);
  CREATE TEMPORARY TRIGGER tr1 DELETE ON t1 BEGIN 
    DELETE FROM t1; 
  END;
  CREATE TABLE temp.t1(a, b);
}

do_execsql_test 2.1 {
  DETACH DATABASE aux;
}

do_execsql_test 2.2 {
  DROP TRIGGER tr1;
}

finish_test

Changes to test/auth.test.

2446
2447
2448
2449
2450
2451
2452



2453


2454
2455
2456
2457
2458
2459
2460
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455

2456
2457
2458
2459
2460
2461
2462
2463
2464







+
+
+
-
+
+







        DROP TABLE v1chng;
      }
    }
  }
  ifcapable stat4 {
    set stat4 "sqlite_stat4 "
  } else {
    ifcapable stat3 {
      set stat4 "sqlite_stat3 "
    } else {
    set stat4 ""
      set stat4 ""
    }
  }
  do_test auth-5.2 {
    execsql {
      SELECT name FROM (
        SELECT * FROM sqlite_master UNION ALL SELECT * FROM temp.sqlite_master)
      WHERE type='table'
      ORDER BY name

Changes to test/autoindex5.test.

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
119
120
121
122
123
124
125














126
127
128
129
130
131
132







-
-
-
-
-
-
-
-
-
-
-
-
-
-







    UNION ALL
    SELECT 0, 0 WHERE 0;

  SELECT (
      SELECT sum(z) FROM vvv WHERE x='aaa'
  ) FROM one;
} {8.0}
do_execsql_test 2.2 {
  DROP TABLE t1;
  CREATE TABLE t1(aaa);
  INSERT INTO t1(aaa) VALUES(9);
  SELECT (
    SELECT aaa FROM t1 GROUP BY (
      SELECT bbb FROM (
        SELECT ccc AS bbb FROM (
           SELECT 1 ccc
        ) WHERE rowid IS NOT 1
      ) WHERE bbb = 1
    )
  );
} {9}

# Ticket https://www.sqlite.org/src/info/787fa716be3a7f65
# Segfault due to multiple uses of the same subquery where the
# subquery is implemented via coroutine.
#
ifcapable windowfunc {
sqlite3 db :memory:

Deleted 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
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











































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 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-3.3. Test that appendvfs can grow by many pages and be written.
# avfs-3.4. Test that grown appendvfs can be reopened and appear intact.
# avfs-3.5. Test that much grown appendvfs can shrink and reopen intact.
# 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.
set ::nrint 50000
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 < $::nrint} {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 < $::nrint} {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 $adba
  set results [concat $results [lrange $qr 0 2]]
  lappend results [expr {$adba > 10.0}]
  set ::result [join $results " | "]
} "ok | $::nrint | 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}

# avfs-3.3. Test that appendvfs can grow by many pages and be written.
do_test 3.3 {
  set results {}
  sqlite3 adb "file:$::fa?mode=rw$::vf" -uri 1
  set npages 300
  adb eval { BEGIN }
  while {$npages > 0} {
    adb eval { INSERT INTO ri VALUES (randomblob(1500)) }
    incr npages -1
  }
  adb eval { COMMIT }
  adb eval {
    SELECT integrity_check as ic FROM pragma_integrity_check();
  } { lappend results $ic }
  adb close
  set adaSzr [expr [file size $::fa] / 300.0 / 1500 ]
  set okSzr [expr $adaSzr > 1.0 && $adaSzr < 1.3 ]
  lappend results $okSzr
  set ::result [join $results " | "]
} {ok | 1}

# avfs-3.4. Test that grown appendvfs can be reopened and appear intact.
do_test 3.4 {
  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 $ic
} {ok}

# avfs-3.5. Test that much grown appendvfs can shrink and reopen intact.
do_test 3.5 {
  set results {}
  set adbsz [file size $::fa]
  sqlite3 adb "file:$::fa?mode=rw$::vf" -uri 1
  adb eval {
    DELETE FROM ri WHERE rowid % 8 <> 0;
    SELECT integrity_check as ic FROM pragma_integrity_check();
    VACUUM;
    SELECT integrity_check as ic FROM pragma_integrity_check();
  } { lappend results $ic }
  adb close
  set adasz [file size $::fa]
  lappend results [expr {$adbsz/$adasz > 5}]
  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 | ok | 1 | 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 ::nrint ::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
163
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 {}
  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]
  if {[string match *BSD $tcl_platform(os)]} { set res "" }
  list $rc $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

Deleted test/bestindex7.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















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020-01-29
#
# 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 bestindex7

ifcapable !vtab {
  finish_test
  return
}

register_tcl_module db

proc vtab_command {src method args} {
  switch -- $method {
    xConnect {
      return "CREATE TABLE xxx(a)"
    }

    xBestIndex {
      set clist [lindex $args 0]
      set iCons 0
      set ret [list]
      foreach cons $clist {
        catch { array unset C }
        array set C $cons
        if {$C(usable)} {
          lappend ret use $iCons
        }
        incr iCons
      }
      return $ret
    }

    xFilter {
      return [list sql "SELECT rowid, x FROM $src"]
    }

  }

  return {}
}

do_execsql_test 1.0 {
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(0), (2);
  CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
}

do_execsql_test 1.1 { select * from vt1 } {0 2}
do_execsql_test 1.2 { select * from vt1 WHERE a=0 } {0}
do_execsql_test 1.3 { select * from vt1 WHERE a=1 } {}
do_execsql_test 1.4 { select * from vt1 WHERE a=1 OR a=0} {0}

do_execsql_test 1.5 {
  UPDATE t1 SET x=NULL WHERE x=2;
}

do_execsql_test 1.6 { select * from vt1 } {0 {}}
do_execsql_test 1.7 { select * from vt1 WHERE a=0 } {0}
do_execsql_test 1.8 { select * from vt1 WHERE a=1 } {}
do_execsql_test 1.9 { select * from vt1 WHERE a=1 OR a=0} {0}
do_execsql_test 1.10 { select * from vt1 WHERE a IN (2) } {}
do_execsql_test 1.10 { select * from vt1 WHERE a IN (0,1,2,3) } {0}
do_execsql_test 1.11 { select * from vt1 WHERE a IN (0, NULL) } {0}
do_execsql_test 1.12 { select * from vt1 WHERE a IN (NULL) } {}

finish_test

Changes to test/between.test.

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
115
116
117
118
119
120
121




















122
123







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


} {4 2 25 27 sort t1 i1zyx}
do_test between-1.5.3 {
  queryplan {
    SELECT * FROM t1 WHERE 26 BETWEEN y AND +z ORDER BY +w
  }
} {4 2 25 27 sort t1 *}

#-------------------------------------------------------------------------
reset_db
do_execsql_test between-2.0 {
  CREATE TABLE t1(x TEXT, y TEXT COLLATE nocase);
  INSERT INTO t1 VALUES('0', 'abc');
}

foreach {tn expr res} {
  1 "x                BETWEEN 1 AND '5'" 0
  2 "x COLLATE binary BETWEEN 1 AND '5'" 0
  3 "x COLLATE nocase BETWEEN 1 AND '5'" 0

  4 "y                  BETWEEN 'A' AND 'B'" 1
  5 "y COLLATE nocase   BETWEEN 'A' AND 'B'" 1
  6 "y COLLATE binary   BETWEEN 'A' AND 'B'" 0
  7 "(y COLLATE binary) BETWEEN 'A' AND 'B'" 0
} {
  set sql "SELECT $expr FROM t1"
  do_execsql_test between-2.1.$tn $sql $res
}

finish_test

Changes to test/bigmmap.test.

91
92
93
94
95
96
97
98

99
100
101
102
103
104
91
92
93
94
95
96
97

98
99
100
101
102
103
104







-
+






    do_eqp_test 2.$i.$t.3 "
      SELECT * FROM t$t AS o WHERE 
        NOT EXISTS( SELECT * FROM t$t AS i WHERE a=o.a AND +b=o.b AND +c=o.c )
      ORDER BY b, c;
    " [string map {"\n    " "\n"} "
      QUERY PLAN
      |--SCAN TABLE t$t AS o USING COVERING INDEX sqlite_autoindex_t${t}_1
      `--CORRELATED SCALAR SUBQUERY xxxxxx
      `--CORRELATED SCALAR SUBQUERY
         `--SEARCH TABLE t$t AS i USING INTEGER PRIMARY KEY (rowid=?)
    "]
  }
}

finish_test

Deleted test/busy2.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











































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 June 30
#
# 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 test the busy handler
#


set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set testprefix busy2

do_multiclient_test tn {
  do_test 1.$tn.0 {
    sql2 {
      CREATE TABLE t1(a, b);
      PRAGMA journal_mode = wal;
      INSERT INTO t1 VALUES('A', 'B');
    }
  } {wal}

  do_test 1.$tn.1 {
    code1 { db timeout 1000 }
    sql1 { SELECT * FROM t1 }
  } {A B}

  do_test 1.$tn.2 {
    sql2 {
      BEGIN;
        INSERT INTO t1 VALUES('C', 'D');
    }
  } {}

  do_test 1.$tn.3 {
    set us [lindex [time { catch { sql1 { BEGIN EXCLUSIVE } } }] 0]
    expr {$us>950000 && $us<1500000}
  } {1}

  do_test 1.$tn.4 {
    sql2 {
      COMMIT
    }
  } {}
}

#-------------------------------------------------------------------------

do_multiclient_test tn {
  # Make the db a WAL mode db. And add a table and a row to it. Then open
  # a second connection within process 1. Process 1 now has connections
  # [db] and [db1.2], process 2 has connection [db2] only.
  #
  # Configure all connections to use a 1000 ms timeout.
  #
  do_test 2.$tn.0 {
    code1 {
      sqlite3 db1.2 test.db
    }
    sql1 {
      PRAGMA auto_vacuum = off;
      PRAGMA journal_mode = wal;
      CREATE TABLE t1(a, b);
      INSERT INTO t1 VALUES(1, 2);
    }
    code2 {
      db2 timeout 1000
    }
    code1 {
      db1.2 timeout 1000
      db    timeout 1000
      db1.2 eval {SELECT * FROM t1}
    }
  } {1 2}

  # Take a read lock with [db] in process 1.
  #
  do_test 2.$tn.1 {
    sql1 {
      BEGIN;
        SELECT * FROM t1;
    }
  } {1 2}

  # Insert a row using [db2] in process 2. Then try a passive checkpoint.
  # It fails to checkpoint the final frame (due to the readlock taken by
  # [db]), and returns in less than 250ms.
  do_test 2.$tn.2 {
    sql2 { INSERT INTO t1 VALUES(3, 4) }
    set us [lindex [time {
      set res [code2 { db2 eval { PRAGMA wal_checkpoint } }]
    }] 0]
    list [expr $us < 250000] $res
  } {1 {0 4 3}}

  # Now try a FULL checkpoint with [db2]. It returns SQLITE_BUSY. And takes
  # over 950ms to do so.
  do_test 2.$tn.3 {
    set us [lindex [time {
      set res [code2 { db2 eval { PRAGMA wal_checkpoint = FULL } }]
    }] 0]
    list [expr $us > 950000] $res
  } {1 {1 4 3}}

  # Passive checkpoint with [db1.2] (process 1). No SQLITE_BUSY, returns
  # in under 250ms.
  do_test 2.$tn.4 {
    set us [lindex [time {
      set res [code1 { db1.2 eval { PRAGMA wal_checkpoint } }]
    }] 0]
    list [expr $us < 250000] $res
  } {1 {0 4 3}}

  # Full checkpoint with [db1.2] (process 1). SQLITE_BUSY returned in
  # a bit over 950ms.
  do_test 2.$tn.5 {
    set us [lindex [time {
      set res [code1 { db1.2 eval { PRAGMA wal_checkpoint = FULL } }]
    }] 0]
    list [expr $us > 950000] $res
  } {1 {1 4 3}}

  code1 {
    db1.2 close
  }
}

#-------------------------------------------------------------------------
# Check that even if the busy-handler fails (returns zero) within a
# call to sqlite3_prepare() (or _v2(), or _v3()), it is still invoked
# the next time an SQLITE_BUSY is encountered.
#
do_multiclient_test tn {
  code1 {
    set ::busy_called 0
    proc busy {args} {
      if {$::busy_called} { return 1 }
      set ::busy_called 1
      return 0
    }
    db busy busy
  }

  do_test 3.$tn.1 {
    sql2 {
      CREATE TABLE t1(x);
      BEGIN EXCLUSIVE;
        INSERT INTO t1 VALUES('x');
    }
  } {}

  do_test 3.$tn.2 {
    set ::busy_called 0
    list [catch { sql1 { SELECT * FROM t1 } } msg] $::busy_called
  } {1 1}

  do_test 3.$tn.3 {
    set ::busy_called 0
    list [catch { sql1 { SELECT * FROM t1 } } msg] $::busy_called
  } {1 1}

}

finish_test

Deleted test/carray01.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




































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020-11-17
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# 
# This file implements tests for CARRAY extension
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix carray01

ifcapable !vtab {
  finish_test
  return
}
load_static_extension db carray

# Parameter $stmt must be a prepared statement created using
# the sqlite3_prepare_v2 command and with parameters fullly bound.
# This routine simply runs the statement, gathers the result, and
# returns a list containing the result.
#
# If the optional second argument is true, then the stmt is finalized
# after it is run.
#
proc run_stmt {stmt {finalizeFlag 0}} {
  set r {}
  while {[sqlite3_step $stmt]=="SQLITE_ROW"} {
    for {set i 0} {$i<[sqlite3_data_count $stmt]} {incr i} {
      lappend r [sqlite3_column_text $stmt $i]
    }
  }
  if {$finalizeFlag} {
    sqlite3_finalize $stmt
  } else {
    sqlite3_reset $stmt
  }
  return $r
}

do_test 100 {
  set STMT [sqlite3_prepare_v2 db {SELECT 5 IN carray(?3)} -1]
  sqlite3_carray_bind $STMT 3 1 2 3 4 5 6 7
  run_stmt $STMT 0
} {1}
do_test 101 {
  sqlite3_carray_bind -static $STMT 3 1 2 3 4 5 6 7
  run_stmt $STMT 0
} {1}
do_test 110 {
  sqlite3_carray_bind $STMT 3 1 2 3 4 6 7
  run_stmt $STMT 0
} {0}
do_test 120 {
  sqlite3_carray_bind -int64 $STMT 3 1 2 3 4 5 6 7
  run_stmt $STMT 0
} {1}
do_test 130 {
  sqlite3_carray_bind -int64 $STMT 3 1 2 3 4 6 7
  run_stmt $STMT 0
} {0}
do_test 131 {
  sqlite3_carray_bind -int64 -static $STMT 3 1 2 3 4 6 7
  run_stmt $STMT 0
} {0}
do_test 140 {
  sqlite3_carray_bind -double $STMT 3 1 2 3 4 5 6 7
  run_stmt $STMT 0
} {1}
do_test 150 {
  sqlite3_carray_bind -double $STMT 3 1 2 3 4 6 7
  run_stmt $STMT 0
} {0}
do_test 160 {
  sqlite3_carray_bind -double $STMT 3 1 2 3 4 5 6 7
  run_stmt $STMT 0
} {1}
do_test 170 {
  sqlite3_carray_bind -text -static $STMT 3 1 2 3 4 6 7
  run_stmt $STMT 0
} {0}
do_test 180 {
  sqlite3_carray_bind -text -transient $STMT 3 1 2 3 4 5 6 7
  run_stmt $STMT 0
} {0}
do_test 190 {
  sqlite3_carray_bind $STMT 3
  run_stmt $STMT 0
} {0}

sqlite3_finalize $STMT

finish_test

Changes to test/cast.test.

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
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







-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+







do_test cast-1.51 {
  execsql {SELECT CAST('123.5abc' AS numeric)}
} 123.5
do_test cast-1.53 {
  execsql {SELECT CAST('123.5abc' AS integer)}
} 123

do_test cast-1.60 {
do_test case-1.60 {
  execsql {SELECT CAST(null AS REAL)}
} {{}}
do_test cast-1.61 {
do_test case-1.61 {
  execsql {SELECT typeof(CAST(null AS REAL))}
} {null}
do_test cast-1.62 {
do_test case-1.62 {
  execsql {SELECT CAST(1 AS REAL)}
} {1.0}
do_test cast-1.63 {
do_test case-1.63 {
  execsql {SELECT typeof(CAST(1 AS REAL))}
} {real}
do_test cast-1.64 {
do_test case-1.64 {
  execsql {SELECT CAST('1' AS REAL)}
} {1.0}
do_test cast-1.65 {
do_test case-1.65 {
  execsql {SELECT typeof(CAST('1' AS REAL))}
} {real}
do_test cast-1.66 {
do_test case-1.66 {
  execsql {SELECT CAST('abc' AS REAL)}
} {0.0}
do_test cast-1.67 {
do_test case-1.67 {
  execsql {SELECT typeof(CAST('abc' AS REAL))}
} {real}
do_test cast-1.68 {
do_test case-1.68 {
  execsql {SELECT CAST(x'31' AS REAL)}
} {1.0}
do_test cast-1.69 {
do_test case-1.69 {
  execsql {SELECT typeof(CAST(x'31' AS REAL))}
} {real}


# Ticket #1662.  Ignore leading spaces in numbers when casting.
#
do_test cast-2.1 {
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
295
296
297
298
299
300
301

302
303
304
305
306
307
308
309







-
+







      execsql {
        SELECT CAST(CAST(x'39323233333732303336383534373734383030' AS real)
                    AS integer)
      }
    } 9223372036854774784
  }
}
do_test cast-3.31 {
do_test case-3.31 {
  execsql {SELECT CAST(NULL AS numeric)}
} {{}}

# Test to see if it is possible to trick SQLite into reading past 
# the end of a blob when converting it to a number.
do_test cast-3.32.1 {
  set blob "1234567890"
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
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







-
+


-
-
+





-
+









-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


} {-9223372036854775808 -9223372036854775808 -9223372036854775808}

# EVIDENCE-OF: R-33990-33527 When casting to INTEGER, if the text looks
# like a floating point value with an exponent, the exponent will be
# ignored because it is no part of the integer prefix.
# EVIDENCE-OF: R-24225-46995 For example, "(CAST '123e+5' AS INTEGER)"
# results in 123, not in 12300000.
do_execsql_test cast-5.3 {
do_execsql_test case-5.3 {
  SELECT CAST('123e+5' AS INTEGER);
  SELECT CAST('123e+5' AS NUMERIC);
  SELECT CAST('123e+5' AS REAL);
} {123 12300000 12300000.0}
} {123 12300000.0}


# The following does not have anything to do with the CAST operator,
# but it does deal with affinity transformations.
#
do_execsql_test cast-6.1 {
do_execsql_test case-6.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a NUMERIC);
  INSERT INTO t1 VALUES
     ('9000000000000000001'),
     ('9000000000000000001 '),
     (' 9000000000000000001'),
     (' 9000000000000000001 ');
  SELECT * FROM t1;
} {9000000000000000001 9000000000000000001 9000000000000000001 9000000000000000001}

# 2019-06-07
# https://www.sqlite.org/src/info/4c2d7639f076aa7c
do_execsql_test cast-7.1 {
  SELECT CAST('-' AS NUMERIC);
} {0}
do_execsql_test cast-7.2 {
  SELECT CAST('-0' AS NUMERIC);
} {0}
do_execsql_test cast-7.3 {
  SELECT CAST('+' AS NUMERIC);
} {0}
do_execsql_test cast-7.4 {
  SELECT CAST('/' AS NUMERIC);
} {0}

# 2019-06-07
# https://www.sqlite.org/src/info/e8bedb2a184001bb
do_execsql_test cast-7.10 {
  SELECT '' - 2851427734582196970;
} {-2851427734582196970}
do_execsql_test cast-7.11 {
  SELECT 0 - 2851427734582196970;
} {-2851427734582196970}
do_execsql_test cast-7.12 {
  SELECT '' - 1;
} {-1}

# 2019-06-10
# https://www.sqlite.org/src/info/dd6bffbfb6e61db9
#
# EVIDENCE-OF: R-55084-10555 Casting a TEXT or BLOB value into NUMERIC
# yields either an INTEGER or a REAL result.
#
do_execsql_test cast-7.20 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0 (c0 TEXT);
  INSERT INTO t0(c0) VALUES ('1.0');
  SELECT CAST(c0 AS NUMERIC) FROM t0;
} {1}

# 2019-06-10
# https://sqlite.org/src/info/27de823723a41df45af3
#
do_execsql_test cast-7.30 {
  SELECT -'.';
} 0
do_execsql_test cast-7.31 {
  SELECT '.'+0;
} 0
do_execsql_test cast-7.32 {
  SELECT CAST('.' AS numeric);
} 0
do_execsql_test cast-7.33 {
  SELECT -CAST('.' AS numeric);
} 0

# 2019-06-12
# https://www.sqlite.org/src/info/674385aeba91c774
#
do_execsql_test cast-7.40 {
  SELECT CAST('-0.0' AS numeric);
} 0
do_execsql_test cast-7.41 {
  SELECT CAST('0.0' AS numeric);
} 0
do_execsql_test cast-7.42 {
  SELECT CAST('+0.0' AS numeric);
} 0
do_execsql_test cast-7.43 {
  SELECT CAST('-1.0' AS numeric);
} -1

ifcapable utf16 {
  reset_db
  execsql { PRAGMA encoding='utf16' }

  do_execsql_test cast-8.1 {
    SELECT quote(X'310032003300')==quote(substr(X'310032003300', 1))
  } 1
  do_execsql_test cast-8.2 {
    SELECT CAST(X'310032003300' AS TEXT)
         ==CAST(substr(X'310032003300', 1) AS TEXT)
  } 1
}

reset_db
do_execsql_test cast-9.0 {
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES (0);
  CREATE VIEW v1(c0, c1) AS 
    SELECT CAST(0.0 AS NUMERIC), COUNT(*) OVER () FROM t0;
  SELECT v1.c0 FROM v1, t0 WHERE v1.c0=0; 
} {0.0}


finish_test

Changes to test/check.test.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21













+







# 2005 November 2
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing CHECK constraints
#
# $Id: check.test,v 1.13 2009/06/05 17:09:12 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix check

# Only run these tests if the build includes support for CHECK constraints
ifcapable !check {
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
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







-
+









-
+







    SELECT * FROM t1;
  }  
} {3 4.0}
do_test check-1.3 {
  catchsql {
    INSERT INTO t1 VALUES(6,7);
  }
} {1 {CHECK constraint failed: x<5}}
} {1 {CHECK constraint failed: t1}}
do_test check-1.4 {
  execsql {
    SELECT * FROM t1;
  }  
} {3 4.0}
do_test check-1.5 {
  catchsql {
    INSERT INTO t1 VALUES(4,3);
  }
} {1 {CHECK constraint failed: y>x}}
} {1 {CHECK constraint failed: t1}}
do_test check-1.6 {
  execsql {
    SELECT * FROM t1;
  }  
} {3 4.0}
do_test check-1.7 {
  catchsql {
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
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







-
+









-
+


















-





-
-
-
-
-
-







    SELECT * FROM t1;
  }
} {2 4.0}
do_test check-1.12 {
  catchsql {
    UPDATE t1 SET x=7 WHERE x==2
  }
} {1 {CHECK constraint failed: x<5}}
} {1 {CHECK constraint failed: t1}}
do_test check-1.13 {
  execsql {
    SELECT * FROM t1;
  }
} {2 4.0}
do_test check-1.14 {
  catchsql {
    UPDATE t1 SET x=5 WHERE x==2
  }
} {1 {CHECK constraint failed: x<5}}
} {1 {CHECK constraint failed: t1}}
do_test check-1.15 {
  execsql {
    SELECT * FROM t1;
  }
} {2 4.0}
do_test check-1.16 {
  catchsql {
    UPDATE t1 SET x=4, y=11 WHERE x==2
  }
} {0 {}}
do_test check-1.17 {
  execsql {
    SELECT * FROM t1;
  }
} {4 11.0}

do_test check-2.1 {
  execsql {
    PRAGMA writable_schema = 1;
    CREATE TABLE t2(
      x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
      y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
      z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
    );
    CREATE TABLE t2n(
      x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
      y NUMERIC CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
      z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
    );
    PRAGMA writable_schema = 0;
  }
} {}
do_test check-2.2 {
  execsql {
    INSERT INTO t2 VALUES(1,2.2,'three');
    SELECT * FROM t2;
  }
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
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







-



-
-
-
-
-
-
-





-
+



















-
+




















-







} {1 2.2 three {} {} {}}
do_test check-2.4 {
  catchsql {
    INSERT INTO t2 VALUES(1.1, NULL, NULL);
  }
} {1 {CHECK constraint failed: one}}
do_test check-2.5 {
  # The 5 gets automatically promoted to 5.0 because the column type is REAL
  catchsql {
    INSERT INTO t2 VALUES(NULL, 5, NULL);
  }
} {0 {}}
do_test check-2.5b {
  # This time the column type is NUMERIC, so not automatic promption to REAL
  # occurs and the constraint fails.
  catchsql {
    INSERT INTO t2n VALUES(NULL, 5, NULL);
  }
} {1 {CHECK constraint failed: two}}
do_test check-2.6 {
  catchsql {
    INSERT INTO t2 VALUES(NULL, NULL, 3.14159);
  }
} {0 {}}
} {1 {CHECK constraint failed: three}}

# Undocumented behavior:  The CONSTRAINT name clause can follow a constraint.
# Such a clause is ignored.  But the parser must accept it for backwards
# compatibility.
#
do_test check-2.10 {
  execsql {
    CREATE TABLE t2b(
      x INTEGER CHECK( typeof(coalesce(x,0))=='integer' ) CONSTRAINT one,
      y TEXT PRIMARY KEY constraint two,
      z INTEGER,
      UNIQUE(x,z) constraint three
    );
  }
} {}
do_test check-2.11 {
  catchsql {
    INSERT INTO t2b VALUES('xyzzy','hi',5);
  }
} {1 {CHECK constraint failed: typeof(coalesce(x,0))=='integer'}}
} {1 {CHECK constraint failed: t2b}}
do_test check-2.12 {
  execsql {
    CREATE TABLE t2c(
      x INTEGER CONSTRAINT x_one CONSTRAINT x_two
          CHECK( typeof(coalesce(x,0))=='integer' )
          CONSTRAINT x_two CONSTRAINT x_three,
      y INTEGER, z INTEGER,
      CONSTRAINT u_one UNIQUE(x,y,z) CONSTRAINT u_two
    );
  }
} {}
do_test check-2.13 {
  catchsql {
    INSERT INTO t2c VALUES('xyzzy',7,8);
  }
} {1 {CHECK constraint failed: x_two}}
do_test check-2.cleanup {
  execsql {
    DROP TABLE IF EXISTS t2b;
    DROP TABLE IF EXISTS t2c;
    DROP TABLE IF EXISTS t2n;
  }
} {}

ifcapable subquery {
  do_test check-3.1 {
    catchsql {
      CREATE TABLE t3(
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266







-
+







    SELECT * FROM t3;
  }
} {1 2 3}
do_test check-3.9 {
  catchsql {
    INSERT INTO t3 VALUES(111,222,333);
  }
} {1 {CHECK constraint failed: t3.x<25}}
} {1 {CHECK constraint failed: t3}}

do_test check-4.1 {
  execsql {
    CREATE TABLE t4(x, y,
      CHECK (
           x+y==11
        OR x*y==12
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
294
295
296
297
298
299
300

301



302
303
304
305
306
307
308







-
+
-
-
-







    SELECT * FROM t4
  }
} {12 -22}
do_test check-4.6 {
  catchsql {
    UPDATE t4 SET x=0, y=1;
  }
} {1 {CHECK constraint failed: x+y==11
} {1 {CHECK constraint failed: t4}}
        OR x*y==12
        OR x/y BETWEEN 5 AND 8
        OR -x==y+10}}
do_test check-4.7 {
  execsql {
    SELECT * FROM t4;
  }
} {12 -22}
do_test check-4.8 {
  execsql {
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
316
317
318
319
320
321
322

323



324
325
326
327
328
329
330







-
+
-
-
-







  PRAGMA ignore_check_constraints=OFF;
  PRAGMA integrity_check;
} {{CHECK constraint failed in t4}}
do_test check-4.9 {
  catchsql {
    UPDATE t4 SET x=0, y=2;
  }
} {1 {CHECK constraint failed: x+y==11
} {1 {CHECK constraint failed: t4}}
        OR x*y==12
        OR x/y BETWEEN 5 AND 8
        OR -x==y+10}}
ifcapable vacuum {
  do_test check_4.10 {
    catchsql {
      VACUUM
    }
  } {0 {}}
}
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
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







-
+











-
+


















-
+







    SELECT * FROM t1;
  }
} {4 11.0 2 20.0}
do_test check-6.5 {
  catchsql {
    UPDATE OR FAIL t1 SET x=7-x, y=y+1;
  }
} {1 {CHECK constraint failed: x<5}}
} {1 {CHECK constraint failed: t1}}
do_test check-6.6 {
  execsql {
    SELECT * FROM t1;
  }
} {3 12.0 2 20.0}
do_test check-6.7 {
  catchsql {
    BEGIN;
    INSERT INTO t1 VALUES(1,30.0);
    INSERT OR ROLLBACK INTO t1 VALUES(8,40.0);
  }
} {1 {CHECK constraint failed: x<5}}
} {1 {CHECK constraint failed: t1}}
do_test check-6.8 {
  catchsql {
    COMMIT;
  }
} {1 {cannot commit - no transaction is active}}
do_test check-6.9 {
  execsql {
    SELECT * FROM t1
  }
} {3 12.0 2 20.0}

do_test check-6.11 {
  execsql {SELECT * FROM t1}
} {3 12.0 2 20.0}
do_test check-6.12 {
  catchsql {
    REPLACE INTO t1 VALUES(6,7);
  }
} {1 {CHECK constraint failed: x<5}}
} {1 {CHECK constraint failed: t1}}
do_test check-6.13 {
  execsql {SELECT * FROM t1}
} {3 12.0 2 20.0}
do_test check-6.14 {
  catchsql {
    INSERT OR IGNORE INTO t1 VALUES(6,7);
  }
443
444
445
446
447
448
449
450

451
452
453
454
455

456
457
458
459
460
461
462
422
423
424
425
426
427
428

429
430
431
432
433

434
435
436
437
438
439
440
441







-
+




-
+







# If a connection opens a database that contains a CHECK constraint that
# uses an unknown UDF, the schema should not be considered malformed.
# Attempting to modify the table should fail (since the CHECK constraint
# cannot be tested).
#
reset_db
proc myfunc {x} {expr $x < 10}
db func myfunc -deterministic myfunc
db func myfunc myfunc

do_execsql_test  7.1 { CREATE TABLE t6(a CHECK (myfunc(a))) }
do_execsql_test  7.2 { INSERT INTO t6 VALUES(9)  }
do_catchsql_test 7.3 { INSERT INTO t6 VALUES(11) } \
          {1 {CHECK constraint failed: myfunc(a)}}
          {1 {CHECK constraint failed: t6}}

do_test 7.4 {
  sqlite3 db2 test.db
  execsql { SELECT * FROM t6 } db2 
} {9}

do_test 7.5 {
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464







-
+







  db2 func myfunc myfunc
  execsql { INSERT INTO t6 VALUES(8) } db2
} {}

do_test 7.8 {
  db2 func myfunc myfunc
  catchsql { INSERT INTO t6 VALUES(12) } db2
} {1 {CHECK constraint failed: myfunc(a)}}
} {1 {CHECK constraint failed: t6}}

# 2013-08-02:  Silently ignore database name qualifiers in CHECK constraints.
#
do_execsql_test 8.1 {
  CREATE TABLE t810(a, CHECK( main.t810.a>0 ));
  CREATE TABLE t811(b, CHECK( xyzzy.t811.b BETWEEN 5 AND 10 ));
} {}
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
489
490
491
492
493
494
495






























































































496







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

sqlite3 db test.db
do_execsql_test 10.1 {
  CREATE TABLE t1(x);
  CREATE VIEW v1(y) AS SELECT x FROM t1;
  PRAGMA integrity_check;
} {ok}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 11.0 {
  CREATE TABLE t1 (Col0 CHECK(1 COLLATE BINARY BETWEEN 1 AND 1) ) ;
}
do_execsql_test 11.1 {
  INSERT INTO t1 VALUES (NULL);
}
do_execsql_test 11.2 {
  INSERT  INTO t1 VALUES (NULL);
}

do_execsql_test 11.3 {
  CREATE TABLE t2(b, a CHECK(
      CASE 'abc' COLLATE nocase WHEN a THEN 1 ELSE 0 END)
  );
}
do_execsql_test 11.4 {
  INSERT INTO t2(a) VALUES('abc');
}
do_execsql_test 11.5 {
  INSERT INTO t2(b, a) VALUES(1, 'abc'||'');
}
do_execsql_test 11.6 {
  INSERT INTO t2(b, a) VALUES(2, 'abc');
}

# 2019-12-24 ticket b383b90278186263
#
reset_db
do_execsql_test 12.10 {
  CREATE TABLE t1(a TEXT, CHECK(a=+a));
  INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75);
  SELECT quote(a) FROM t1 ORDER BY rowid;
} {NULL 'xyz' '5' X'303132' '4.75'}
do_execsql_test 12.20 {
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, CHECK(a<>+a));
  INSERT INTO t1(a) VALUES(NULL);
} {}
do_catchsql_test 12.21 {
  INSERT INTO t1(a) VALUES('xyz');
} {1 {CHECK constraint failed: a<>+a}}
do_catchsql_test 12.22 {
  INSERT INTO t1(a) VALUES(123);
} {1 {CHECK constraint failed: a<>+a}}
do_execsql_test 12.30 {
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, CHECK(NOT(a=+a)));
  INSERT INTO t1(a) VALUES(NULL);
} {}
do_catchsql_test 12.31 {
  INSERT INTO t1(a) VALUES('xyz');
} {1 {CHECK constraint failed: NOT(a=+a)}}
do_catchsql_test 12.32 {
  INSERT INTO t1(a) VALUES(123);
} {1 {CHECK constraint failed: NOT(a=+a)}}
do_execsql_test 12.40 {
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, CHECK(NOT(a<>+a)));
  INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75);
  SELECT quote(a) FROM t1 ORDER BY rowid;
} {NULL 'xyz' '5' X'303132' '4.75'}
do_execsql_test 12.50 {
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, CHECK(a BETWEEN 0 AND +a));
  INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75);
  SELECT quote(a) FROM t1 ORDER BY rowid;
} {NULL 'xyz' '5' X'303132' '4.75'}
do_execsql_test 12.60 {
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, CHECK(a NOT BETWEEN 0 AND +a));
  INSERT INTO t1(a) VALUES(NULL);
  SELECT quote(a) FROM t1 ORDER BY rowid;
} {NULL}
do_catchsql_test 12.61 {
  INSERT INTO t1(a) VALUES(456);
} {1 {CHECK constraint failed: a NOT BETWEEN 0 AND +a}}
do_execsql_test 12.70 {
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, CHECK(a BETWEEN +a AND 999999));
  INSERT INTO t1(a) VALUES(NULL),(5);
  SELECT quote(a) FROM t1 ORDER BY rowid;
} {NULL '5'}
do_execsql_test 12.80 {
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, CHECK(a NOT BETWEEN +a AND 999999));
  INSERT INTO t1(a) VALUES(NULL);
  SELECT quote(a) FROM t1 ORDER BY rowid;
} {NULL}
do_catchsql_test 12.81 {
  INSERT INTO t1(a) VALUES(456);
} {1 {CHECK constraint failed: a NOT BETWEEN +a AND 999999}}

finish_test

Deleted test/checkfault.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









































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 July 17
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains fault-injection test cases for the 
# sqlite3_db_cacheflush API.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix cffault
source $testdir/malloc_common.tcl

do_execsql_test 1.0 {
  CREATE TABLE t1 (Col0 CHECK(1 COLLATE BINARY BETWEEN 1 AND 1) ) ;
  CREATE TABLE t2(b, a CHECK(
      CASE 'abc' COLLATE nocase WHEN a THEN 1 ELSE 0 END)
  );
}

do_faultsim_test 1.1 -faults oom* -body {
  execsql { INSERT INTO t1 VALUES ('ABCDEFG') }
} -test {
  faultsim_test_result {0 {}}
}

do_faultsim_test 1.2 -faults oom* -body {
  execsql { INSERT INTO t2(a) VALUES('abc') }
} -test {
  faultsim_test_result {0 {}}
}


finish_test

Deleted test/chunksize.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









































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 June 5
#
# 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 chunksize

if {$::tcl_platform(platform)!="unix"} {
  finish_test
  return
}

foreach {tn jrnlmode} {
  1 delete
  2 wal
} {
  reset_db
  file_control_chunksize_test db main 32768
  do_execsql_test $tn.0 " PRAGMA journal_mode = $jrnlmode " $jrnlmode
  do_execsql_test $tn.1 {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 2);
  }

  execsql { PRAGMA wal_checkpoint }

  do_test $tn.2 {
    file size test.db
  } 32768
}

finish_test

Changes to test/close.test.

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
75
76
77
78
79
80
81







82







-
-
-
-
-
-
-

  } msg] $msg
} {1 {(21) bad parameter or other API misuse}}

do_test 1.4.4 {
  sqlite3_finalize $STMT
} {SQLITE_OK}

do_test 1.5 {
  set DB [sqlite3_open test.db]
  sqlite3_blob_open $DB main t1 x 2 0 BLOB
  sqlite3_close_v2 $DB
  sqlite3_blob_close $BLOB
} {}

finish_test

Changes to test/collate1.test.

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
396
397
398
399
400
401
402















































403
404







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


    ORDER BY 1 COLLATE nocase COLLATE nocase COLLATE nocase COLLATE binary;
} {DEF abc}
do_execsql_test 7.2 {
   SELECT 'abc' UNION ALL SELECT 'DEF'
    ORDER BY 1 COLLATE binary COLLATE binary COLLATE binary COLLATE nocase;
} {abc DEF}

# 2019-06-14
# https://sqlite.org/src/info/f1580ba1b574e9e9
#
do_execsql_test 8.0 {
  SELECT ' ' > char(20) COLLATE rtrim;
} 0
do_execsql_test 8.1 {
  SELECT '' < char(20) COLLATE rtrim;
} 1
do_execsql_test 8.2 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 COLLATE RTRIM, c1 BLOB UNIQUE,
                  PRIMARY KEY (c0, c1)) WITHOUT ROWID;
  INSERT INTO t0 VALUES (123, 3), (' ', 1), ('	', 2), ('', 4);
  SELECT * FROM t0 WHERE c1 = 1;
} {{ } 1}

# 2019-10-09
# ALWAYS() macro fails following OOM
# Problem detected by dbsqlfuzz.
#
do_execsql_test 9.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d);
}

do_faultsim_test 9.1 -faults oom* -body {
  execsql {
    SELECT * FROM (
        SELECT b COLLATE nocase IN (SELECT c FROM t2) FROM t1
    );
  }
} -test {
  faultsim_test_result {0 {}}
}

# 2020-01-03 dbsqlfuzz find
#
reset_db
do_catchsql_test 10.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY,b);
  INSERT INTO t1 VALUES(0,NULL);
  CREATE TABLE t2(x UNIQUE);
  CREATE VIEW v1a(z,y) AS SELECT x COLLATE x FROM t2;
  SELECT a,b,z,y,'' FROM t1 JOIN v1a ON b IS NOT FALSE;
} {1 {no such collation sequence: x}}


finish_test

Changes to test/colname.test.

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
395
396
397
398
399
400
401






402
403
404
405
406
407
408







-
-
-
-
-
-







} {Bbb 123}
ifcapable vtab {
  do_execsql_test colname-9.320 {
    CREATE TABLE t2 AS SELECT BBb FROM (SELECT aaa AS Bbb FROM t1);
    SELECT name FROM pragma_table_info('t2');
  } {Bbb}
}
do_execsql_test colname-9.330 { -- added 2019-08-10 to invalidate
  DROP TABLE IF EXISTS t1;      -- a couple assert()s that were
  CREATE TABLE t1(a);           -- added by ticket 3b44500725
  INSERT INTO t1 VALUES(17),(2),(99),(-3),(7);
  SELECT (SELECT avg(a) UNION SELECT min(a) OVER()) FROM t1;
} {17}

# Issue detected by OSSFuzz on 2017-12-24 (Christmas Eve)
# caused by check-in https://sqlite.org/src/info/6b2ff26c25
#
# Prior to being fixed, the following CREATE TABLE was dereferencing
# a NULL pointer and segfaulting.
#

Deleted 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

Changes to test/conflict.test.

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
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







-
+




















-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

    CREATE TABLE t13(a CHECK(a!=2));
    BEGIN;
    REPLACE INTO t13 VALUES(1);
  }
  catchsql {
    REPLACE INTO t13 VALUES(2);
  }
} {1 {CHECK constraint failed: a!=2}}
} {1 {CHECK constraint failed: t13}}
verify_ex_errcode conflict-13.1b SQLITE_CONSTRAINT_CHECK
do_test conflict-13.2 {
  execsql {
    REPLACE INTO t13 VALUES(3);
    COMMIT;
    SELECT * FROM t13;
  }
} {1 3}


# Ticket https://www.sqlite.org/src/tktview/e6f1f2e34dceeb1ed61531c7e9
# Verify that it is not possible to sneak a NULL value into a NOT NULL
# column using REPLACE.
#
do_catchsql_test conflict-14.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x NOT NULL DEFAULT NULL);
  REPLACE INTO t1 DEFAULT VALUES;
} {1 {NOT NULL constraint failed: t1.x}}

# 2019-12-15 gramfuzz1 find
# Three UNIQUE constraints, where the third would is a duplicate except
# that it adds ON CONFLICT REPLACE.  Verify that the indexes end up
# sorted in the correct order (REPLACE last) so that constraint processing
# works correctly.
#

reset_db
do_execsql_test conflict-15.10 {
  CREATE TABLE t1(
    x PRIMARY KEY,
    UNIQUE(x,x),
    UNIQUE(x,x) ON CONFLICT REPLACE
  );
  INSERT INTO t1(x) VALUES(1);
  SELECT * FROM t1;
} {1}
do_catchsql_test conflict-15.20 {
  INSERT INTO t1(x) VALUES(1);
} {1 {UNIQUE constraint failed: t1.x}}
do_execsql_test conflict-15.30 {
  SELECT * FROM t1;
} {1}

finish_test

Changes to test/conflict2.test.

807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
807
808
809
810
811
812
813

814
815
816
817
818
819
820
821







-
+







    CREATE TABLE t13(a PRIMARY KEY CHECK(a!=2)) WITHOUT rowid;
    BEGIN;
    REPLACE INTO t13 VALUES(1);
  }
  catchsql {
    REPLACE INTO t13 VALUES(2);
  }
} {1 {CHECK constraint failed: a!=2}}
} {1 {CHECK constraint failed: t13}}
verify_ex_errcode conflict2-13.1b SQLITE_CONSTRAINT_CHECK
do_test conflict2-13.2 {
  execsql {
    REPLACE INTO t13 VALUES(3);
    COMMIT;
    SELECT * FROM t13;
  }

Changes to test/conflict3.test.

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
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
362
363
364
365
366
367
368



































































369
370







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


do_execsql_test 12.2 {
  REPLACE INTO t2 VALUES(NULL, '112'), (111, '111B');
}
do_execsql_test 12.3 {
  SELECT * FROM t2;
} {111 111B 112 112}

#-------------------------------------------------------------------------
ifcapable trigger {
  reset_db
  do_execsql_test 13.1.0 {
    PRAGMA recursive_triggers = true;
    CREATE TABLE t0 (c0 UNIQUE, c1 UNIQUE);
    CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN 
      DELETE FROM t0; 
    END;

    INSERT INTO t0 VALUES(1, NULL);
    INSERT INTO t0 VALUES(0, NULL);
  }

  do_catchsql_test 13.1.1 {
    UPDATE OR REPLACE t0 SET c1 = 1;
  } {1 {constraint failed}}

  integrity_check 13.1.2

  do_execsql_test 13.1.3 {
    SELECT * FROM t0
  } {1 {} 0 {}}

  do_execsql_test 13.2.0 {
    CREATE TABLE t2 (a PRIMARY KEY, b UNIQUE, c UNIQUE) WITHOUT ROWID;
    CREATE TRIGGER tr3 AFTER DELETE ON t2 BEGIN 
      DELETE FROM t2; 
    END;

    INSERT INTO t2 VALUES(1, 1, 1);
    INSERT INTO t2 VALUES(2, 2, 2);
  }

  do_catchsql_test 13.2.1 {
    UPDATE OR REPLACE t2 SET c = 0;
  } {1 {constraint failed}}

  integrity_check 13.2.2

  do_execsql_test 13.2.3 {
    SELECT * FROM t2
  } {1 1 1 2 2 2}

  do_execsql_test 13.3.0 {
    CREATE TABLE t1(a, b);
    CREATE TABLE log(x);
    CREATE INDEX i1 ON t1(a);
    INSERT INTO t1 VALUES(1, 2);

    CREATE TRIGGER tb BEFORE UPDATE ON t1 BEGIN
      DELETE FROM t1;
    END;
    CREATE TRIGGER ta AFTER UPDATE ON t1 BEGIN
      INSERT INTO log VALUES('fired!');
    END;

    UPDATE t1 SET b=3;
  }

  do_execsql_test 13.3.1 {
    SELECT * FROM t1;
  } {}
  do_execsql_test 13.3.2 {
    SELECT * FROM log;
  } {}
}

finish_test

Changes to test/corrupt3.test.

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104







-
+







do_test corrupt3-1.9 {
  db close
  hexio_write test.db 2044 [hexio_render_int32 4]
  sqlite3 db test.db
  catchsql {
    SELECT substr(x,1,10) FROM t1
  }
} [list 1 {database disk image is malformed}]
} [list 0 0123456789]
do_test corrupt3-1.10 {
  catchsql {
    PRAGMA integrity_check
  }
} {0 {{*** in database main ***
On tree page 2 cell 0: invalid page number 4
Page 3 is never used}}}

Changes to test/corruptC.test.

30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46







-


+







# These tests deal with corrupt database files
#
database_may_be_corrupt

# Construct a compact, dense database for testing.
#
do_test corruptC-1.1 {
  sqlite3_db_config db LEGACY_FILE_FORMAT 1
  execsql {
    PRAGMA auto_vacuum = 0;
    PRAGMA legacy_file_format=1;
    BEGIN;
    CREATE TABLE t1(x,y);
    INSERT INTO t1 VALUES(1,1);
    INSERT OR IGNORE INTO t1 SELECT x*2,y FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*3,y FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*5,y FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*7,y FROM t1;

Changes to test/corruptE.test.

32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48







-


+







  finish_test
  return
}

# Construct a compact, dense database for testing.
#
do_test corruptE-1.1 {
  sqlite3_db_config db LEGACY_FILE_FORMAT 1
  execsql {
    PRAGMA auto_vacuum = 0;
    PRAGMA legacy_file_format=1;
    BEGIN;
    CREATE TABLE t1(x,y);
    INSERT INTO t1 VALUES(1,1);
    INSERT OR IGNORE INTO t1 SELECT x*2,y FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*3,y FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*5,y FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*7,y FROM t1;

Changes to test/corruptL.test.

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
224
225
226
227
228
229
230

231
232
233
234
235
236
237







-







|   4080: 01 04 04 03 08 01 13 04 03 08 01 02 03 03 08 09   ................
| page 5 offset 16384
|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
| end crash.txt.db
}]} {}

do_execsql_test 2.1 {
  PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
  INSERT INTO t1(b) VALUES(X'a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bfef346e6ac8ae0d0e7c3175946e62ba2b');
}

do_catchsql_test 2.2 {
  SELECT b,c FROM t1 ORDER BY a;
} {1 {database disk image is malformed}}

373
374
375
376
377
378
379
380
381
382
383
384
385
386

387

388
389
390
391
392
393
394
372
373
374
375
376
377
378




379

380
381

382
383
384
385
386
387
388
389







-
-
-
-

-

+
-
+







|    448: 00 00 74 72 69 67 62 ff ff ff ff fc 00 00 07 05   ..trigb.........
|    464: 05 01 01 09 09 02 02 19 04 05 17 17 17 17 10 65   ...............e
|    480: 76 65 6e 65 69 67 68 74 65 40 18 00 00 00 00 01   veneighte@......
|    496: 02 03 07 04 01 01 01 03 04 02 05 04 09 01 ff fd   ................
| end crash-6b48ba69806134.db
}]} {}

set res {1 {database disk image is malformed}}
ifcapable oversize_cell_check {
  set res {1 {no such table: t3}}
}
do_catchsql_test 4.1 {
  PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
  INSERT INTO t3 SELECT * FROM t2;
} {1 {database disk image is malformed}}
} $res


#-------------------------------------------------------------------------
reset_db
do_test 5.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 192512 pagesize 4096 filename crash-9ae5502296c949.db
606
607
608
609
610
611
612
613

614
615
616
617
618
619
620
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615







-
+







|   3808: 05 43 52 45 41 54 45 20 49 4e 44 45 58 20 74 31   .CREATE INDEX t1
|   3824: 62 20 4f 4e 20 74 31 28 62 29 50 03 06 17 2b 2b   b ON t1(b)P...++
|   3840: 01 59 74 61 62 6c 65 73 71 6c 69 74 65 5f 73 65   .Ytablesqlite_se
|   3856: 71 75 65 6e 63 65 73 71 6c 69 74 65 5f 73 65 71   quencesqlite_seq
|   3872: 75 65 6e 63 65 04 43 52 45 41 54 45 20 54 41 42   uence.CREATE TAB
|   3888: 4c 45 20 73 71 6c 69 74 65 5f 73 65 71 75 65 6e   LE sqlite_sequen
|   3904: 63 65 28 6e 61 6d 65 2c 73 65 71 29 81 04 01 07   ce(name,seq)....
|   3920: 17 11 11 01 81 73 74 61 62 6c 65 74 31 74 31 02   .....stablet1t1.
|   3920: 17 11 11 01 81 73 74 61 c2 6c 65 74 31 74 31 02   .....sta.let1t1.
|   3936: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 28   CREATE TABLE t1(
|   3952: 61 20 52 45 41 4c 20 4e 4f 54 20 4e 55 4c 4c 20   a REAL NOT NULL 
|   3968: 44 45 46 41 55 4c 54 28 32 35 2b 33 32 29 2c 62   DEFAULT(25+32),b
|   3984: 20 46 4c 4f 41 54 2c 63 20 44 4f 55 42 4c 45 20    FLOAT,c DOUBLE 
|   4000: 55 4e 49 51 55 45 2c 0a 64 20 43 4c 4f 42 2c 65   UNIQUE,.d CLOB,e
|   4016: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59    INTEGER PRIMARY
|   4032: 20 4b 45 59 20 41 55 54 4f 49 4e 43 52 45 4d 45    KEY AUTOINCREME
834
835
836
837
838
839
840
841
842
843
844

845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
829
830
831
832
833
834
835




836
837

838

























839


















































































































































































































































































































































































































































































840
841







-
-
-
-
+

-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


|    480: 00 00 ff ff ff 00 00 00 5f 00 fb 00 00 2d 00 00   ........_....-..
|    496: 00 00 00 1e 00 00 00 fe 00 00 64 00 00 ff fb 02   ..........d.....
| page 4 offset 1536
|      0: 0d 00 39 00 00 02 00 00 00 00 00 00 00 00 00 00   ..9.............
| end a.db
}]} {}

set res {1 {database disk image is malformed}}
ifcapable oversize_cell_check {
  set res {1 {no such table: t3}}
}

do_catchsql_test 8.1 {
  PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
  INSERT INTO t3 SELECT * FROM t2;
} $res

#-------------------------------------------------------------------------
reset_db
do_test 9.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename crash-ab10597e4e1c32.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 00 00 00 01 0f d6 00 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 28 01 06 17 11 11 01 3d 74 61   ......(......=ta
|   4064: 62 6c 65 74 31 74 31 02 43 52 45 41 54 45 20 54   blet1t1.CREATE T
|   4080: 41 42 4c 45 20 74 31 28 61 2c 62 2c 63 2c 64 29   ABLE t1(a,b,c,d)
| page 2 offset 4096
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
| end crash-ab10597e4e1c32.db
}]} {}

do_execsql_test 9.1 {
  SAVEPOINT one;
}
do_catchsql_test 9.3 {
  INSERT INTO t1(b,c) VALUES(5,6);
} {1 {database disk image is malformed}}
do_execsql_test 9.3 {
  ROLLBACK TO one;
}

#-------------------------------------------------------------------------
reset_db
do_test 10.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 180224 pagesize 4096 filename crash-41390d95d613b6.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 00 00 00 04 0e e2 00 0f 96 0f 44   ...............D
|    112: 0f 10 0e e2 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3808: 00 00 2c 14 06 17 15 11 01 41 69 6e 64 65 78 74   ..,......Aindext
|   3824: 41 78 33 74 31 06 43 52 45 41 54 45 20 49 4e 44   Ax3t1.CREATE IND
|   3840: 45 58 20 74 31 78 32 20 4f 4e 20 74 31 28 62 29   EX t1x2 ON t1(b)
|   3856: 32 03 06 17 15 11 01 4d 69 6e 64 65 78 74 31 88   2......Mindext1.
|   3872: 31 74 31 05 43 52 45 41 54 45 20 49 4e 44 45 58   1t1.CREATE INDEX
|   3888: 20 74 31 78 31 20 4f 4e 20 74 31 28 67 2b 68 2c    t1x1 ON t1(g+h,
|   3904: 6a 2d 6b 29 50 02 06 17 2b 2b 01 59 74 61 62 6c   j-k)P...++.Ytabl
|   3920: 65 73 71 6c 69 74 65 5e 73 65 71 74 65 6e 63 65   esqlite^seqtence
|   3936: 73 71 6c 69 74 65 5f 73 65 71 75 65 6e 63 65 04   sqlite_sequence.
|   3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c   CREATE TABLE sql
|   3968: 69 74 65 5f 73 65 71 75 65 6e 63 65 28 6e 61 6d   ite_sequence(nam
|   3984: 65 2c 73 65 71 29 68 00 07 17 11 11 01 81 3b 74   e,seq)h.......;t
|   4000: 61 62 6c 65 74 31 74 31 03 43 52 45 41 54 45 20   ablet1t1.CREATE 
|   4016: 54 41 42 4c 45 20 74 31 28 61 20 49 4e 54 45 47   TABLE t1(a INTEG
|   4032: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 20 41   ER PRIMARY KEY A
|   4048: 55 54 4f 49 4e 43 52 45 4d 45 4e 54 2c 0a 62 2c   UTOINCREMENT,.b,
|   4064: 63 2c 64 2c 65 2c 66 2c 67 2c 68 2c 6a 2c 6b 2c   c,d,e,f,g,h,j,k,
|   4080: 6c 2c 6d 2c 6e 2c 6f 2c 70 2c 71 2c 72 2c 73 29   l,m,n,o,p,q,r,s)
| page 2 offset 4096
|      0: 01 00 00 00 00 01 00 00 10 00 01 00 00 00 00 01   ................
|     16: 00 00 00 00 02 00 0f f0 00 15 00 00 00 03 02 00   ................
|     32: 00 00 d9 05 00 00 00 03 02 00 00 00 00 05 00 00   ................
|     48: 10 03 02 00 00 00 00 05 00 00 00 03 02 00 00 00   ................
|     64: 00 05 00 00 00 02 62 00 00 00 00 05 00 00 00 03   ......b.........
|     80: 02 00 00 00 00 05 00 00 00 03 02 00 00 00 00 05   ................
|     96: 00 00 00 03 02 00 00 00 00 05 00 00 00 03 05 00   ................
|    112: 00 00 03 03 01 00 00 23 02 00 00 4f 00 02 00 00   .......#...O....
|    128: 10 25 02 00 00 00 00 03 00 00 00 23 02 00 00 00   .%.........#....
|    144: 00 03 00 00 00 23 02 00 00 00 00 03 00 00 00 23   .....#.........#
|    160: 05 00 08 90 06 05 00 00 00 06 01 ff 00 00 00 03   ................
|    176: 00 00 00 06 02 00 00 00 00 02 ff 00 00 00 00 00   ................
| page 3 offset 8192
|      0: 05 00 00 00 09 0f d0 00 00 00 00 19 0f fb 0f f6   ................
|     16: 0f f1 10 ec ec e7 0f e2 0f dc 0f d6 0f 00 00 00   ................
|   1072: 00 97 4c 0a 24 00 ae 00 00 00 00 00 00 00 00 00   ..L.$...........
|   4048: 00 00 00 16 83 39 ff ff ff 14 81 16 00 00 00 12   .....9..........
|   4064: 81 02 00 00 00 10 6e 00 00 00 0e 5a 00 00 00 0c   ......n....Z....
|   4080: 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   F...............
| page 4 offset 12288
|   1072: 97 4d 32 14 00 ae 00 00 00 00 00 00 00 00 00 00   .M2.............
|   4080: 00 00 00 00 00 00 00 07 01 03 11 02 74 31 00 bd   ............t1..
| page 5 offset 16384
|      0: fa 0f 7c 00 0a 0f 74 00 0f f9 0f eb 0f dd 0f cf   ..|...t.........
|     16: 0f c1 0f b3 0f a4 0e 94 0f 84 0f 74 0f 74 0f 74   ...........t.t.t
|     32: 0f 74 0f 64 0f 00 00 00 00 00 00 00 00 00 00 00   .t.d............
|   3952: 00 00 00 00 07 05 00 00 00 02 00 be 0f 8c 10 07   ................
|   3968: ff ff 00 00 07 05 00 00 00 02 00 aa 0f 9b f0 08   ................
|   3984: c8 00 00 00 37 06 00 00 00 01 00 96 0f ac 00 08   ....7...........
|   4000: 00 00 00 b3 07 15 00 10 00 02 00 82 0f ba 00 07   ................
|   4016: 00 00 00 06 05 00 00 00 01 6e 0f c8 00 07 00 00   .........n......
|   4032: 00 06 05 00 00 00 01 5a 03 f6 00 07 00 00 00 06   .......Z........
|   4048: 05 00 00 00 01 46 0f e4 00 07 00 00 10 06 05 00   .....F..........
|   4064: 00 00 01 32 10 02 00 07 00 00 00 07 05 00 00 00   ...2............
|   4080: 01 1d ff ff ff 07 10 00 00 06 05 00 00 00 01 0a   ................
| page 6 offset 20480
|    624: 00 00 00 00 00 21 97 00 00 00 00 00 00 00 00 00   .....!..........
|   1120: 00 00 00 00 00 24 57 3e 00 00 00 00 00 00 00 00   .....$W>........
|   1616: 00 00 00 00 1f 97 00 00 00 00 00 00 00 00 00 00   ................
|   2112: 00 00 00 1e 97 3d 00 00 00 00 00 00 00 00 00 00   .....=..........
|   2608: 00 1d 97 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
| page 8 offset 28672
|   1184: 00 00 00 00 00 00 00 00 00 97 4d 1e 13 ff ae 7c   ..........M....|
|   4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90   ................
| page 9 offset 32768
|    256: 0d 01 c0 00 01 04 30 00 04 30 00 00 00 00 00 00   ......0..0......
| page 10 offset 36864
|      0: 0d 00 22 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05   ................
| page 12 offset 45056
|      0: 0d 00 00 00 01 04 30 00 00 00 00 00 00 00 00 00   ......0.........
| page 14 offset 53248
|      0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00   ......0..0......
|   1072: 96 4d 5a 14 00 00 00 00 00 00 00 00 00 00 00 00   .MZ.............
| page 16 offset 61440
|      0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00   ......0..0......
|   1072: 97 4d 6e 14 00 ae 7b ff ff ff ff 00 00 00 00 00   .Mn.............
| page 18 offset 69632
|   1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1072: 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   M...............
|   4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d   ................
| page 20 offset 77824
|   1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1072: 4d 81 16 14 00 ae 00 00 00 00 00 00 00 00 00 00   M...............
|   4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f   ................
| page 22 offset 86016
|      0: 0d 00 00 00 01 04 2f 00 04 2f 01 00 00 00 00 00   ....../../......
|   1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1072: 4d 81 2a 14 00 00 00 00 00 00 00 00 00 00 00 00   M.*.............
| page 24 offset 94208
|   1072: 00 97 4c 0a 14 00 ae 7c 00 00 00 00 00 00 00 00   ..L....|........
| page 25 offset 98304
|   1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1072: 4d 81 3e 14 00 ae 7c 00 00 18 ff 00 00 00 00 00   M.>...|.........
| page 27 offset 106496
|      0: 00 00 00 00 00 00 00 12 00 00 00 07 00 00 00 1d   ................
|     16: 00 00 00 09 00 00 00 1f 00 00 00 0b 00 00 00 21   ...............!
|     32: 00 00 00 0d 00 10 00 25 00 00 00 0f 00 00 00 27   .......%.......'
|     48: 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00   ................
| page 32 offset 126976
|   2512: 00 00 00 00 00 00 00 45 21 00 00 00 00 00 00 00   .......E!.......
| page 35 offset 139264
|      0: 00 0a 08 44 00 05 02 77 00 0e 11 0a 92 00 00 00   ...D...w........
|   1120: 00 00 00 00 00 20 97 00 00 00 00 00 00 00 00 00   ..... ..........
|   1616: 00 00 00 00 22 00 00 00 00 00 00 00 00 00 00 00   ................
|   2608: 00 00 00 97 3d 04 00 00 00 00 00 00 00 00 00 00   ....=...........
|   3104: 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3600: 00 97 3d 04 ae 7c 00 00 00 00 00 00 00 00 00 00   ..=..|..........
|   4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a   ................
| page 36 offset 143360
|      0: 0a 08 44 00 04 02 00 00 00 00 00 00 00 00 00 00   ..D.............
|   1120: 00 00 00 00 00 2a 97 3e 04 00 00 00 00 00 00 00   .....*.>........
|   1616: 00 00 00 00 2c 97 3e 00 00 00 00 00 00 00 00 00   ....,.>.........
|   2112: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 38   ...............8
|   2128: 00 00 05 cd 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3600: 00 97 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
| page 38 offset 151552
|   2464: 00 00 00 00 00 00 00 00 00 6e 00 00 00 00 00 00   .........n......
| page 40 offset 159744
|   2512: 00 00 00 00 00 00 00 00 82 00 00 00 00 00 00 00   ................
| page 42 offset 167936
|   2512: 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 00   ................
| page 44 offset 176128
|   2512: 00 00 00 00 00 00 00 00 aa 00 00 00 00 00 00 00   ................
| end crash-41390d95d613b6.db
}]} {}

do_catchsql_test 10.1 {
  PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
  SELECT * FROM t1 WHERE a<='2019-05-09' ORDER BY a DESC;
} {1 {database disk image is malformed}}


#-------------------------------------------------------------------------
reset_db
do_test 11.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 595 pagesize 512 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: 02 00 00 01 00 40 20 20 00 01 00 0c 00 00 00 07   .....@  ........
|     32: 00 00 00 05 07 a1 1f fa 00 00 00 08 00 00 00 04   ................
|     48: 00 00 01 00 00 49 00 00 00 00 00 05 00 00 00 00   .....I..........
|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c   ................
|     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 62 00 00 00 00 00   .V...*....b.....
|    128: 00 ed e2 78 74 64 33 ff 43 52 45 41 54 45 20 49   ...xtd3.CREATE I
|    144: 4e 44 45 58 20 74 33 78 20 4f 4e 20 74 33 28 38   NDEX t3x ON t3(8
|    160: 29 2e 04 06 17 15 11 01 45 69 6e 64 65 68 74 32   ).......Eindeht2
|    176: 63 64 74 31 e5 43 52 45 41 54 45 20 49 4e 44 45   cdt1.CREATE INDE
|    192: 58 20 74 32 63 c4 20 4f 4e 20 74 32 28 63 2c 64   X t2c. ON t2(c,d
|    208: 29 28 05 06 17 01 11 11 3d 74 61 6c 36 74 62 74   )(......=tal6tbt
|    224: 65 32 04 43 52 45 41 54 45 20 54 41 42 4c 45 20   e2.CREATE TABLE 
|    240: 74 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00   t...............
|    256: 00 00 00 00 00 00 22 07 06 17 11 11 01 30 e8 03   .............0..
|    272: 62 6c 65 74 34 74 35 02 43 52 45 41 54 45 20 54   blet4t5.CREATE T
|    288: 41 42 4c 45 20 74 34 28 94 29 2a 06 06 17 13 11   ABLE t4(.)*.....
|    304: 01 3f 69 33 74 6e 65 78 78 74 64 33 ff 43 52 45   .?i3tnexxtd3.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 31 28 38 29 2e 04 06 17 15 11 01 45 69 6e    t1(8).......Ein
|    352: 64 65 68 74 32 63 64 74 31 e5 43 52 45 41 54 45   deht2cdt1.CREATE
|    368: 20 49 4e 44 45 58 20 74 32 63 c4 20 4f 4e 20 74    INDEX t2c. ON t
|    384: 32 28 63 2c 64 29 28 05 06 17 01 11 11 3d 74 61   2(c,d)(......=ta
|    400: 6c 32 74 62 74 65 32 04 43 52 45 41 54 45 20 54   l2tbte2.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 9e 93 65 74 32 74   (......=ta..et2t
|    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 55 61 62 6c 88 74 31 74 31 02 43 52 45 41   .5Uabl.t1t1.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 0d 25 00 01 cf 00 01 fa 01 f3 01 de   .....%..........
|     16: 01 00 00 00 fd 00 00 0d 00 00 00 00 45 20 54 41   ............E TA
|     32: 42 4c 45 20 74 34 28 94 29 2a 06 06 17 13 11 01   BLE t4(.)*......
|     48: 3f 69 33 74 6e 65 78 78 74 64 33 ff 43 52 45 a0   ?i3tnexxtd3.CRE.
|     64: a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 74 13 11 01   ............t...
|     80: 49 45 74 00 00 00 00 00 00 00 00 00 00 00 00 00   IEt.............
| end x.db
}]} {}

do_catchsql_test 11.1 {
  PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
  DELETE FROM t3 WHERE x IN (SELECT x FROM t4);
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 12.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 12288 pagesize 4096 filename crash-e6d070858a3a85.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 00 00 00 02 0f 8f 00 0f bf 0f 8f   ................
|   3968: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2e   ................
|   3984: 02 06 17 15 11 01 45 69 6e 64 65 78 74 31 63 62   ......Eindext1cb
|   4000: 74 31 03 43 52 45 41 54 45 20 49 4e 44 45 58 20   t1.CREATE INDEX 
|   4016: 74 31 63 62 20 4f 4e 20 74 31 28 63 2c 62 29 3f   t1cb ON t1(c,b)?
|   4032: 01 06 17 11 11 01 6b 74 61 62 6c 65 74 31 74 31   ......ktablet1t1
|   4048: 02 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31   .CREATE TABLE t1
|   4064: 28 61 20 49 4e 54 2c 20 62 20 49 4e 54 2c 20 43   (a INT, b INT, C
|   4080: 20 49 4e 54 20 44 45 46 41 55 4c 54 20 31 36 29    INT DEFAULT 16)
| page 2 offset 4096
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4000: 00 00 00 00 00 00 00 00 07 0b 04 01 01 01 63 63   ..............cc
|   4016: 11 05 0a 04 00 00 01 11 05 09 04 08 08 01 0f 05   ................
|   4032: 08 04 00 00 01 01 56 07 04 01 08 01 07 10 07 06   ......V.........
|   4048: 14 01 01 01 06 08 10 06 05 04 f5 00 01 05 10 07   ................
|   4064: 04 04 01 01 01 04 03 10 06 03 04 01 09 01 03 10   ................
|   4080: 06 02 04 01 00 01 02 10 06 01 04 09 01 01 02 10   ................
| page 3 offset 8192
|      0: 0a 00 00 00 0b 0f b0 00 0f f9 0f f2 0f eb 0f e4   ................
|     16: 0f dd 0f d6 0f 9f 0f c7 0f be 00 00 00 00 00 00   ................
|   4016: 07 04 01 01 01 11 e2 0b 06 04 91 00 01 11 0a 07   ................
|   4032: 04 01 01 01 10 08 06 07 04 01 01 01 10 04 04 06   ................
|   4048: 04 01 01 09 10 02 06 04 01 0a 01 10 00 00 00 00   ................
| end crash-e6d070858a3a85.db
}]} {}

do_catchsql_test 12.1 {
  SELECT CAST((SELECT b FROM t1 WHERE 16=c) AS int) FROM t1 WHERE 16=c;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 13.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename crash-81dd2952aef34f.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 02   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04   ................
|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
|     96: 00 00 00 00 0d 00 00 00 01 0f c4 00 0f c4 00 00   ................
|   4032: 00 00 00 00 3a 11 06 17 11 11 01 61 74 61 62 6c   ....:......atabl
|   4048: 65 74 31 74 31 02 43 52 45 41 54 45 20 54 41 42   et1t1.CREATE TAB
|   4064: 4c 45 20 74 31 28 61 20 49 4e 54 45 47 45 52 20   LE t1(a INTEGER 
|   4080: 50 52 49 4d 41 52 59 20 4b 45 59 2c 62 2c 63 29   PRIMARY KEY,b,c)
| page 2 offset 4096
|      0: 0d 07 70 00 02 0f eb 00 0f fa 00 00 00 00 00 00   ..p.............
|   4064: 00 00 00 00 00 00 00 00 00 00 00 05 bf ff ff ff   ................
|   4080: ff ff ff ff ff 04 00 01 00 02 04 01 00 00 00 00   ................
| end crash-81dd2952aef34f.db
}]} {}

do_catchsql_test 13.1 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x-2019 FROM c WHERE x<2)
    INSERT INTO t1(b,c) SELECT last_insert_rowid(), x FROM c;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 14.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 512 pagesize 65536 filename clusterfuzz-testcase-minimized-sqlite3_dbfuzz2_fuzzer-4806406219825152
| 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: 00 01 02 01 00 40 20 20 00 63 2e 78 00 00 00 07   .....@  .c.x....
|     32: 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 04   ................
|     48: 00 00 00 00 00 00 01 00 35 05 43 00 04 00 00 00   ........5.C.....
|     80: 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 0c   ................
|     96: 00 2e 2c 50 0d 00 00 00 03 00 00 00 01 da 01 b0   ..,P............
|    112: 01 56 01 86 01 2a 01 02 00 00 00 00 00 00 00 1c   .V...*..........
|    128: 00 38 80 b2 e6 0e 00 00 00 00 00 00 00 00 00 10   .8..............
|    144: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
|    160: 00 00 00 00 00 00 00 00 00 00 00 00 45 20 54 41   ............E TA
|    256: 00 00 00 00 00 00 22 07 06 17 11 11 01 35 74 61   .............5ta
|    272: 62 6c 00 10 00 00 34 07 43 52 54 45 20 54 41 42   bl....4.CRTE TAB
|    288: 4c 45 20 74 33 28 63 2e 78 2c 65 2c 66 15 28 3a   LE t3(c.x,e,f.(:
|    304: 06 17 11 11 01 65 78 8c cc 87 85 35 05 43 72 45   .....ex....5.CrE
|    320: 41 54 48 20 49 4e 44 45 58 20 74 33 78 20 4f 4e   ATH INDEX t3x ON
|    336: 20 74 33 28 78 39 2e 04 06 17 15 11 01 45 69 6e    t3(x9.......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 2a 44 29 28 05 fa e8 ee ed 01 3d 74 63   2(c*D)(......=tc
|    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 2e 78 2c 65 2c 66 15   ABLE t3(c.x,e,f.
|    432: 28 3a 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 63 29   TE TABLE t1(a,c)
| end clusterfuzz-testcase-minimized-sqlite3_dbfuzz2_fuzzer-4806406219825152
}]} {}

extra_schema_checks 0
do_catchsql_test 14.1 {
  PRAGMA integrity_check;
} {1 {database disk image is malformed}}

do_catchsql_test 14.2 {
  ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s; 
} {1 {database disk image is malformed}}
extra_schema_checks 1

#-------------------------------------------------------------------------
reset_db
do_test 15.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename crash-3afa1ca9e9c1bd.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 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04   ................
|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
|     96: 00 00 00 00 0d 00 00 00 06 0e 88 00 0f b8 0f 6d   ...............m
|    112: 0f 3a 0f 0b 0e d5 0e 88 01 00 00 00 00 00 00 00   .:..............
|   3712: 00 00 00 00 00 00 00 00 4b 06 06 17 25 25 01 5b   ........K...%%.[
|   3728: 74 61 62 6c 65 73 71 6c 69 74 65 5f 73 74 61 74   tablesqlite_stat
|   3744: 31 73 71 6c 69 74 65 5f 73 74 61 74 31 07 43 52   1sqlite_stat1.CR
|   3760: 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c 69 74   EATE TABLE sqlit
|   3776: 65 5f 73 74 61 74 31 28 74 62 6c 2c 69 64 78 2c   e_stat1(tbl,idx,
|   3792: 73 74 61 74 29 34 05 06 17 13 11 01 53 69 6e 64   stat)4......Sind
|   3808: 65 78 63 31 63 63 31 06 43 52 45 41 54 45 20 55   exc1cc1.CREATE U
|   3824: 4e 49 51 55 45 20 49 4e 44 45 58 20 63 31 63 20   NIQUE INDEX c1c 
|   3840: 4f 4e 20 63 31 28 63 2c 20 62 29 2d 04 06 17 13   ON c1(c, b)-....
|   3856: 11 01 45 69 6e 64 65 78 63 31 64 63 31 05 43 52   ..Eindexc1dc1.CR
|   3872: 45 41 54 45 20 49 4e 44 45 58 20 63 31 64 20 4f   EATE INDEX c1d O
|   3888: 4e 20 63 31 28 64 2c 20 62 29 31 03 06 17 13 11   N c1(d, b)1.....
|   3904: 01 4d 69 6e 64 65 78 62 31 63 62 31 05 43 52 45   .Mindexb1cb1.CRE
|   3920: 41 54 45 20 55 4e 49 51 55 45 20 49 4e 44 45 58   ATE UNIQUE INDEX
|   3936: 20 62 31 63 20 4f 4e 20 62 31 28 63 29 49 02 06    b1c ON b1(c)I..
|   3952: 17 11 11 0f 7f 74 61 62 6c 65 63 31 63 31 03 43   .....tablec1c1.C
|   3968: 52 45 41 54 45 20 54 41 42 4c 45 20 63 31 28 61   REATE TABLE c1(a
|   3984: 20 49 4e 54 20 50 52 49 4d 41 52 59 20 4b 45 59    INT PRIMARY KEY
|   4000: 2c 20 62 2c 20 63 2c 20 64 29 20 57 49 54 48 4f   , b, c, d) WITHO
|   4016: 55 54 20 52 4f 57 49 44 46 01 06 17 11 11 01 79   UT ROWIDF......y
|   4032: 74 61 62 6c 65 62 31 62 31 02 43 52 45 41 54 45   tableb1b1.CREATE
|   4048: 20 54 41 42 4c 45 20 62 31 28 61 20 49 4e 54 20    TABLE b1(a INT 
|   4064: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 2c 20   PRIMARY KEY, b, 
|   4080: 63 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44   c) WITHOUT ROWID
| page 2 offset 4096
|      0: 0a 00 00 00 07 0f ca 00 0f fa 0f f2 0f ea 0f e2   ................
|     16: 0f da 00 00 00 01 00 00 00 00 00 00 00 00 00 00   ................
|   4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 06   ................
|   4048: 67 07 07 04 01 0f 01 06 66 06 07 04 01 0f 01 05   g.......f.......
|   4064: 65 05 07 04 01 0f 01 04 64 04 07 04 01 0f 01 03   e.......d.......
|   4080: 63 03 07 04 01 0f 01 02 62 0f 05 04 09 0f 09 61   c.......b......a
| page 3 offset 8192
|      0: 0a 00 00 00 07 0f bd 00 0f f9 0f ef 0f e5 0f db   ................
|     16: 0f d1 0f c7 0f bd 00 00 00 00 01 00 00 00 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 09 05 01   ................
|   4032: 0f 01 01 07 61 07 07 09 05 01 0f 01 01 06 61 06   ....a.........a.
|   4048: 06 09 05 01 0f 01 01 05 61 05 05 09 05 01 0f 01   ........a.......
|   4064: 01 04 61 04 04 09 05 01 0f 01 01 03 61 03 03 09   ..a.........a...
|   4080: 05 01 0f 01 01 02 61 0f 02 06 05 09 0f 09 09 61   ......a........a
| page 4 offset 12288
|      0: 0a 00 00 00 07 0f d8 00 0f fc 0f f0 0f ea 0f e4   ................
|     16: 0f de 0f d8 0f f6 00 00 00 00 00 00 00 00 00 00   ................
|   4048: 00 00 00 00 00 00 00 00 05 03 01 01 07 07 05 03   ................
|   4064: 01 01 06 06 05 03 01 01 05 05 05 03 01 01 04 04   ................
|   4080: 05 03 01 01 03 03 05 03 01 01 0f 02 03 03 09 09   ................
| page 5 offset 16384
|      0: 0a 00 00 00 07 0f ca 00 0f fa 0f f2 0f ea 0f 00   ................
|   4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 07   ................
|   4048: 61 07 07 04 01 0f 01 06 61 06 07 04 01 0f 01 05   a.......a.......
|   4064: 61 05 07 04 01 1f 01 04 61 04 07 04 01 0f 01 03   a.......a.......
|   4080: 61 03 07 04 01 0f 01 02 61 02 05 04 09 0f 09 61   a.......a......a
| page 6 offset 20480
|      0: 0a 00 00 00 07 0f ca 00 0f fa 0f ea 0f e2 00 00   ................
|   4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 07   ................
|   4048: 61 07 07 04 01 0f 01 06 61 06 07 04 01 0f 01 05   a.......a.......
|   4064: 61 05 07 04 01 0f 01 04 61 04 07 04 01 0f 01 03   a.......a.......
|   4080: 61 03 07 04 01 0f 01 0f 61 02 05 04 09 0f 09 61   a.......a......a
| page 7 offset 24576
|      0: 0d 00 00 00 05 0f 1c 00 0f f0 0f e0 0f d3 0f c5   ................
|     16: 0f b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 0b 05 04 11 11 13 62 31   ..............b1
|   4032: 62 31 37 20 31 0c 04 04 11 13 13 62 31 62 31 63   b17 1......b1b1c
|   4048: 37 20 31 0b 03 04 11 11 13 63 31 63 31 37 20 31   7 1......c1c17 1
|   4064: 0e 02 04 11 13 07 63 31 63 31 64 37 20 31 20 31   ......c1c1d7 1 1
|   4080: 0e 01 04 11 13 17 63 31 63 31 63 37 20 31 00 00   ......c1c1c7 1..
| end crash-3afa1ca9e9c1bd.db
}]} {}

extra_schema_checks 0
do_execsql_test 15.1 {
  PRAGMA cell_size_check = 0;
  UPDATE c1 SET c= NOT EXISTS(SELECT 1 FROM c1 ORDER BY (SELECT 1 FROM c1 ORDER BY a)) +10 WHERE d BETWEEN 4 AND 7;
} {}
extra_schema_checks 1

#-------------------------------------------------------------------------
reset_db
do_execsql_test 16.0 {
  CREATE TABLE t1(w, x, y, z, UNIQUE(w, x), UNIQUE(y, z));
  INSERT INTO t1 VALUES(1, 1, 1, 1);

  CREATE TABLE t1idx(x, y, i INTEGER, PRIMARY KEY(x)) WITHOUT ROWID;
  INSERT INTO t1idx VALUES(10, NULL, 5);

  PRAGMA writable_schema = 1;
  UPDATE sqlite_master SET rootpage = (
    SELECT rootpage FROM sqlite_master WHERE name='t1idx'
  ) WHERE type = 'index';
}

extra_schema_checks 0
db close
sqlite3 db test.db
extra_schema_checks 1

do_catchsql_test 16.1 {
  PRAGMA writable_schema = ON;
  INSERT INTO t1(rowid, w, x, y, z) VALUES(5, 10, 11, 10, NULL);
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
# Test that corruption is reported from within a checkpoint if the 
# expected final size of the database (according to the last commit
# frame in the wal file) is greater than the combined initial sizes 
# of the database and wal file.
#
if {[wal_is_capable]} {
  reset_db
  do_execsql_test 17.0 {
    CREATE TABLE t1(o INTEGER PRIMARY KEY, t UNIQUE);
    INSERT INTO t1(t) VALUES(randomblob(123));
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
    INSERT INTO t1(t) SELECT randomblob(123) FROM t1;
  
    PRAGMA journal_mode = wal;
    INSERT INTO t1 VALUES(-1, 'b');
  } {wal}
  
  do_test 17.1 {
    set fd [open test.db r+]
    chan truncate $fd 2048
    file size test.db
  } {2048}
  
  do_catchsql_test 17.2 {
    PRAGMA wal_checkpoint
  } {1 {database disk image is malformed}}
  
  do_test 17.3 {
    close $fd
  } {}
}


finish_test

Deleted test/corruptM.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


























































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-08-12
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Check to ensure that the type, name, and tbl_name fields of the
# sqlite_master table are validated and errors are reported if they
# are inconsistent with the sql.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corruptM

# These tests deal with corrupt database files
#
database_may_be_corrupt

proc open_db2_and_catchsql {sql} {
  set rc [catch { sqlite3 db2 test.db } msg]
  if {$rc} {
    return [list $rc $msg]
  }
  set res [catchsql $sql db2]
  db2 close
  set res
}

db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test corruptM-100 {
  CREATE TABLE t1(a,b,c);
  INSERT INTO t1 VALUES(111,222,333);
  CREATE INDEX i1 ON t1(b);
  CREATE VIEW v2 AS SELECT 15,22;
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN SELECT 5; END;
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_execsql_test corruptM-101 {
  PRAGMA writable_schema=on;
  UPDATE sqlite_master SET tbl_name=NULL WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 {} | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_test corruptM-102 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
  }
} {1 {malformed database schema (t1)}}

do_execsql_test corruptM-110 {
  UPDATE sqlite_master SET tbl_name='tx' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 tx | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_test corruptM-111 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
  }
} {1 {malformed database schema (t1)}}
do_execsql_test corruptM-112 {
  UPDATE sqlite_master SET tbl_name='t1', type='tabl' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {tabl t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_test corruptM-113 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
  }
} {1 {malformed database schema (t1)}}
do_execsql_test corruptM-114 {
  UPDATE sqlite_master SET tbl_name='t9',type='table',name='t9'WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t9 t9 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_test corruptM-114 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
  }
} {1 {malformed database schema (t9)}}

do_execsql_test corruptM-120 {
  UPDATE sqlite_master SET name='t1',tbl_name='T1' WHERE name='t9';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_test corruptM-121 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } 
} {0 {ok 111 222 333 15 22}}

do_execsql_test corruptM-130 {
  UPDATE sqlite_master SET type='view' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {view t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_test corruptM-131 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  }
} {1 {malformed database schema (t1)}}

do_execsql_test corruptM-140 {
  UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='t1';
  UPDATE sqlite_master SET tbl_name='tx' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 tx | view v2 v2 | trigger r1 t1 |}
do_test corruptM-141 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  }
} {1 {malformed database schema (i1)}}

do_execsql_test corruptM-150 {
  UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | table i1 t1 | view v2 v2 | trigger r1 t1 |}
do_test corruptM-151 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  }
} {1 {malformed database schema (i1)}}

do_execsql_test corruptM-160 {
  UPDATE sqlite_master SET type='view', tbl_name='t1' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | view i1 t1 | view v2 v2 | trigger r1 t1 |}
do_test corruptM-161 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  }
} {1 {malformed database schema (i1)}}

do_execsql_test corruptM-170 {
  UPDATE sqlite_master SET type='index', tbl_name='t1' WHERE name='i1';
  UPDATE sqlite_master SET type='table', tbl_name='v2' WHERE name='v2';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | table v2 v2 | trigger r1 t1 |}
do_test corruptM-171 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  }
} {1 {malformed database schema (v2)}}

do_execsql_test corruptM-180 {
  UPDATE sqlite_master SET type='view',name='v3',tbl_name='v3' WHERE name='v2';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v3 v3 | trigger r1 t1 |}
do_test corruptM-181 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  }
} {1 {malformed database schema (v3)}}

do_execsql_test corruptM-190 {
  UPDATE sqlite_master SET type='view',name='v2',tbl_name='v2' WHERE name='v3';
  UPDATE sqlite_master SET type='view' WHERE name='r1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | view r1 t1 |}
do_test corruptM-191 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  }
} {1 {malformed database schema (r1)}}
do_execsql_test corruptM-192 {
  UPDATE sqlite_master SET type='trigger',tbl_name='v2' WHERE name='r1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 v2 |}
do_test corruptM-193 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  }
} {1 {malformed database schema (r1)}}

finish_test

Deleted 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/cost.test.

226
227
228
229
230
231
232
233

234
235
236

237
238
239
240
241
242
243
226
227
228
229
230
231
232

233
234
235

236
237
238
239
240
241
242
243







-
+


-
+







    CREATE INDEX i2 ON t1(a,b,c,d,e,f,g,h,i,j);
  }
} {}

set L [list a=? b=? c=? d=? e=? f=? g=? h=? i=? j=?]
foreach {tn nTerm nRow} {
  1   1 10
  2   2 10
  2   2  9
  3   3  8
  4   4  7
  5   5  7
  5   5  6
  6   6  5
  7   7  5
  8   8  5
  9   9  5
  10 10  5
} {
  set w [join [lrange $L 0 [expr $nTerm-1]] " AND "]

Changes to test/count.test.

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
191
192
193
194
195
196
197






































198
199







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  SELECT count(*) FROM t5;
} {1}

do_catchsql_test count-6.1 {
  CREATE TABLE t6(x);
  SELECT count(DISTINCT) FROM t6 GROUP BY x;
} {1 {DISTINCT aggregates must have exactly one argument}}

# 2020-05-08.
# The count() optimization should honor the NOT INDEXED clause
#
reset_db
do_execsql_test count-7.1 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c VARCHAR(1000));
  CREATE INDEX t1b ON t1(b);
  INSERT INTO t1(a,b,c) values(1,2,'count.test cases for NOT INDEXED');
  ANALYZE;
  UPDATE sqlite_stat1 SET stat='1000000 10' WHERE idx='t1b';
  ANALYZE sqlite_master;
}
do_eqp_test count-7.2 {
  SELECT count(1) FROM t1;
} {
  QUERY PLAN
  `--SCAN TABLE t1 USING COVERING INDEX t1b
}
do_eqp_test count-7.3 {
  SELECT count(1) FROM t1 NOT INDEXED
} {
  QUERY PLAN
  `--SCAN TABLE t1
}
do_eqp_test count-7.3 {
  SELECT count(*) FROM t1;
} {
  QUERY PLAN
  `--SCAN TABLE t1 USING COVERING INDEX t1b
}
do_eqp_test count-7.4 {
  SELECT count(*) FROM t1 NOT INDEXED
} {
  QUERY PLAN
  `--SCAN TABLE t1
}


finish_test

Changes to test/countofview.test.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
35
36
37
38
39
40
41













42
43







-
-
-
-
-
-
-
-
-
-
-
-
-


} {1}

do_execsql_test 1.3 {
  select count(*) from (
    select c from t2 union all select f from t3
  )
} {3}

# 2019-05-15
do_execsql_test 2.0 {
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(1),(99),('abc');
  CREATE VIEW v1(x,y) AS SELECT x,1 FROM t1 UNION ALL SELECT x,2 FROM t1;
  SELECT count(*) FROM v1 WHERE x<>1;
} {4}
do_execsql_test 2.1 {
  SELECT count(*) FROM v1 GROUP BY y;
} {3 3}



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
101
102
103
104
105
106
107
108
109



























110
111
112
113
114
115
116
117
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_ENABLE_MEMORY_MANAGEMENT..."
   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 1} {$jj < 100} {incr jj} {
  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] {
        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"
        catch {db eval { CREATE UNIQUE INDEX i1 ON t1(a); }} msg
        # puts "$n $msg ac=[sqlite3_get_autocommit db]"
#       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
        # 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/cse.test.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
14
15
16
17
18
19
20

21
22
23
24
25
26
27







-







# common subexpression eliminations.
#
# $Id: cse.test,v 1.6 2008/08/04 03:51:24 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix cse

do_test cse-1.1 {
  execsql {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e, f);
    INSERT INTO t1 VALUES(1,11,12,13,14,15);
    INSERT INTO t1 VALUES(2,21,22,23,24,25);
  }
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
153
154
155
156
157
158
159







































160







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  set sql "SELECT [join $colset ,] FROM t2"
  do_test cse-2.2.$i {
    # explain $::sql
    execsql $::sql
  } $answer
}

#-------------------------------------------------------------------------
# Ticket fd1bda016d1a
#
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t1(a TEXT, b);
  INSERT INTO t1 VALUES('hello', 0);
  INSERT INTO t1 VALUES('world', 0);

  CREATE TABLE t2(x TEXT);
  INSERT INTO t2 VALUES('hello');
  INSERT INTO t2 VALUES('world');

  CREATE TABLE t3(y);
  INSERT INTO t3 VALUES(1000);
} {}

do_execsql_test 3.1 {
  SELECT 1000 = y FROM t3
} {1}

do_execsql_test 3.2 {
  SELECT 1000 IN (SELECT x FROM t2), 1000 = y FROM t3
} {0 1}

do_execsql_test 3.3 {
  SELECT 0 IN (SELECT a), (SELECT a LIMIT 0) FROM t1 
} {0 {} 0 {}}

do_execsql_test 3.4 {
  SELECT 0 IN (SELECT a) FROM t1 WHERE a = 'hello' OR (SELECT a LIMIT 0);
} {0}

do_execsql_test 3.5 {
  CREATE TABLE v0(v1 VARCHAR0);
  INSERT INTO v0 VALUES(2), (3);
  SELECT 0 IN(SELECT v1) FROM v0 WHERE v1 = 2 OR(SELECT v1 LIMIT 0);
} {0}

finish_test

Changes to test/cursorhint.test.

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
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







-
+












-
+







     SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
  }
} {{EQ(r[1],c0)}}
do_test 1.2 {
  p5_of_opcode db OpenRead {
     SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
  }
} {0 0}
} {00 00}

# Do the same test the other way around.
#
do_test 2.1 {
  p4_of_opcode db CursorHint {
     SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
  }
} {{EQ(c0,r[1])}}
do_test 2.2 {
  p5_of_opcode db OpenRead {
     SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
  }
} {0 0}
} {00 00}

# Various expressions captured by CursorHint
#
do_test 3.1 {
  p4_of_opcode db CursorHint {
    SELECT * FROM t1 WHERE a=15 AND c=22 AND rowid!=98
  }
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
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







-
+














-
+







    SELECT * FROM t1 WHERE b>11 ORDER BY b DESC;
  }
} {GT(c0,11)}
do_test 4.2 {
  p5_of_opcode db OpenRead {
    SELECT * FROM t1 WHERE b>11;
  }
} {2 0}
} {02 00}
do_test 4.3asc {
  p4_of_opcode db CursorHint {
    SELECT c FROM t1 WHERE b<11 ORDER BY b ASC;
  }
} {LT(c0,11)}
do_test 4.3desc {
  p4_of_opcode db CursorHint {
    SELECT c FROM t1 WHERE b<11 ORDER BY b DESC;
  }
} {}
do_test 4.4 {
  p5_of_opcode db OpenRead {
    SELECT c FROM t1 WHERE b<11;
  }
} {0}
} {00}

do_test 4.5asc {
  p4_of_opcode db CursorHint {
    SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b ASC;
  }
} {LE(c0,20)}
do_test 4.5desc {

Changes to test/date2.test.

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
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







-
+





-
+
-
-
-
-
-
-
-








-
+












-
+








do_execsql_test date2-100 {
  CREATE TABLE t1(x, y, CHECK( date(x) BETWEEN '2017-07-01' AND '2017-07-31' ));
  INSERT INTO t1(x,y) VALUES('2017-07-20','one');
} {}
do_catchsql_test date2-110 {
  INSERT INTO t1(x,y) VALUES('now','two');
} {1 {non-deterministic use of date() in a CHECK constraint}}
} {1 {non-deterministic function in index expression or CHECK constraint}}
do_execsql_test date2-120 {
  SELECT * FROM t1;
} {2017-07-20 one}
do_catchsql_test date2-130 {
  INSERT INTO t1(x,y) VALUES('2017-08-01','two');
} {1 {CHECK constraint failed: date(x) BETWEEN '2017-07-01' AND '2017-07-31'}}
} {1 {CHECK constraint failed: t1}}

# 2021-03-16 Forum post https://sqlite.org/forum/forumpost/464afd4086
do_catchsql_test date2-140 {
  DROP TABLE t1;
  CREATE TABLE t1(x, y, z AS (date()));
  INSERT INTO t1(x,y) VALUES(1,2);
} {1 {non-deterministic use of date() in a generated column}}

do_execsql_test date2-200 {
  CREATE TABLE t2(x,y);
  INSERT INTO t2(x,y) VALUES(1, '2017-07-20'), (2, 'xyzzy');
  CREATE INDEX t2y ON t2(date(y));
}
do_catchsql_test date2-210 {
  INSERT INTO t2(x,y) VALUES(3, 'now');
} {1 {non-deterministic use of date() in an index}}
} {1 {non-deterministic function in index expression or CHECK constraint}}
do_execsql_test date2-220 {
  SELECT x, y FROM t2 ORDER BY x;
} {1 2017-07-20 2 xyzzy}

do_execsql_test date2-300 {
  CREATE TABLE t3(a INTEGER PRIMARY KEY,b);
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
    INSERT INTO t3(a,b) SELECT x, julianday('2017-07-01')+x FROM c;
  UPDATE t3 SET b='now' WHERE a=500;
}
do_catchsql_test date2-310 {
  CREATE INDEX t3b1 ON t3(datetime(b));
} {1 {non-deterministic use of datetime() in an index}}
} {1 {non-deterministic function in index expression or CHECK constraint}}
do_catchsql_test date2-320 {
  CREATE INDEX t3b1 ON t3(datetime(b)) WHERE typeof(b)='real';
} {0 {}}
do_execsql_test date2-330 {
  EXPLAIN QUERY PLAN
  SELECT a FROM t3
   WHERE typeof(b)='real'
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102







-
+







-
+







  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
    INSERT INTO t4(a,b) SELECT x, julianday('2017-07-01')+x FROM c;
  UPDATE t4 SET b='now' WHERE a=500;
}
do_catchsql_test date2-410 {
  CREATE INDEX t4b1 ON t4(b)
    WHERE date(b) BETWEEN '2017-06-01' AND '2017-08-31';
} {1 {non-deterministic use of date() in an index}}
} {1 {non-deterministic function in index expression or CHECK constraint}}
do_execsql_test date2-420 {
  DELETE FROM t4 WHERE a=500;
  CREATE INDEX t4b1 ON t4(b)
    WHERE date(b) BETWEEN '2017-06-01' AND '2017-08-31';
}
do_catchsql_test date2-430 {
  INSERT INTO t4(a,b) VALUES(9999,'now');
} {1 {non-deterministic use of date() in an index}}
} {1 {non-deterministic function in index expression or CHECK constraint}}

do_execsql_test date2-500 {
  CREATE TABLE mods(x);
  INSERT INTO mods(x) VALUES
    ('+10 days'),
    ('-10 days'),
    ('+10 hours'),
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
117
118
119
120
121
122
123

124
125
126

127
128


129

















130

131













132




133
134







-
+


-
+

-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-


  CREATE TABLE t5(y,m);
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
    INSERT INTO t5(y,m) SELECT julianday('2017-07-01')+c.x, mods.x FROM c, mods;
  CREATE INDEX t5x1 on t5(y) WHERE datetime(y,m) IS NOT NULL;
}
do_catchsql_test date2-510 {
  INSERT INTO t5(y,m) VALUES('2017-07-20','localtime');
} {1 {non-deterministic use of datetime() in an index}}
} {1 {non-deterministic function in index expression or CHECK constraint}}
do_catchsql_test date2-520 {
  INSERT INTO t5(y,m) VALUES('2017-07-20','utc');
} {1 {non-deterministic use of datetime() in an index}}
} {1 {non-deterministic function in index expression or CHECK constraint}}

# 2019-10-30 Ticket 830277d9db6c3ba1
#

do_catchsql_test date2-600 {
  CREATE TABLE t600(a REAL CHECK( a<julianday('now') ));
  INSERT INTO t600(a) VALUES(1.0);
} {1 {non-deterministic use of julianday() in a CHECK constraint}}
do_catchsql_test date2-601 {
  CREATE TABLE t601(a REAL, b TEXT, CHECK( a<julianday(b) ));
  INSERT INTO t601(a,b) VALUES(1.0, '1970-01-01');
} {0 {}}
do_catchsql_test date2-602 {
  INSERT INTO t601(a,b) VALUES(1e100, '1970-01-01');
} {1 {CHECK constraint failed: a<julianday(b)}}
do_catchsql_test date2-603 {
  INSERT INTO t601(a,b) VALUES(10, 'now');
} {1 {non-deterministic use of julianday() in a CHECK constraint}}
do_catchsql_test date2-604 {
  INSERT INTO t600(a) VALUES(julianday('now')+10);
} {1 {non-deterministic use of julianday() in a CHECK constraint}}


  
do_catchsql_test date2-610 {
  CREATE TABLE t610(a,b);
  CREATE INDEX t610x1 ON t610(julianday('now')+b);
  INSERT INTO t610(a,b) VALUES(123,456);
} {1 {non-deterministic use of julianday() in an index}}
do_catchsql_test date2-611 {
  CREATE TABLE t611(a,b);
  CREATE INDEX t611x1 ON t611(julianday(a)+b);
  INSERT INTO t611(a,b) VALUES('1970-01-01',10.0);
} {0 {}}
do_catchsql_test date2-612 {
  INSERT INTO t611(a,b) VALUES('now',10.0);
} {1 {non-deterministic use of julianday() in an index}}

do_catchsql_test date3-620 {
  CREATE TABLE t620(a, b AS (a+julianday('now')));
  INSERT INTO t620 VALUES(10);
} {1 {non-deterministic use of julianday() in a generated column}}

finish_test

Deleted test/dbdata.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



















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-04-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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite_dbpage virtual table.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix dbdata

ifcapable !vtab||!compound {
  finish_test
  return
}
if { [catch { db enable_load_extension 1 }]
  || [catch { db eval { SELECT load_extension('../dbdata') } }] 
} {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE T1(a, b);
  INSERT INTO t1(rowid, a ,b) VALUES(5, 'v', 'five');
  INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
}

do_execsql_test 1.1 {
  SELECT pgno, cell, field, quote(value) FROM sqlite_dbdata WHERE pgno=2;
} {
  2 0 -1 5 
  2 0  0 'v' 
  2 0  1 'five' 
  2 1 -1 10 
  2 1  0 'x' 
  2 1  1 'ten'
}

breakpoint
do_execsql_test 1.2 {
  SELECT pgno, cell, field, quote(value) FROM sqlite_dbdata;
} {
  1 0 -1 1 
  1 0 0 'table' 
  1 0 1 'T1' 
  1 0 2 'T1' 
  1 0 3 2 
  1 0 4 {'CREATE TABLE T1(a, b)'}
  2 0 -1 5 
  2 0  0 'v' 
  2 0  1 'five' 
  2 1 -1 10 
  2 1  0 'x' 
  2 1  1 'ten'
}

set big [string repeat big 2000]
do_execsql_test 1.3 {
  INSERT INTO t1 VALUES(NULL, $big);
  SELECT value FROM sqlite_dbdata WHERE pgno=2 AND cell=2 AND field=1;
} $big

do_execsql_test 1.4 {
  DELETE FROM t1;
  INSERT INTO t1 VALUES(NULL, randomblob(5050));
}
do_test 1.5 {
  execsql {
    SELECT quote(value) FROM sqlite_dbdata WHERE pgno=2 AND cell=0 AND field=1;
  }
} [db one {SELECT quote(b) FROM t1}]

#-------------------------------------------------------------------------
reset_db
db enable_load_extension 1
db eval { SELECT load_extension('../dbdata') }

do_execsql_test 2.0 {
  CREATE TABLE t1(a);
  CREATE INDEX i1 ON t1(a);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10
  )
  INSERT INTO t1 SELECT randomblob(900) FROM s;
}

do_execsql_test 2.1 {
  SELECT * FROM sqlite_dbptr WHERE pgno=2;
} {
  2 25   2 6   2 7   2 9   2 11   2 13   2 15   2 17   2 19   2 21
}

do_execsql_test 2.2 {
  SELECT * FROM sqlite_dbptr WHERE pgno=3;
} {
  3 24   3 23
}

do_execsql_test 2.3 {
  SELECT * FROM sqlite_dbptr
} {
  2 25   2 6   2 7   2 9   2 11   2 13   2 15   2 17   2 19   2 21
  3 24   3 23
}


finish_test

Changes to test/dbfuzz001.test.

301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315







-
+







|    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
|    432: 28 02 06 17 11 11 01 3d 74 61 74 65 6c 03 62 74   (......=tatel.bt
|    448: 32 32 43 52 45 41 54 45 20 54 41 42 4c 45 20 74   22CREATE 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 cf 00 01 fa 01 f3 01 de 01 cf   ................
|    160: 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00   .. .............
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
357
358
359
360
361
362
363

364
365
366
367
368
369
370

371
372







-







-


|    464: 69 67 68 74 0a 06 02 07 40 18 00 00 00 00 00 00   ight....@.......
|    480: 0a 05 02 07 40 18 00 00 00 00 00 00 03 04 02 01   ....@...........
|    496: 04 03 03 02 01 04 03 02 02 01 02 03 01 02 01 02   ................
| end x/c02.db
  }]
} {}

extra_schema_checks 0
do_catchsql_test dbfuzz001-320 {
  PRAGMA integrity_check;
} {1 {database disk image is malformed}}

do_catchsql_test dbfuzz001-330 {
  DELETE FROM t3 WHERE x IN (SELECT x FROM t4);
} {1 {database disk image is malformed}}
extra_schema_checks 1

finish_test

Changes to test/dbfuzz2.c.

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64







-
+







#include "sqlite3.h"

/*
** This is the is the SQL that is run against the database.
*/
static const char *azSql[] = {
  "PRAGMA integrity_check;",
  "SELECT * FROM sqlite_schema;",
  "SELECT * FROM sqlite_master;",
  "SELECT sum(length(name)) FROM dbstat;",
  "UPDATE t1 SET b=a, a=b WHERE a<b;",
  "ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s;",
  "INSERT INTO t3 SELECT * FROM t2;",
  "DELETE FROM t3 WHERE x IN (SELECT x FROM t4);",
  "REINDEX;",
  "DROP TABLE t3;",
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
207
208
209
210
211
212
213



214
215
216
217
218
219
220







-
-
-







#endif
  if( bVdbeDebug ){
    sqlite3_exec(db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
  }
  if( mxCb>0 ){
    sqlite3_progress_handler(db, 10, progress_handler, 0);
  }
#ifdef SQLITE_TESTCTRL_PRNG_SEED
  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1, db);
#endif
  for(i=0; i<sizeof(azSql)/sizeof(azSql[0]); i++){
    if( eVerbosity>=1 ){
      printf("%s\n", azSql[i]);
      fflush(stdout);
    }
    zErr = 0;
    nCb = 0;
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
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







+
+
+
+









-
-
-
-
-
-
-
-
-
-
-
-







        }
        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;
      }
      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;
        int resource = RLIMIT_STACK;
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387

388
389
390







-








-



    int nIn;
    pIn = readFile(argv[i], &nIn);
    if( pIn ){
      LLVMFuzzerTestOneInput((const uint8_t*)pIn, (size_t)nIn);
      free(pIn);
    }
  }
#ifdef RUSAGE_SELF
  if( eVerbosity>0 ){
    struct rusage x;
    printf("SQLite %s\n", sqlite3_sourceid());
    memset(&x, 0, sizeof(x));
    if( getrusage(RUSAGE_SELF, &x)==0 ){
      printf("Maximum RSS = %ld KB\n", x.ru_maxrss);
    }
  }
#endif
  return 0;
}
#endif /*STANDALONE*/

Changes to test/dbstatus.test.

59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73







-
+








proc lookaside {db} {
  expr { $::lookaside_buffer_size *
    [lindex [sqlite3_db_status $db SQLITE_DBSTATUS_LOOKASIDE_USED 0] 1]
  }
}

ifcapable stat4 {
ifcapable stat4||stat3 {
  set STAT3 1
} else {
  set STAT3 0
}

#---------------------------------------------------------------------------
# Run the dbstatus-2 and dbstatus-3 tests with several of different

Deleted test/decimal.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


























































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2017 December 9
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix decimal

if {[catch {load_static_extension db decimal} error]} {
  puts "Skipping decimal tests, hit load error: $error"
  finish_test; return
}

do_execsql_test 1000 {
  SELECT decimal(1);
} {1}
do_execsql_test 1010 {
  SELECT decimal(1.0);
} {1.0}
do_execsql_test 1020 {
  SELECT decimal(0001.0);
} {1.0}
do_execsql_test 1030 {
  SELECT decimal(+0001.0);
} {1.0}
do_execsql_test 1040 {
  SELECT decimal(-0001.0);
} {-1.0}
do_execsql_test 1050 {
  SELECT decimal(1.0e72);
} {1000000000000000000000000000000000000000000000000000000000000000000000000}
#   123456789 123456789 123456789 123456789 123456789 123456789 123456789 123
do_execsql_test 1060 {
  SELECT decimal(1.0e-72);
} {0.0000000000000000000000000000000000000000000000000000000000000000000000010}
#    123456789 123456789 123456789 123456789 123456789 123456789 123456789 123
do_execsql_test 1070 {
  SELECT decimal(-123e-4);
} {-0.0123}
do_execsql_test 1080 {
  SELECT decimal(+123e+4);
} {1230000.0}


do_execsql_test 2000 {
  CREATE TABLE t1(seq INTEGER PRIMARY KEY, val TEXT);
  INSERT INTO t1 VALUES
    (1, '-9999e99'),
    (2, '-9998.000e+99'),
    (3, '-9999.0'),
    (4, '-1'),
    (5, '-9999e-20'),
    (6, '0'),
    (7, '1e-30'),
    (8, '1e-29'),
    (9, '1'),
    (10,'1.00000000000000001'),
    (11,'+1.00001'),
    (12,'99e+99');
  SELECT *, '|'
    FROM t1 AS a, t1 AS b
   WHERE a.seq<b.seq
     AND decimal_cmp(a.val,b.val)>=0;
} {}
do_execsql_test 2010 {
  SELECT *, '|'
    FROM t1 AS a, t1 AS b
   WHERE a.seq<>b.seq
     AND decimal_cmp(a.val,b.val)==0;
} {}
do_execsql_test 2020 {
  SELECT *, '|'
    FROM t1 AS a, t1 AS b
   WHERE a.seq>b.seq
     AND decimal_cmp(a.val,b.val)<=0;
} {}
do_execsql_test 2030 {
  SELECT seq FROM t1 ORDER BY val COLLATE decimal;
} {1 2 3 4 5 6 7 8 9 10 11 12}
do_execsql_test 2040 {
  SELECT seq FROM t1 ORDER BY val COLLATE decimal DESC;
} {12 11 10 9 8 7 6 5 4 3 2 1}

do_execsql_test 3000 {
  CREATE TABLE t3(seq INTEGER PRIMARY KEY, val TEXT);
  WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<10)
    INSERT INTO t3(seq, val) SELECT x, x FROM c;
  WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<5)
    INSERT INTO t3(seq, val) SELECT x+10, x*1000 FROM c;
  SELECT decimal(val) FROM t3 ORDER BY seq;
} {1 2 3 4 5 6 7 8 9 10 1000 2000 3000 4000 5000}
do_execsql_test 3020 {
  SELECT decimal_add(val,'0.5') FROM t3 WHERE seq>5 ORDER BY seq
} {6.5 7.5 8.5 9.5 10.5 1000.5 2000.5 3000.5 4000.5 5000.5}
do_execsql_test 3030 {
  SELECT decimal_add(val,'-10') FROM t3 ORDER BY seq;
} {-9 -8 -7 -6 -5 -4 -3 -2 -1 0 990 1990 2990 3990 4990}

do_execsql_test 4000 {
  SELECT decimal_sum(val) FROM t3;
} {15055}
do_execsql_test 4010 {
  SELECT decimal_sum(decimal_add(val,val||'e+10')) FROM t3;
} {150550000015055}
do_execsql_test 4010 {
  SELECT decimal_sum(decimal_add(val||'e+20',decimal_add(val,val||'e-20')))
    FROM t3;
} {1505500000000000000015055.00000000000000015055}

do_execsql_test 5000 {
  WITH RECURSIVE c(x,y,z) AS (
    VALUES(0,'1','1')
    UNION ALL
    SELECT x+1, decimal_mul(y,'2'), decimal_mul(z,'0.5')
      FROM c WHERE x<32
  )
  SELECT count(*) FROM c WHERE decimal_mul(y,z)='1';
} {33}

do_execsql_test 5100 {
  SELECT decimal_mul('1234.00','2.00');
} {2468.00}
do_execsql_test 5101 {
  SELECT decimal_mul('1234.00','2.0000');
} {2468.00}
do_execsql_test 5102 {
  SELECT decimal_mul('1234.0000','2.000');
} {2468.000}
do_execsql_test 5103 {
  SELECT decimal_mul('1234.0000','2');
} {2468}

if {[catch {load_static_extension db ieee754} error]} {
  puts "Skipping ieee754 tests, hit load error: $error"
  finish_test; return
}

do_execsql_test 6000 {
  CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
  WITH RECURSIVE c(x,v) AS (
    VALUES(0,'1')
    UNION ALL
    SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971
  ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
  WITH RECURSIVE c(x,v) AS (
    VALUES(-1,'0.5')
    UNION ALL
    SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075
  ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
} {}
do_execsql_test 6010 {
  WITH c(n) AS (SELECT ieee754_from_blob(x'0000000000000001'))
SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
  FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
} {0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625}
do_execsql_test 6020 {
  WITH c(n) AS (SELECT ieee754_from_blob(x'7fefffffffffffff'))
SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
  FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
} {179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368}

do_execsql_test 6100 {
  SELECT ieee754(ieee754_from_blob(x'0000000000000001'));
} {ieee754(1,-1074)}
do_execsql_test 6110 {
  SELECT ieee754(ieee754_from_blob(x'7fefffffffffffff'));
} {ieee754(9007199254740991,971)}
do_execsql_test 6120 {
  SELECT printf('%.8e',ieee754_from_blob(x'0000000000000001'));
} {4.94065646e-324}
do_execsql_test 6130 {
  SELECT printf('%.8e',ieee754_from_blob(x'ffefffffffffffff'));
} {-1.79769313e+308}




finish_test

Changes to test/default.test.

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
124
125
126
127
128
129
130









131







-
-
-
-
-
-
-
-
-

do_catchsql_test default-4.3 {
  CREATE TABLE t2(a TEXT, b TEXT DEFAULT(abs(:xyz)));
} {1 {default value of column [b] is not constant}}
do_catchsql_test default-4.4 {
  CREATE TABLE t2(a TEXT, b TEXT DEFAULT(98+coalesce(5,:xyz)));
} {1 {default value of column [b] is not constant}}

# 2020-03-09 out-of-bounds memory access discovered by "Eternal Sakura"
# and reported to chromium.
#
reset_db
do_catchsql_test default-5.1 {
  CREATE TABLE t1 (a,b DEFAULT(random() NOTNULL IN (RAISE(IGNORE),2,3)));
  INSERT INTO t1(a) VALUES(1);
} {1 {RAISE() may only be used within a trigger-program}}

finish_test

Changes to test/descidx1.test.

18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
18
19
20
21
22
23
24

25

26
27
28
29
30
31
32







-
+
-







source $testdir/tester.tcl

# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec

#db eval {PRAGMA legacy_file_format=OFF}
db eval {PRAGMA legacy_file_format=OFF}
sqlite3_db_config db LEGACY_FILE_FORMAT 0

# This procedure sets the value of the file-format in file 'test.db'
# to $newval. Also, the schema cookie is incremented.
# 
proc set_file_format {newval} {
  hexio_write test.db 44 [hexio_render_int32 $newval]
  set schemacookie [hexio_get_int [hexio_read test.db 40 4]]
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
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







-
+






-
+



-
-
+
+


















-
-
+
+



















-

+









# the get_file_format command.
#
ifcapable legacyformat {
  do_test descidx1-6.1 {
    db close
    forcedelete test.db test.db-journal
    sqlite3 db test.db
    sqlite3_db_config db LEGACY_FILE_FORMAT
    execsql {PRAGMA legacy_file_format}
  } {1}
} else {
  do_test descidx1-6.1 {
    db close
    forcedelete test.db test.db-journal
    sqlite3 db test.db
    sqlite3_db_config db LEGACY_FILE_FORMAT
    execsql {PRAGMA legacy_file_format}
  } {0}
}
do_test descidx1-6.2 {
  sqlite3_db_config db LEGACY_FILE_FORMAT 1
  sqlite3_db_config db LEGACY_FILE_FORMAT
  execsql {PRAGMA legacy_file_format=YES}
  execsql {PRAGMA legacy_file_format}
} {1}
do_test descidx1-6.3 {
  execsql {
    CREATE TABLE t1(a,b,c);
  }
  get_file_format
} {1}
ifcapable vacuum {
  # Verify that the file format is preserved across a vacuum.
  do_test descidx1-6.3.1 {
    execsql {VACUUM}
    get_file_format
  } {1}
}
do_test descidx1-6.4 {
  db close
  forcedelete test.db test.db-journal
  sqlite3 db test.db
  sqlite3_db_config db LEGACY_FILE_FORMAT 0
  sqlite3_db_config db LEGACY_FILE_FORMAT
  execsql {PRAGMA legacy_file_format=NO}
  execsql {PRAGMA legacy_file_format}
} {0}
do_test descidx1-6.5 {
  execsql {
    CREATE TABLE t1(a,b,c);
    CREATE INDEX i1 ON t1(a ASC, b DESC, c ASC);
    INSERT INTO t1 VALUES(1,2,3);
    INSERT INTO t1 VALUES(1,1,0);
    INSERT INTO t1 VALUES(1,2,1);
    INSERT INTO t1 VALUES(1,3,4);
  }
  get_file_format
} {4}
ifcapable vacuum {
  # Verify that the file format is preserved across a vacuum.
  do_test descidx1-6.6 {
    execsql {VACUUM}
    get_file_format
  } {4}
  do_test descidx1-6.7 {
    sqlite3_db_config db LEGACY_FILE_FORMAT 1
    execsql {
      PRAGMA legacy_file_format=ON;
      VACUUM;
    }
    get_file_format
  } {4}
} 



finish_test

Changes to test/descidx2.test.

19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
19
20
21
22
23
24
25

26

27
28
29
30
31
32
33







-
+
-








# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec


#db eval {PRAGMA legacy_file_format=OFF}
db eval {PRAGMA legacy_file_format=OFF}
sqlite3_db_config db LEGACY_FILE_FORMAT 0

# This procedure sets the value of the file-format in file 'test.db'
# to $newval. Also, the schema cookie is incremented.
# 
proc set_file_format {newval} {
  hexio_write test.db 44 [hexio_render_int32 $newval]
  set schemacookie [hexio_get_int [hexio_read test.db 40 4]]

Changes to test/descidx3.test.

22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
22
23
24
25
26
27
28

29

30
31
32
33
34
35
36







-
+
-







#
do_not_use_codec

ifcapable !bloblit {
  finish_test
  return
}
#db eval {PRAGMA legacy_file_format=OFF}
db eval {PRAGMA legacy_file_format=OFF}
sqlite3_db_config db LEGACY_FILE_FORMAT 0

# This procedure sets the value of the file-format in file 'test.db'
# to $newval. Also, the schema cookie is incremented.
# 
proc set_file_format {newval} {
  hexio_write test.db 44 [hexio_render_int32 $newval]
  set schemacookie [hexio_get_int [hexio_read test.db 40 4]]

Changes to test/distinct.test.

47
48
49
50
51
52
53
54
55


56
57
58
59
60
61
62
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62







-
-
+
+







}

proc do_temptables_test {tn sql temptables} {
  uplevel [list do_test $tn [subst -novar {
    set ret ""
    db eval "EXPLAIN [set sql]" {
      if {$opcode == "OpenEphemeral" || $opcode == "SorterOpen"} { 
        if {$p5!=8 && $p5!=0} { error "p5 = $p5" }
        if {$p5==8} {
        if {$p5 != "08" && $p5!="00"} { error "p5 = $p5" }
        if {$p5 == "08"} {
          lappend ret hash
        } else {
          lappend ret btree
        }
      }
    }
    set ret
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
264
265
266
267
268
269
270



271























272







-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

} {jjj}
do_execsql_test 6.2 {
  CREATE TABLE nnn(x);
  SELECT (SELECT 'mmm' UNION SELECT DISTINCT max(name) ORDER BY 1) 
    FROM sqlite_master;
} {mmm}

#-------------------------------------------------------------------------
# Ticket [9c944882]
#

reset_db
do_execsql_test 7.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY);
  CREATE TABLE t3(a INTEGER PRIMARY KEY);

  CREATE TABLE t4(x);
  CREATE TABLE t5(y);
  
  INSERT INTO t5 VALUES(1), (2), (2);
  INSERT INTO t1 VALUES(2);
  INSERT INTO t3 VALUES(2);
  INSERT INTO t4 VALUES(2);
}

do_execsql_test 7.1 {
  WITH t2(b) AS (
    SELECT DISTINCT y FROM t5 ORDER BY y
  )
  SELECT * FROM 
    t4 CROSS JOIN t3 CROSS JOIN t1 
  WHERE (t1.a=t3.a) AND (SELECT count(*) FROM t2 AS y WHERE t4.x!='abc')=t1.a
} {2 2 2}

finish_test

Changes to test/distinct2.test.

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
225
226
227
228
229
230
231







































































232
233







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  CREATE TABLE t2(x PRIMARY KEY);
  INSERT INTO t2 VALUES('yes');
  SELECT DISTINCT a FROM t1, t2 WHERE x=b;
  ANALYZE;
  SELECT DISTINCT a FROM t1, t2 WHERE x=b;
} {1 1}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 2000 {
  CREATE TABLE t0 (c0, c1, c2, PRIMARY KEY (c0, c1));
  CREATE TABLE t1 (c2);
  INSERT INTO t0(c2) VALUES (0),(1),(3),(4),(5),(6),(7),(8),(9),(10),(11);
  INSERT INTO t0(c1) VALUES ('a');
  INSERT INTO t1(c2) VALUES (0);
}
do_execsql_test 2010 {
  SELECT DISTINCT t0.c0, t1._rowid_, t0.c1 FROM t1 CROSS JOIN t0 ORDER BY t0.c0;
} {{} 1 {} {} 1 a}
do_execsql_test 1.2 {
  ANALYZE;
}
do_execsql_test 2020 {
  SELECT DISTINCT t0.c0, t1._rowid_, t0.c1 FROM t1 CROSS JOIN t0 ORDER BY t0.c0;
} {{} 1 {} {} 1 a}


do_execsql_test 2030 {
  CREATE TABLE t2(a, b, c);
  CREATE INDEX t2ab ON t2(a, b);
  
  WITH c(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM c WHERE i<64)
    INSERT INTO t2 SELECT 'one', i%2, 'one' FROM c;

  WITH c(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM c WHERE i<64)
    INSERT INTO t2 SELECT 'two', i%2, 'two' FROM c;

  CREATE TABLE t3(x INTEGER PRIMARY KEY);
  INSERT INTO t3 VALUES(1);

  ANALYZE;
}
do_execsql_test 2040 {
  SELECT DISTINCT a, b, x FROM t3 CROSS JOIN t2 ORDER BY a, +b; 
} {
  one 0 1
  one 1 1
  two 0 1
  two 1 1
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 3000 {
  CREATE TABLE t0 (c0, c1 NOT NULL DEFAULT 1, c2, PRIMARY KEY (c0, c1));
  INSERT INTO t0(c2) VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL);
  INSERT INTO t0(c2) VALUES('a');
}

do_execsql_test 3010 {
  SELECT DISTINCT * FROM t0 WHERE NULL IS t0.c0;
} {
  {} 1 {}
  {} 1 a
}

do_execsql_test 3020 {
  ANALYZE;
}

do_execsql_test 3030 {
  SELECT DISTINCT * FROM t0 WHERE NULL IS c0;
} {
  {} 1 {}
  {} 1 a
}

finish_test

Changes to test/e_createtable.test.

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
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







-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
















-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-






-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-







do_createtable_tests 1.2.2 {
  1    "CREATE TABLE main.abc(a, b, c)"          {}
  2    "CREATE TABLE temp.helloworld(x)"         {}
  3    {CREATE TABLE auxa."t 1"(x, y)}           {}
  4    {CREATE TABLE auxb.xyz(z)}                {}
}
drop_all_tables
if {[permutation]!="maindbname"} {
  do_createtable_tests 1.3 -tclquery {
    unset -nocomplain X
    array set X [table_list]
    list $X(main) $X(temp) $X(auxa) $X(auxb)
  } {
    1    "CREATE TABLE main.abc(a, b, c)"  {abc {} {} {}}
    2    "CREATE TABLE main.t1(a, b, c)"   {{abc t1} {} {} {}}
    3    "CREATE TABLE temp.tmp(a, b, c)"  {{abc t1} tmp {} {}}
    4    "CREATE TABLE auxb.tbl(x, y)"     {{abc t1} tmp {} tbl}
    5    "CREATE TABLE auxb.t1(k, v)"      {{abc t1} tmp {} {t1 tbl}}
    6    "CREATE TABLE auxa.next(c, d)"    {{abc t1} tmp next {t1 tbl}}
do_createtable_tests 1.3 -tclquery {
  unset -nocomplain X
  array set X [table_list]
  list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
  1    "CREATE TABLE main.abc(a, b, c)"  {abc {} {} {}}
  2    "CREATE TABLE main.t1(a, b, c)"   {{abc t1} {} {} {}}
  3    "CREATE TABLE temp.tmp(a, b, c)"  {{abc t1} tmp {} {}}
  4    "CREATE TABLE auxb.tbl(x, y)"     {{abc t1} tmp {} tbl}
  5    "CREATE TABLE auxb.t1(k, v)"      {{abc t1} tmp {} {t1 tbl}}
  6    "CREATE TABLE auxa.next(c, d)"    {{abc t1} tmp next {t1 tbl}}
  }
}

# EVIDENCE-OF: R-18895-27365 If the "TEMP" or "TEMPORARY" keyword occurs
# between the "CREATE" and "TABLE" then the new table is created in the
# temp database.
#
drop_all_tables
if {[permutation]!="maindbname"} {
  do_createtable_tests 1.4 -tclquery {
    unset -nocomplain X
    array set X [table_list]
    list $X(main) $X(temp) $X(auxa) $X(auxb)
  } {
    1    "CREATE TEMP TABLE t1(a, b)"      {{} t1 {} {}}
    2    "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}}
do_createtable_tests 1.4 -tclquery {
  unset -nocomplain X
  array set X [table_list]
  list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
  1    "CREATE TEMP TABLE t1(a, b)"      {{} t1 {} {}}
  2    "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}}
  }
}

# EVIDENCE-OF: R-23976-43329 It is an error to specify both a
# schema-name and the TEMP or TEMPORARY keyword, unless the schema-name
# is "temp".
#
drop_all_tables
do_createtable_tests 1.5.1 -error {
  temporary table name must be unqualified
} {
  1    "CREATE TEMP TABLE main.t1(a, b)"        {}
  2    "CREATE TEMPORARY TABLE auxa.t2(a, b)"   {}
  3    "CREATE TEMP TABLE auxb.t3(a, b)"        {}
  4    "CREATE TEMPORARY TABLE main.xxx(x)"     {}
}
drop_all_tables
if {[permutation]!="maindbname"} {
  do_createtable_tests 1.5.2 -tclquery {
    unset -nocomplain X
    array set X [table_list]
    list $X(main) $X(temp) $X(auxa) $X(auxb)
  } {
    1    "CREATE TEMP TABLE temp.t1(a, b)"        {{} t1 {} {}}
    2    "CREATE TEMPORARY TABLE temp.t2(a, b)"   {{} {t1 t2} {} {}}
    3    "CREATE TEMP TABLE TEMP.t3(a, b)"        {{} {t1 t2 t3} {} {}}
    4    "CREATE TEMPORARY TABLE TEMP.xxx(x)"     {{} {t1 t2 t3 xxx} {} {}}
do_createtable_tests 1.5.2 -tclquery {
  unset -nocomplain X
  array set X [table_list]
  list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
  1    "CREATE TEMP TABLE temp.t1(a, b)"        {{} t1 {} {}}
  2    "CREATE TEMPORARY TABLE temp.t2(a, b)"   {{} {t1 t2} {} {}}
  3    "CREATE TEMP TABLE TEMP.t3(a, b)"        {{} {t1 t2 t3} {} {}}
  4    "CREATE TEMPORARY TABLE TEMP.xxx(x)"     {{} {t1 t2 t3 xxx} {} {}}
  }
}

# EVIDENCE-OF: R-31997-24564 If no schema name is specified and the TEMP
# keyword is not present then the table is created in the main database.
#
drop_all_tables
if {[permutation]!="maindbname"} {
  do_createtable_tests 1.6 -tclquery {
    unset -nocomplain X
    array set X [table_list]
    list $X(main) $X(temp) $X(auxa) $X(auxb)
  } {
    1    "CREATE TABLE t1(a, b)"   {t1 {} {} {}}
    2    "CREATE TABLE t2(a, b)"   {{t1 t2} {} {} {}}
    3    "CREATE TABLE t3(a, b)"   {{t1 t2 t3} {} {} {}}
    4    "CREATE TABLE xxx(x)"     {{t1 t2 t3 xxx} {} {} {}}
do_createtable_tests 1.6 -tclquery {
  unset -nocomplain X
  array set X [table_list]
  list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
  1    "CREATE TABLE t1(a, b)"   {t1 {} {} {}}
  2    "CREATE TABLE t2(a, b)"   {{t1 t2} {} {} {}}
  3    "CREATE TABLE t3(a, b)"   {{t1 t2 t3} {} {} {}}
  4    "CREATE TABLE xxx(x)"     {{t1 t2 t3 xxx} {} {} {}}
  }
}

drop_all_tables
do_execsql_test e_createtable-1.7.0 {
  CREATE TABLE t1(x, y);
  CREATE INDEX i1 ON t1(x);
  CREATE VIEW  v1 AS SELECT * FROM t1;
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
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







-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+







  CREATE TABLE t2(a, b, CHECK( a||b ));
  INSERT INTO x2 VALUES(1, 'xx');
  INSERT INTO x2 VALUES(1, 'yy');
  INSERT INTO t2 SELECT * FROM x2;
}

do_createtable_tests 4.11 -error {CHECK constraint failed: %s} {
  1a    "INSERT INTO x1 VALUES('one', 0)"       {b>0}
  1b    "INSERT INTO t1 VALUES('one', -4.0)"    {b>0}
  1a    "INSERT INTO x1 VALUES('one', 0)"       {x1}
  1b    "INSERT INTO t1 VALUES('one', -4.0)"    {t1}

  2a    "INSERT INTO x2 VALUES('abc', 1)"       {a||b}
  2b    "INSERT INTO t2 VALUES('abc', 1)"       {a||b}
  2a    "INSERT INTO x2 VALUES('abc', 1)"       {x2}
  2b    "INSERT INTO t2 VALUES('abc', 1)"       {t2}

  3a    "INSERT INTO x2 VALUES(0, 'abc')"       {a||b}
  3b    "INSERT INTO t2 VALUES(0, 'abc')"       {a||b}
  3a    "INSERT INTO x2 VALUES(0, 'abc')"       {x2}
  3b    "INSERT INTO t2 VALUES(0, 'abc')"       {t2}

  4a    "UPDATE t1 SET b=-1 WHERE rowid=1"      {b>0}
  4b    "UPDATE x1 SET b=-1 WHERE rowid=1"      {b>0}
  4a    "UPDATE t1 SET b=-1 WHERE rowid=1"      {t1}
  4b    "UPDATE x1 SET b=-1 WHERE rowid=1"      {x1}

  4a    "UPDATE x2 SET a='' WHERE rowid=1"      {a||b}
  4b    "UPDATE t2 SET a='' WHERE rowid=1"      {a||b}
  4a    "UPDATE x2 SET a='' WHERE rowid=1"      {x2}
  4b    "UPDATE t2 SET a='' WHERE rowid=1"      {t2}
}

# EVIDENCE-OF: R-34109-39108 If the CHECK expression evaluates to NULL,
# or any other non-zero value, it is not a constraint violation.
#
do_createtable_tests 4.12 {
  1a    "INSERT INTO x1 VALUES('one', NULL)"    {}
1635
1636
1637
1638
1639
1640
1641
1642

1643
1644
1645
1646
1647
1648
1649
1627
1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
1641







-
+







  CREATE TABLE t4(a, b CHECK (b!=10));
  INSERT INTO t4 VALUES(1, 2);
  INSERT INTO t4 VALUES(3, 4);
}
do_execsql_test  4.18.2 { BEGIN; INSERT INTO t4 VALUES(5, 6) }
do_catchsql_test 4.18.3 { 
  INSERT INTO t4 SELECT a+4, b+4 FROM t4
} {1 {CHECK constraint failed: b!=10}}
} {1 {CHECK constraint failed: t4}}
do_test e_createtable-4.18.4 { sqlite3_get_autocommit db } 0
do_execsql_test 4.18.5 { SELECT * FROM t4 } {1 2 3 4 5 6}

# EVIDENCE-OF: R-19114-56113 Different constraints within the same table
# may have different default conflict resolution algorithms.
#
do_execsql_test 4.19.0 {

Changes to test/e_droptrigger.test.

123
124
125
126
127
128
129
130
131


132
133
134
135
136
137
138
123
124
125
126
127
128
129


130
131
132
133
134
135
136
137
138







-
-
+
+







    droptrigger_reopen_db
    execsql $droptrigger
    execsql " INSERT INTO $tbl VALUES('1', '2') "
    set ::triggers_fired
  } $after
}

# EVIDENCE-OF: R-04950-25529 Once removed, the trigger definition is no
# longer present in the sqlite_schema (or sqlite_temp_schema) table and
# EVIDENCE-OF: R-50239-29811 Once removed, the trigger definition is no
# longer present in the sqlite_master (or sqlite_temp_master) table and
# is not fired by any subsequent INSERT, UPDATE or DELETE statements.
#
#   Test cases e_droptrigger-1.* test the first part of this statement
#   (that dropped triggers do not appear in the schema table), and tests
#   droptrigger-2.* test that dropped triggers are not fired by INSERT
#   statements. The following tests verify that they are not fired by
#   UPDATE or DELETE statements.

Changes to test/e_dropview.test.

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
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







-
+





-
+





-
+





-
+

-
-
-
-
-
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+







#
set databasedata [list_all_data]

do_execsql_test  3.1.0 { SELECT * FROM temp.v1 } {{a temp} {b temp}}
do_execsql_test  3.1.1 { DROP VIEW temp.v1 } {}
do_catchsql_test 3.1.2 { SELECT * FROM temp.v1 } {1 {no such table: temp.v1}}
do_test          3.1.3 { list_all_views } {main.v1 main.v2 aux.v1 aux.v2 aux.v3}
do_test          3.1.4 { string compare [list_all_data] $databasedata } 0
do_test          3.1.4 { list_all_data  } $databasedata

do_execsql_test  3.2.0 { SELECT * FROM v1 } {{a main} {b main}}
do_execsql_test  3.2.1 { DROP VIEW v1 } {}
do_catchsql_test 3.2.2 { SELECT * FROM main.v1 } {1 {no such table: main.v1}}
do_test          3.2.3 { list_all_views } {main.v2 aux.v1 aux.v2 aux.v3}
do_test          3.2.4 { string compare [list_all_data] $databasedata } 0
do_test          3.2.4 { list_all_data  } $databasedata

do_execsql_test  3.3.0 { SELECT * FROM v2 } {{a main} {b main}}
do_execsql_test  3.3.1 { DROP VIEW v2 } {}
do_catchsql_test 3.3.2 { SELECT * FROM main.v2 } {1 {no such table: main.v2}}
do_test          3.3.3 { list_all_views } {aux.v1 aux.v2 aux.v3}
do_test          3.3.4 { string compare [list_all_data] $databasedata } 0
do_test          3.3.4 { list_all_data  } $databasedata

do_execsql_test  3.4.0 { SELECT * FROM v1 } {{a aux} {b aux}}
do_execsql_test  3.4.1 { DROP VIEW v1 } {}
do_catchsql_test 3.4.2 { SELECT * FROM v1 } {1 {no such table: v1}}
do_test          3.4.3 { list_all_views } {aux.v2 aux.v3}
do_test          3.4.4 { string compare [list_all_data] $databasedata } 0
do_test          3.4.4 { list_all_data  } $databasedata

do_execsql_test  3.5.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}}
do_execsql_test  3.5.1 { DROP VIEW aux.v2 } {}
do_catchsql_test 3.5.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}}
do_test          3.5.3 { list_all_views } {aux.v3}
do_test          3.5.4 { string compare [list_all_data] $databasedata } 0
do_execsql_test  3.4.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}}
do_execsql_test  3.4.1 { DROP VIEW aux.v2 } {}
do_catchsql_test 3.4.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}}
do_test          3.4.3 { list_all_views } {aux.v3}
do_test          3.4.4 { list_all_data  } $databasedata

do_execsql_test  3.6.0 { SELECT * FROM v3 } {{a aux} {b aux}}
do_execsql_test  3.6.1 { DROP VIEW v3 } {}
do_catchsql_test 3.6.2 { SELECT * FROM v3 } {1 {no such table: v3}}
do_test          3.6.3 { list_all_views } {}
do_test          3.6.4 { string compare [list_all_data] $databasedata } 0
do_execsql_test  3.5.0 { SELECT * FROM v3 } {{a aux} {b aux}}
do_execsql_test  3.5.1 { DROP VIEW v3 } {}
do_catchsql_test 3.5.2 { SELECT * FROM v3 } {1 {no such table: v3}}
do_test          3.5.3 { list_all_views } {}
do_test          3.5.4 { list_all_data  } $databasedata

# EVIDENCE-OF: R-25558-37487 If the specified view cannot be found and
# the IF EXISTS clause is not present, it is an error.
#
do_dropview_tests 4 -repair {
  dropview_reopen_db 
} -errorformat {
175
176
177
178
179
180
181
182

183
184
185
186



187
188
189
190
191
192
175
176
177
178
179
180
181

182
183



184
185
186
187
188
189
190
191
192







-
+

-
-
-
+
+
+






# an IF EXISTS clause is present in the DROP VIEW statement, then the
# statement is a no-op.
#
do_dropview_tests 5 -repair {
  dropview_reopen_db
} -tclquery {
  list_all_views
  #expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"}
  expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"}
} {
  1    "DROP VIEW IF EXISTS xx" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
  2    "DROP VIEW IF EXISTS main.xx" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
  3    "DROP VIEW IF EXISTS temp.v2" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
  1    "DROP VIEW IF EXISTS xx"       1
  2    "DROP VIEW IF EXISTS main.xx"  1
  3    "DROP VIEW IF EXISTS temp.v2"  1
}




finish_test

Changes to test/e_expr.test.

250
251
252
253
254
255
256
257

258
259

260
261
262
263
264
265
266
250
251
252
253
254
255
256

257


258
259
260
261
262
263
264
265







-
+
-
-
+







  
  do_execsql_test e_expr-5.$tn "SELECT $a || $b" [list "${as}${bs}"]
}

#-------------------------------------------------------------------------
# Test the % operator.
#
# EVIDENCE-OF: R-53431-59159 The % operator casts both of its operands
# EVIDENCE-OF: R-04223-04352 The operator % outputs the integer value of
# to type INTEGER and then computes the remainder after dividing the
# left integer by the right integer.
# its left operand modulo its right operand.
#
do_execsql_test e_expr-6.1 {SELECT  72%5}  {2}
do_execsql_test e_expr-6.2 {SELECT  72%-5} {2}
do_execsql_test e_expr-6.3 {SELECT -72%-5} {-2}
do_execsql_test e_expr-6.4 {SELECT -72%5}  {-2}
do_execsql_test e_expr-6.5 {SELECT 72.35%5} {2.0}

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
1009
1010
1011
1012
1013
1014
1015

1016



1017
1018


1019



1020
1021


1022

1023
1024
1025
1026
1027
1028
1029







-
+
-
-
-
+
+
-
-
+
-
-
-
+
+
-
-
+
-







do_test         e_expr-15.1.4 { set likeargs } {def abc X}
db close
sqlite3 db test.db

# EVIDENCE-OF: R-22868-25880 The LIKE operator can be made case
# sensitive using the case_sensitive_like pragma.
#
do_execsql_test e_expr-16.1.1  { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.1 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.1b { SELECT 'abc%xyz' LIKE 'ABC\%x%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.2  { PRAGMA case_sensitive_like = 1 } {}
do_execsql_test e_expr-16.1.3  { SELECT 'abcxyz' LIKE 'ABC%' } 0
do_execsql_test e_expr-16.1.2 { PRAGMA case_sensitive_like = 1 } {}
do_execsql_test e_expr-16.1.3 { SELECT 'abcxyz' LIKE 'ABC%' } 0
do_execsql_test e_expr-16.1.3b { SELECT 'abc%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 0
do_execsql_test e_expr-16.1.4  { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.4 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.4b { SELECT 'ABC%xyz' LIKE 'ABC\%x%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.5  { PRAGMA case_sensitive_like = 0 } {}
do_execsql_test e_expr-16.1.6  { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.5 { PRAGMA case_sensitive_like = 0 } {}
do_execsql_test e_expr-16.1.6 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.6b { SELECT 'abc%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.7  { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.7 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.7b { SELECT 'ABC%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 1

# EVIDENCE-OF: R-52087-12043 The GLOB operator is similar to LIKE but
# uses the Unix file globbing syntax for its wildcards.
#
# EVIDENCE-OF: R-09813-17279 Also, GLOB is case sensitive, unlike LIKE.
#
do_execsql_test e_expr-17.1.1 { SELECT 'abcxyz' GLOB 'abc%' } 0
1136
1137
1138
1139
1140
1141
1142
1143

1144
1145
1146
1147
1148
1149
1150
1130
1131
1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
1144







-
+







do_execsql_test e_expr-19.2.3 { SELECT 'X' NOT MATCH 'Y' } 0
do_test         e_expr-19.2.4 { set matchargs } {Y X}
sqlite3 db test.db

#-------------------------------------------------------------------------
# Test cases for the testable statements related to the CASE expression.
#
# EVIDENCE-OF: R-57495-24088 There are two fundamental forms of the CASE
# EVIDENCE-OF: R-15199-61389 There are two basic forms of the CASE
# expression: those with a base expression and those without.
#
do_execsql_test e_expr-20.1 {
  SELECT CASE WHEN 1 THEN 'true' WHEN 0 THEN 'false' ELSE 'else' END;
} {true}
do_execsql_test e_expr-20.2 {
  SELECT CASE 0 WHEN 1 THEN 'true' WHEN 0 THEN 'false' ELSE 'else' END;
1232
1233
1234
1235
1236
1237
1238
1239
1240


1241
1242
1243


1244
1245
1246
1247
1248
1249
1250
1226
1227
1228
1229
1230
1231
1232


1233
1234
1235


1236
1237
1238
1239
1240
1241
1242
1243
1244







-
-
+
+

-
-
+
+







} {null}
db nullvalue {}

# EVIDENCE-OF: R-13943-13592 A NULL result is considered untrue when
# evaluating WHEN terms.
#
do_execsql_test e_expr-21.4.1 {
  SELECT CASE WHEN NULL THEN 'A' WHEN 1 THEN 'B' END, iif(NULL,8,99);
} {B 99}
  SELECT CASE WHEN NULL THEN 'A' WHEN 1 THEN 'B' END
} {B}
do_execsql_test e_expr-21.4.2 {
  SELECT CASE WHEN 0 THEN 'A' WHEN NULL THEN 'B' ELSE 'C' END, iif(0,8,99);
} {C 99}
  SELECT CASE WHEN 0 THEN 'A' WHEN NULL THEN 'B' ELSE 'C' END
} {C}

# EVIDENCE-OF: R-38620-19499 In a CASE with a base expression, the base
# expression is evaluated just once and the result is compared against
# the evaluation of each WHEN expression from left to right.
#
# Note: This test case tests the "evaluated just once" part of the above
# statement. Tests associated with the next two statements test that the
1641
1642
1643
1644
1645
1646
1647
1648
1649


1650
1651
1652
1653

1654
1655
1656
1657

1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1635
1636
1637
1638
1639
1640
1641


1642
1643




1644




1645

1646
1647
1648
1649
1650
1651
























1652
1653
1654
1655
1656
1657
1658







-
-
+
+
-
-
-
-
+
-
-
-
-
+
-






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  CAST(-9223372036854775809.0 AS INT)
} integer -9223372036854775808
do_expr_test e_expr-31.2.4 { 
  CAST(9223372036854775809.0 AS INT)
} integer 9223372036854775807


# EVIDENCE-OF: R-55084-10555 Casting a TEXT or BLOB value into NUMERIC
# yields either an INTEGER or a REAL result.
# EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC
# first does a forced conversion into REAL but then further converts the
#
# EVIDENCE-OF: R-48945-04866 If the input text looks like an integer
# (there is no decimal point nor exponent) and the value is small enough
# to fit in a 64-bit signed integer, then the result will be INTEGER.
# result into INTEGER if and only if the conversion from REAL to INTEGER
#
# EVIDENCE-OF: R-47045-23194 Input text that looks like floating point
# (there is a decimal point and/or an exponent) and the text describes a
# value that can be losslessly converted back and forth between IEEE 754
# is lossless and reversible.
# 64-bit float and a 51-bit signed integer, then the result is INTEGER.
#
do_expr_test e_expr-32.1.1 { CAST('45'   AS NUMERIC)  } integer 45
do_expr_test e_expr-32.1.2 { CAST('45.0' AS NUMERIC)  } integer 45
do_expr_test e_expr-32.1.3 { CAST('45.2' AS NUMERIC)  } real 45.2
do_expr_test e_expr-32.1.4 { CAST('11abc' AS NUMERIC) } integer 11
do_expr_test e_expr-32.1.5 { CAST('11.1abc' AS NUMERIC) } real 11.1
do_expr_test e_expr-32.1.6 {CAST( '9.223372036e14' AS NUMERIC)} integer  922337203600000
do_expr_test e_expr-32.1.7 {CAST('-9.223372036e14' AS NUMERIC)} integer -922337203600000
do_test e_expr-32.1.8 {
  set expr {CAST( '9.223372036e15' AS NUMERIC)}
  db eval "SELECT typeof($expr) AS type, printf('%.5e',$expr) AS value"  break;
  list $type $value
} {real 9.22337e+15}
do_test e_expr-32.1.9 {
  set expr {CAST('-9.223372036e15' AS NUMERIC)}
  db eval "SELECT typeof($expr) AS type, printf('%.5e',$expr) AS value"  break;
  list $type $value
} {real -9.22337e+15}

# EVIDENCE-OF: R-50300-26941 Any text input that describes a value
# outside the range of a 64-bit signed integer yields a REAL result.
#
do_expr_test e_expr-32.1.20 { CAST('9223372036854775807' AS numeric) } \
   integer 9223372036854775807
do_expr_test e_expr-32.1.21 { CAST('9223372036854775808' AS numeric) } \
   real 9.22337203685478e+18
do_expr_test e_expr-32.1.22 { CAST('-9223372036854775808' AS numeric) } \
   integer -9223372036854775808
do_expr_test e_expr-32.1.23 { CAST('-9223372036854775809' AS numeric) } \
   real -9.22337203685478e+18

# EVIDENCE-OF: R-30347-18702 Casting a REAL or INTEGER value to NUMERIC
# is a no-op, even if a real value could be losslessly converted to an
# integer.
#
do_expr_test e_expr-32.2.1 { CAST(13.0 AS NUMERIC) } real 13.0
do_expr_test e_expr-32.2.2 { CAST(13.5 AS NUMERIC) } real 13.5
1729
1730
1731
1732
1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743


1744
1745
1746
1747
1748
1749
1750
1692
1693
1694
1695
1696
1697
1698

1699
1700
1701
1702
1703
1704


1705
1706
1707
1708
1709
1710
1711
1712
1713







-
+





-
-
+
+







  SELECT typeof(CAST(x AS NUMERIC)), CAST(x AS NUMERIC)||'' FROM t1;
} [list \
 integer 9000000000000000001 \
 integer 9000000000000000001 \
 integer 9000000000000000001 \
 integer 9000000000000000001 \
 integer 9000000000000000001 \
 real 9.0e+18 \
 integer 9000000000000000001 \
 integer 9223372036854775807 \
 integer 9223372036854775807 \
 integer 9223372036854775807 \
 real 9.22337203685478e+18 \
 real 9.22337203685478e+18 \
 real 9.22337203685478e+18 \
 real 9.22337203685478e+18 \
 integer 9223372036854775807 \
 integer 9223372036854775807 \
 integer -5 \
 integer -5 \
]

# EVIDENCE-OF: R-64550-29191 Note that the result from casting any
# non-BLOB value into a BLOB and the result from casting any BLOB value
# into a non-BLOB value may be different depending on whether the
1913
1914
1915
1916
1917
1918
1919



1920
1921
1922
1923
1924
1925
1926
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892







+
+
+







} {
  do_catchsql_test e_expr-35.2.$tn $sql $M
}

# EVIDENCE-OF: R-18318-14995 The value of a subquery expression is the
# first row of the result from the enclosed SELECT statement.
#
# EVIDENCE-OF: R-15900-52156 In other words, an implied "LIMIT 1" is
# added to the subquery, overriding an explicitly coded LIMIT.
#
do_execsql_test e_expr-36.3.1 {
  CREATE TABLE t4(x, y);
  INSERT INTO t4 VALUES(1, 'one');
  INSERT INTO t4 VALUES(2, 'two');
  INSERT INTO t4 VALUES(3, 'three');
} {}

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
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







-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+





-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+



  do_expr_test e_expr-36.4.$tn $expr null {}
}

# EVIDENCE-OF: R-62477-06476 For example, the values NULL, 0.0, 0,
# 'english' and '0' are all considered to be false.
#
do_execsql_test e_expr-37.1 {
   SELECT CASE WHEN NULL THEN 'true' ELSE 'false' END, iif(NULL,'true','false');
} {false false}
   SELECT CASE WHEN NULL THEN 'true' ELSE 'false' END;
} {false}
do_execsql_test e_expr-37.2 {
   SELECT CASE WHEN 0.0 THEN 'true' ELSE 'false' END, iif(0.0,'true','false');
} {false false}
   SELECT CASE WHEN 0.0 THEN 'true' ELSE 'false' END;
} {false}
do_execsql_test e_expr-37.3 {
   SELECT CASE WHEN 0 THEN 'true' ELSE 'false' END, iif(0,'true','false');
} {false false}
   SELECT CASE WHEN 0 THEN 'true' ELSE 'false' END;
} {false}
do_execsql_test e_expr-37.4 {
   SELECT CASE WHEN 'engligh' THEN 'true' ELSE 'false' END, iif('engligh','true','false');
} {false false}
   SELECT CASE WHEN 'engligh' THEN 'true' ELSE 'false' END;
} {false}
do_execsql_test e_expr-37.5 {
   SELECT CASE WHEN '0' THEN 'true' ELSE 'false' END, iif('0','true','false');
} {false false}
   SELECT CASE WHEN '0' THEN 'true' ELSE 'false' END;
} {false}

# EVIDENCE-OF: R-55532-10108 Values 1, 1.0, 0.1, -0.1 and '1english' are
# considered to be true.
#
do_execsql_test e_expr-37.6 {
   SELECT CASE WHEN 1 THEN 'true' ELSE 'false' END, iif(1,'true','false');
} {true true}
   SELECT CASE WHEN 1 THEN 'true' ELSE 'false' END;
} {true}
do_execsql_test e_expr-37.7 {
   SELECT CASE WHEN 1.0 THEN 'true' ELSE 'false' END, iif(1.0,'true','false');
} {true true}
   SELECT CASE WHEN 1.0 THEN 'true' ELSE 'false' END;
} {true}
do_execsql_test e_expr-37.8 {
   SELECT CASE WHEN 0.1 THEN 'true' ELSE 'false' END, iif(0.1,'true','false');
} {true true}
   SELECT CASE WHEN 0.1 THEN 'true' ELSE 'false' END;
} {true}
do_execsql_test e_expr-37.9 {
   SELECT CASE WHEN -0.1 THEN 'true' ELSE 'false' END, iif(-0.1,'true','false');
} {true true}
   SELECT CASE WHEN -0.1 THEN 'true' ELSE 'false' END;
} {true}
do_execsql_test e_expr-37.10 {
   SELECT CASE WHEN '1english' THEN 'true' ELSE 'false' END, iif('1engl','true','false');
} {true true}
   SELECT CASE WHEN '1english' THEN 'true' ELSE 'false' END;
} {true}


finish_test

Changes to test/e_fkey.test.

2051
2052
2053
2054
2055
2056
2057
2058

2059
2060

2061
2062
2063
2064
2065
2066
2067
2051
2052
2053
2054
2055
2056
2057

2058
2059

2060
2061
2062
2063
2064
2065
2066
2067







-
+

-
+







do_test e_fkey-44.5 {
  execsql { SELECT quote(c) FROM cB }
} {NULL}

#-------------------------------------------------------------------------
# Test SET DEFAULT actions.
#
# EVIDENCE-OF: R-55814-22637 The "SET DEFAULT" actions are similar to
# EVIDENCE-OF: R-43054-54832 The "SET DEFAULT" actions are similar to
# "SET NULL", except that each of the child key columns is set to
# contain the column's default value instead of NULL.
# contain the columns default value instead of NULL.
#
drop_all_tables
do_test e_fkey-45.1 {
  execsql {
    CREATE TABLE pA(x PRIMARY KEY);
    CREATE TABLE cA(c DEFAULT X'0000' REFERENCES pA ON DELETE SET DEFAULT);
    CREATE TABLE cB(c DEFAULT X'9999' REFERENCES pA ON UPDATE SET DEFAULT);
2503
2504
2505
2506
2507
2508
2509
2510

2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532


2533
2534
2535
2536
2537
2538
2539
2503
2504
2505
2506
2507
2508
2509

2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530


2531
2532
2533
2534
2535
2536
2537
2538
2539







-
+




















-
-
+
+







# clause, unless the default value of the new column is NULL. Attempting
# to do so returns an error.
#
proc test_efkey_6 {tn zAlter isError} {
  drop_all_tables 

  do_test e_fkey-56.$tn.1 "
    execsql { CREATE TABLE tbl(a, b); INSERT INTO tbl VALUES(1, 2); }
    execsql { CREATE TABLE tbl(a, b) }
    [list catchsql $zAlter]
  " [lindex {{0 {}} {1 {Cannot add a REFERENCES column with non-NULL default value}}} $isError]

}

test_efkey_6 1 "ALTER TABLE tbl ADD COLUMN c REFERENCES xx" 0
test_efkey_6 2 "ALTER TABLE tbl ADD COLUMN c DEFAULT NULL REFERENCES xx" 0
test_efkey_6 3 "ALTER TABLE tbl ADD COLUMN c DEFAULT 0 REFERENCES xx" 1

#-------------------------------------------------------------------------
# Test that ALTER TABLE adjusts REFERENCES clauses when the parent table
# is RENAMED.
#
# EVIDENCE-OF: R-47080-02069 If an "ALTER TABLE ... RENAME TO" command
# is used to rename a table that is the parent table of one or more
# foreign key constraints, the definitions of the foreign key
# constraints are modified to refer to the parent table by its new name
#
# Test that these adjustments are visible in the sqlite_master table.
#
# EVIDENCE-OF: R-43040-62530 The text of the child CREATE TABLE
# statement or statements stored in the sqlite_schema table are modified
# EVIDENCE-OF: R-63827-54774 The text of the child CREATE TABLE
# statement or statements stored in the sqlite_master table are modified
# to reflect the new parent table name.
#
do_test e_fkey-56.1 {
  drop_all_tables
  execsql {
    CREATE TABLE 'p 1 "parent one"'(a REFERENCES 'p 1 "parent one"', b, PRIMARY KEY(b));

2767
2768
2769
2770
2771
2772
2773
2774

2775
2776
2777
2778
2779
2780
2781
2767
2768
2769
2770
2771
2772
2773

2774
2775
2776
2777
2778
2779
2780
2781







-
+







#   3. Running an implicit DELETE FROM command as part of DROP TABLE.
#
# EVIDENCE-OF: R-54142-41346 The properties of the DROP TABLE and ALTER
# TABLE commands described above only apply if foreign keys are enabled.
#
do_test e_fkey-61.1.1 {
  drop_all_tables
  execsql { CREATE TABLE t1(a, b) ; INSERT INTO t1 VALUES(1, 2) }
  execsql { CREATE TABLE t1(a, b) }
  catchsql { ALTER TABLE t1 ADD COLUMN c DEFAULT 'xxx' REFERENCES t2 }
} {1 {Cannot add a REFERENCES column with non-NULL default value}}
do_test e_fkey-61.1.2 {
  execsql { PRAGMA foreign_keys = OFF }
  execsql { ALTER TABLE t1 ADD COLUMN c DEFAULT 'xxx' REFERENCES t2 }
  execsql { SELECT sql FROM sqlite_master WHERE name = 't1' }
} {{CREATE TABLE t1(a, b, c DEFAULT 'xxx' REFERENCES t2)}}

Changes to test/enc.test.

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
165
166
167
168
169
170
171
















































































172







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_test enc-11.2 {
  set cp200 "\u00C8"
  execsql {
    SELECT count(*) FROM ab WHERE a = $::cp200;
  }
} {2}

#-------------------------------------------------------------------------
reset_db
forcedelete test.db2
forcedelete test.db3

do_execsql_test enc-12.0 {
  PRAGMA encoding = 'utf-8';
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES('a', 'b', 'c');
  ATTACH 'test.db3' AS aux;
  CREATE TABLE aux.t3(x, y, z);
  INSERT INTO t3 VALUES('xxx', 'yyy', 'zzz');
  PRAGMA encoding;
} {UTF-8}

do_test enc-12.1 {
  sqlite3 db2 test.db2
  db2 eval {
    PRAGMA encoding = 'UTF-16le';
    CREATE TABLE t2(d, e, f);
    INSERT INTO t2 VALUES('d', 'e', 'f');
    PRAGMA encoding;
  }
} {UTF-16le}

do_test enc-12.2 {
  db2 backup test.db
  db2 close
} {}

do_catchsql_test enc-12.3 {
  SELECT * FROM t2;
} {1 {attached databases must use the same text encoding as main database}}

db close
sqlite3 db test.db3
do_execsql_test enc-12.4 {
  SELECT * FROM t3;
  PRAGMA encoding = 'UTF-16le';
  SELECT * FROM t3;
} {xxx yyy zzz xxx yyy zzz}

db close
sqlite3 db test.db3
breakpoint
do_execsql_test enc-12.5 {
  PRAGMA encoding = 'UTF-16le';
  PRAGMA encoding;
} {UTF-8}

reset_db
do_execsql_test enc-12.6 {
  PRAGMA encoding = 'UTF-8';
  CREATE TEMP TABLE t1(a, b, c);
  INSERT INTO t1 VALUES('xxx', 'yyy', 'zzz');
}
do_test enc-12.7 {
  sqlite3 db2 test.db2
  db2 backup test.db
  db2 close
  db eval {
    SELECT * FROM t1;
  }
} {xxx yyy zzz}
do_catchsql_test enc-12.8 {
  SELECT * FROM t2;
  SELECT * FROM t1;
} {1 {attached databases must use the same text encoding as main database}}

db close
sqlite3 db test.db
do_execsql_test enc-12.9 {
  CREATE TEMP TABLE t1(a, b, c);
  INSERT INTO t1 VALUES('xxx', 'yyy', 'zzz');
}
do_execsql_test enc-12.10 {
  SELECT * FROM t2;
  SELECT * FROM t1;
} {d e f xxx yyy zzz}

finish_test

Changes to test/enc2.test.

9
10
11
12
13
14
15

16
17
18
19
20
21
22
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23







+







#
#***********************************************************************
# This file implements regression tests for SQLite library.  The focus of
# this file is testing the SQLite routines used for converting between the
# various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
# UTF-16be).
#
# $Id: enc2.test,v 1.29 2007/10/09 08:29:32 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If UTF16 support is disabled, ignore the tests in this file
#
ifcapable {!utf16} {
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
548
549
550
551
552
553
554













555







-
-
-
-
-
-
-
-
-
-
-
-
-

  db close
  sqlite3 db test.db
  db eval {
    SELECT name FROM sqlite_master
  }
} {t1 t2}

# 2020-01-15 ticket a08879a4a476eea9
# Do not allow a database connection encoding change unless *all*
# attached databases are empty.
#
reset_db
do_execsql_test enc2-11.10 {
  PRAGMA encoding=UTF8;
  CREATE TEMP TABLE t1(x);
  INSERT INTO t1 VALUES('this is a test');
  PRAGMA encoding=UTF16;
  SELECT * FROM t1;
} {{this is a test}}

finish_test

Changes to test/exclusive.test.

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
507
508
509
510
511
512
513
























514
515
516







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



} {}

do_execsql_test exclusive-6.5 {
  PRAGMA locking_mode = EXCLUSIVE;
  SELECT * FROM sqlite_master;
} {exclusive}

# 2019-12-26 ticket fb3b3024ea238d5c
if {[permutation]!="journaltest"} {
  # The custom VFS used by the "journaltest" permutation cannot open the
  # shared-memory file. So, while it is able to switch the db file to
  # journal_mode=WAL when locking_mode=EXCLUSIVE, it can no longer access
  # it once the locking_mode is changed back to NORMAL.
  do_test exclusive-7.1 {
    db close
    forcedelete test.db test.db-journal test.db-wal
    sqlite3 db test.db
    # The following sequence of pragmas would trigger an assert()
    # associated with Pager.changeCountDone inside of assert_pager_state(),
    # prior to the fix.
    db eval {
      PRAGMA locking_mode = EXCLUSIVE;
      PRAGMA journal_mode = WAL;
      PRAGMA locking_mode = NORMAL;
      PRAGMA user_version;
      PRAGMA journal_mode = DELETE;
    }
  } {exclusive wal normal 0 delete}
}
 

} ;# atomic_batch_write==0

finish_test

Deleted 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
189
190
191
192
193
194


































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 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
}

do_execsql_test 2.7b {
  SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (a,x)=(c,y) LIMIT 1)
} {
  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

Deleted 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/expr.test.

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
1032
1033
1034
1035
1036
1037
1038




















1039







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  do_execsql_test expr-15.$tn.6 {
    SELECT sum(CASE WHEN x THEN 0 ELSE 1 END) FROM t1
     WHERE x
  } {0}
}

reset_db
sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
do_execsql_test expr-16.1 {
  CREATE TABLE t1(a,b,c);
  CREATE TABLE dual(dummy);
  INSERT INTO dual VALUES('X');
} {}
do_execsql_test expr-16.100 {
  SELECT implies_nonnull_row( (b=1 AND 0)>(b=3 AND 0),a)
  FROM dual LEFT JOIN t1;
} {0}
do_execsql_test expr-16.101 {
  SELECT implies_nonnull_row( (b=1 AND 0)>(b=3 AND a=4),a)
  FROM dual LEFT JOIN t1;
} {1}
do_execsql_test expr-16.102 {
  SELECT implies_nonnull_row( (b=1 AND a=2)>(b=3 AND a=4),a)
  FROM dual LEFT JOIN t1;
} {1}

finish_test

Deleted test/expr2.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






















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 May 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.  The
# focus of this file is testing expressions.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix expr2

do_execsql_test 1.0 {
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES ('val');
}

do_execsql_test 1.1 {
  SELECT * FROM t0 WHERE (
      ( (0 IS NOT FALSE) OR NOT (0 IS FALSE OR (t0.c0 = 1)) ) IS 0
  )
} {val}

do_execsql_test 1.2.1 {
  SELECT 
      ( (0 IS NOT FALSE) OR NOT (0 IS FALSE OR (t0.c0 = 1)) ) IS 0
  FROM t0 
} {1}

do_execsql_test 1.2.2 {
  SELECT 
      ( (0 IS NOT FALSE) OR NOT (0 IS 0 OR (t0.c0 = 1)) ) IS 0
  FROM t0 
} {1}

do_execsql_test 1.3 {
  SELECT ( (0 IS NOT FALSE) OR NOT (0 IS FALSE OR (t0.c0 = 1)) ) FROM t0 
} {0}

do_execsql_test 1.4.1 {
  SELECT (0 IS NOT FALSE) FROM t0 
} {0}
do_execsql_test 1.4.2 {
  SELECT NOT (0 IS FALSE OR (t0.c0 = 1)) FROM t0 
} {0}


finish_test

Deleted test/filter1.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

































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2018 May 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.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix filter1

ifcapable !windowfunc {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a);
  CREATE INDEX i1 ON t1(a);
  INSERT INTO t1 VALUES(1), (2), (3), (4), (5), (6), (7), (8), (9);
}

do_execsql_test 1.1 { SELECT sum(a) FROM t1; } 45
do_execsql_test 1.2 { SELECT sum(a) FILTER( WHERE a<5 ) FROM t1; } 10

do_execsql_test 1.3 { 
  SELECT sum(a) FILTER( WHERE a>9 ),
         sum(a) FILTER( WHERE a>8 ),
         sum(a) FILTER( WHERE a>7 ),
         sum(a) FILTER( WHERE a>6 ),
         sum(a) FILTER( WHERE a>5 ),
         sum(a) FILTER( WHERE a>4 ),
         sum(a) FILTER( WHERE a>3 ),
         sum(a) FILTER( WHERE a>2 ),
         sum(a) FILTER( WHERE a>1 ),
         sum(a) FILTER( WHERE a>0 )
  FROM t1;
} {{} 9 17 24 30 35 39 42 44 45}

do_execsql_test 1.4 {
  SELECT max(a) FILTER (WHERE (a % 2)==0) FROM t1
} {8}

do_execsql_test 1.5 {
  SELECT min(a) FILTER (WHERE a>4) FROM t1
} {5}

do_execsql_test 1.6 {
  SELECT count(*) FILTER (WHERE a!=5) FROM t1
} {8}

do_execsql_test 1.7 {
  SELECT min(a) FILTER (WHERE a>3) FROM t1 GROUP BY (a%2) ORDER BY 1;
} {4 5}

do_execsql_test 1.8 {
  CREATE VIEW vv AS 
  SELECT sum(a) FILTER( WHERE a>9 ),
         sum(a) FILTER( WHERE a>8 ),
         sum(a) FILTER( WHERE a>7 ),
         sum(a) FILTER( WHERE a>6 ),
         sum(a) FILTER( WHERE a>5 ),
         sum(a) FILTER( WHERE a>4 ),
         sum(a) FILTER( WHERE a>3 ),
         sum(a) FILTER( WHERE a>2 ),
         sum(a) FILTER( WHERE a>1 ),
         sum(a) FILTER( WHERE a>0 )
  FROM t1;
  SELECT * FROM vv;
} {{} 9 17 24 30 35 39 42 44 45}


#-------------------------------------------------------------------------
# Test some errors:
#
#   .1 FILTER on a non-aggregate function,
#   .2 Window function in FILTER clause,
#   .3 Aggregate function in FILTER clause,
#
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(1), (2), (3), (4), (5), (6), (7), (8), (9);
}

do_catchsql_test 2.1 {
  SELECT upper(a) FILTER (WHERE a=1) FROM t1
} {1 {FILTER may not be used with non-aggregate upper()}}

do_catchsql_test 2.2 {
  SELECT sum(a) FILTER (WHERE 1 - max(a) OVER () > 0) FROM t1
} {1 {misuse of window function max()}}

do_catchsql_test 2.3 {
  SELECT sum(a) FILTER (WHERE 1 - count(a)) FROM t1
} {1 {misuse of aggregate function count()}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t1(a,b);
  INSERT INTO t1 VALUES(1, 1);
}
do_execsql_test 3.1 {
  SELECT b, max(a) FILTER (WHERE b='x') FROM t1;
} {1 {}}

do_execsql_test 3.2 {
  CREATE TABLE t2(a, b, c);
  INSERT INTO t2 VALUES(1, 2, 3);
  INSERT INTO t2 VALUES(1, 3, 4);
  INSERT INTO t2 VALUES(2, 5, 6);
  INSERT INTO t2 VALUES(2, 7, 8);
}
do_execsql_test 3.3 {
  SELECT a, c, max(b) FILTER (WHERE c='x') FROM t2 GROUP BY a;
} {1 3 {} 2 6 {}}

do_execsql_test 3.4 {
  DELETE FROM t2;
  INSERT INTO t2 VALUES(1, 5, 'x');
  INSERT INTO t2 VALUES(1, 2, 3);
  INSERT INTO t2 VALUES(1, 4, 'x');
  INSERT INTO t2 VALUES(2, 5, 6);
  INSERT INTO t2 VALUES(2, 7, 8);
}
do_execsql_test 3.5 {
  SELECT a, c, max(b) FILTER (WHERE c='x') FROM t2 GROUP BY a;
} {1 x 5 2 6 {}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES('a', 0, 5);
  INSERT INTO t1 VALUES('a', 1, 10);
  INSERT INTO t1 VALUES('a', 0, 15);

  INSERT INTO t1 VALUES('b', 0, 5);
  INSERT INTO t1 VALUES('b', 1, 1000);
  INSERT INTO t1 VALUES('b', 0, 5);

  INSERT INTO t1 VALUES('c', 0, 1);
  INSERT INTO t1 VALUES('c', 1, 2);
  INSERT INTO t1 VALUES('c', 0, 3);
}

do_execsql_test 4.1 {
  SELECT avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY h;
} {2.0 5.0 10.0}
do_execsql_test 4.2 {
  SELECT avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY (h+1.0);
} {2.0 5.0 10.0}
do_execsql_test 4.3 {
  SELECT a, avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY avg(c);
} {c 2.0 a 10.0 b 5.0}
do_execsql_test 4.4 {
  SELECT a, avg(c) FILTER (WHERE b!=1) FROM t1 GROUP BY a ORDER BY 2
} {c 2.0 b 5.0 a 10.0}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(1, 3);
}

do_execsql_test 5.1 {
  SELECT count(*) FILTER (WHERE b>2) FROM (SELECT * FROM t1) 
} {1}

do_execsql_test 5.2 {
  SELECT count(*) FILTER (WHERE b>2) OVER () FROM (SELECT * FROM t1) 
} {1 1}

do_execsql_test 5.3 {
  SELECT count(*) FILTER (WHERE b>2) OVER (ORDER BY b) FROM (SELECT * FROM t1) 
} {0 1}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
  CREATE TABLE t1(a,b);
  INSERT INTO t1 VALUES(1,1);
  INSERT INTO t1 VALUES(2,2);
  CREATE TABLE t2(x,y);
  INSERT INTO t2 VALUES(1,1);
}

do_execsql_test 6.1 {
  SELECT (SELECT COUNT(a) FILTER(WHERE x) FROM t2) FROM t1;
} {1 1}
do_execsql_test 6.2 {
  SELECT (SELECT COUNT(a+x) FROM t2) FROM t1;
} {1 1}
do_execsql_test 6.3 {
  SELECT (SELECT COUNT(a) FROM t2) FROM t1;
} {2}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  INSERT INTO t1 VALUES(321, 100000);
  INSERT INTO t1 VALUES(111, 110000);
  INSERT INTO t1 VALUES(444, 120000);
  INSERT INTO t1 VALUES(222, 130000);
}

do_execsql_test 7.1 {
  SELECT max(a), max(a) FILTER (WHERE b<12345), b FROM t1;
} {
  444 {} 120000
}



finish_test

Deleted test/filter2.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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




































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2018 May 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.
#
#***********************************************************************
#

source [file join [file dirname $argv0] pg_common.tcl]

#=========================================================================


start_test filter2 "2019 July 2"

ifcapable !windowfunc

execsql_test 1.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER);
  INSERT INTO t1 VALUES
   (1, 7), (2, 3), (3, 5), (4, 30), (5, 26), (6, 23), (7, 27),
   (8, 3), (9, 17), (10, 26), (11, 33), (12, 25), (13, NULL), (14, 47),
   (15, 36), (16, 13), (17, 45), (18, 31), (19, 11), (20, 36), (21, 37),
   (22, 21), (23, 22), (24, 14), (25, 16), (26, 3), (27, 7), (28, 29),
   (29, 50), (30, 38), (31, 3), (32, 36), (33, 12), (34, 4), (35, 46),
   (36, 3), (37, 48), (38, 23), (39, NULL), (40, 24), (41, 5), (42, 46),
   (43, 11), (44, NULL), (45, 18), (46, 25), (47, 15), (48, 18), (49, 23);
}

execsql_test 1.1 { SELECT sum(b) FROM t1 }

execsql_test 1.2 { SELECT sum(b) FILTER (WHERE a<10) FROM t1 }

execsql_test 1.3 { SELECT count(DISTINCT b) FROM t1 }

execsql_test 1.4 { SELECT count(DISTINCT b) FILTER (WHERE a!=19) FROM t1 }

execsql_test 1.5 { 
  SELECT min(b) FILTER (WHERE a>19),
         min(b) FILTER (WHERE a>0),
         max(a+b) FILTER (WHERE a>19),
         max(b+a) FILTER (WHERE a BETWEEN 10 AND 40)
  FROM t1;
}

execsql_test 1.6 { 
  SELECT min(b),
         min(b),
         max(a+b),
         max(b+a)
  FROM t1
  GROUP BY (a%10)
  ORDER BY 1, 2, 3, 4;
}

execsql_test 1.7 { 
  SELECT min(b) FILTER (WHERE a>19),
         min(b) FILTER (WHERE a>0),
         max(a+b) FILTER (WHERE a>19),
         max(b+a) FILTER (WHERE a BETWEEN 10 AND 40)
  FROM t1
  GROUP BY (a%10)
  ORDER BY 1, 2, 3, 4;
}

execsql_test 1.8 { 
  SELECT sum(a+b) FILTER (WHERE a=NULL) FROM t1
}

execsql_test 1.9 {
  SELECT (a%5) FROM t1 GROUP BY (a%5) 
  HAVING sum(b) FILTER (WHERE b<20) > 34
  ORDER BY 1
}

execsql_test 1.10 {
  SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb
  FROM t1
  GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) >34
  ORDER BY 1
}

execsql_test 1.11 {
  SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb
  FROM t1
  GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) >34
  ORDER BY 2
}

execsql_test 1.12 {
  SELECT (a%5), 
    sum(b) FILTER (WHERE b<20) AS bbb,
    count(distinct b) FILTER (WHERE b<20 OR a=13) AS ccc
  FROM t1 GROUP BY (a%5)
  ORDER BY 2
}

execsql_test 1.13 {
  SELECT 
    string_agg(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=0),
    string_agg(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=1),
    count(*) FILTER (WHERE b%2!=0),
    count(*) FILTER (WHERE b%2!=1)
  FROM t1;
}

execsql_float_test 1.14 {
  SELECT 
    avg(b) FILTER (WHERE b>a),
    avg(b) FILTER (WHERE b<a)
  FROM t1 GROUP BY (a%2) ORDER BY 1,2;
}

execsql_test 1.15 {
  SELECT 
    a/5,
    sum(b) FILTER (WHERE a%5=0),
    sum(b) FILTER (WHERE a%5=1),
    sum(b) FILTER (WHERE a%5=2),
    sum(b) FILTER (WHERE a%5=3),
    sum(b) FILTER (WHERE a%5=4)
  FROM t1 GROUP BY (a/5) ORDER BY 1;
}

finish_test


Deleted test/filter2.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




























































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 July 2
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#

####################################################
# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
####################################################

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix filter2

ifcapable !windowfunc { finish_test ; return }
do_execsql_test 1.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER);
  INSERT INTO t1 VALUES
   (1, 7), (2, 3), (3, 5), (4, 30), (5, 26), (6, 23), (7, 27),
   (8, 3), (9, 17), (10, 26), (11, 33), (12, 25), (13, NULL), (14, 47),
   (15, 36), (16, 13), (17, 45), (18, 31), (19, 11), (20, 36), (21, 37),
   (22, 21), (23, 22), (24, 14), (25, 16), (26, 3), (27, 7), (28, 29),
   (29, 50), (30, 38), (31, 3), (32, 36), (33, 12), (34, 4), (35, 46),
   (36, 3), (37, 48), (38, 23), (39, NULL), (40, 24), (41, 5), (42, 46),
   (43, 11), (44, NULL), (45, 18), (46, 25), (47, 15), (48, 18), (49, 23);
} {}

do_execsql_test 1.1 {
  SELECT sum(b) FROM t1
} {1041}

do_execsql_test 1.2 {
  SELECT sum(b) FILTER (WHERE a<10) FROM t1
} {141}

do_execsql_test 1.3 {
  SELECT count(DISTINCT b) FROM t1
} {31}

do_execsql_test 1.4 {
  SELECT count(DISTINCT b) FILTER (WHERE a!=19) FROM t1
} {31}

do_execsql_test 1.5 {
  SELECT min(b) FILTER (WHERE a>19),
         min(b) FILTER (WHERE a>0),
         max(a+b) FILTER (WHERE a>19),
         max(b+a) FILTER (WHERE a BETWEEN 10 AND 40)
  FROM t1;
} {3 3 88 85}

do_execsql_test 1.6 {
  SELECT min(b),
         min(b),
         max(a+b),
         max(b+a)
  FROM t1
  GROUP BY (a%10)
  ORDER BY 1, 2, 3, 4;
} {3 3 58 58   3 3 66 66   3 3 71 71   3 3 88 88   4 4 61 61   5 5 54 54
  7 7 85 85   11 11 79 79   16 16 81 81   24 24 68 68}

do_execsql_test 1.7 {
  SELECT min(b) FILTER (WHERE a>19),
         min(b) FILTER (WHERE a>0),
         max(a+b) FILTER (WHERE a>19),
         max(b+a) FILTER (WHERE a BETWEEN 10 AND 40)
  FROM t1
  GROUP BY (a%10)
  ORDER BY 1, 2, 3, 4;
} {3 3 58 58   3 3 71 39   4 4 38 61   7 7 85 85   11 5 54 45   16 16 81 81
  18 3 66 61   21 3 88 68   23 11 79 79   24 24 68 68}

do_execsql_test 1.8 {
  SELECT sum(a+b) FILTER (WHERE a=NULL) FROM t1
} {{}}

do_execsql_test 1.9 {
  SELECT (a%5) FROM t1 GROUP BY (a%5) 
  HAVING sum(b) FILTER (WHERE b<20) > 34
  ORDER BY 1
} {3   4}

do_execsql_test 1.10 {
  SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb
  FROM t1
  GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) >34
  ORDER BY 1
} {3 49   4 46}

do_execsql_test 1.11 {
  SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb
  FROM t1
  GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) >34
  ORDER BY 2
} {4 46   3 49}

do_execsql_test 1.12 {
  SELECT (a%5), 
    sum(b) FILTER (WHERE b<20) AS bbb,
    count(distinct b) FILTER (WHERE b<20 OR a=13) AS ccc
  FROM t1 GROUP BY (a%5)
  ORDER BY 2
} {2 25 3   0 34 2   1 34 4   4 46 4   3 49 5}

do_execsql_test 1.13 {
  SELECT 
    group_concat(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=0),
    group_concat(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=1),
    count(*) FILTER (WHERE b%2!=0),
    count(*) FILTER (WHERE b%2!=1)
  FROM t1;
} {7_3_5_23_27_3_17_33_25_47_13_45_31_11_37_21_3_7_29_3_3_23_5_11_25_15_23 30_26_26_36_36_22_14_16_50_38_36_12_4_46_48_24_46_18_18 27 19}


do_test 1.14 {
  set myres {}
  foreach r [db eval {SELECT 
    avg(b) FILTER (WHERE b>a),
    avg(b) FILTER (WHERE b<a)
  FROM t1 GROUP BY (a%2) ORDER BY 1,2;}] {
    lappend myres [format %.4f [set r]]
  }
  set res2 {30.8333 13.7273 31.4167 13.0000}
  set i 0
  foreach r [set myres] r2 [set res2] {
    if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
      error "list element [set i] does not match: got=[set r] expected=[set r2]"
    }
    incr i
  }
  set {} {}
} {}

do_execsql_test 1.15 {
  SELECT 
    a/5,
    sum(b) FILTER (WHERE a%5=0),
    sum(b) FILTER (WHERE a%5=1),
    sum(b) FILTER (WHERE a%5=2),
    sum(b) FILTER (WHERE a%5=3),
    sum(b) FILTER (WHERE a%5=4)
  FROM t1 GROUP BY (a/5) ORDER BY 1;
} {0 {} 7 3 5 30   1 26 23 27 3 17   2 26 33 25 {} 47   3 36 13 45 31 11
  4 36 37 21 22 14   5 16 3 7 29 50   6 38 3 36 12 4   7 46 3 48 23 {}
  8 24 5 46 11 {}   9 18 25 15 18 23}

finish_test

Deleted test/filterfault.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












































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2018 May 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.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix filterfault

ifcapable !windowfunc {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c, d);
  INSERT INTO t1 VALUES(1, 2, 3, 4);
  INSERT INTO t1 VALUES(5, 6, 7, 8);
  INSERT INTO t1 VALUES(9, 10, 11, 12);
}
faultsim_save_and_close

do_faultsim_test 1 -faults oom-t* -prep {
  faultsim_restore_and_reopen
} -body {
  execsql {
    SELECT sum(a) FILTER (WHERE b<5),
           count() FILTER (WHERE d!=c) 
      FROM t1 GROUP BY c ORDER BY 1;
  }
} -test {
  faultsim_test_result {0 {{} 1 {} 1 1 1}}
}


finish_test

Changes to test/fkey2.test.

413
414
415
416
417
418
419
420

421
422
423
424
425
426
427

428
429
430
431
432
433
434
413
414
415
416
417
418
419

420
421
422
423
424
425
426

427
428
429
430
431
432
433
434







-
+






-
+







    INSERT INTO ab VALUES(1, 'b');
    INSERT INTO cd VALUES(1, 'd');
    INSERT INTO ef VALUES(1, 'e');
  }
} {}
do_test fkey2-3.1.3 {
  catchsql { UPDATE ab SET a = 5 }
} {1 {CHECK constraint failed: e!=5}}
} {1 {CHECK constraint failed: ef}}
do_test fkey2-3.1.4 {
  execsql { SELECT * FROM ab }
} {1 b}
do_test fkey2-3.1.4 {
  execsql BEGIN;
  catchsql { UPDATE ab SET a = 5 }
} {1 {CHECK constraint failed: e!=5}}
} {1 {CHECK constraint failed: ef}}
do_test fkey2-3.1.5 {
  execsql COMMIT;
  execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
} {1 b 1 d 1 e}

do_test fkey2-3.2.1 {
  execsql BEGIN;
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
951
952
953
954
955
956
957

958
959
960
961
962
963
964







-







drop_all_tables
ifcapable altertable {
  do_test fkey2-14.1.1 {
    # Adding a column with a REFERENCES clause is not supported.
    execsql { 
      CREATE TABLE t1(a PRIMARY KEY);
      CREATE TABLE t2(a, b);
      INSERT INTO t2 VALUES(1,2);
    }
    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
  } {0 {}}
  do_test fkey2-14.1.2 {
    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
  } {0 {}}
  do_test fkey2-14.1.3 {
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
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







-
+









-
+







  # Test the sqlite_rename_parent() function directly.
  #
  proc test_rename_parent {zCreate zOld zNew} {
    db eval {SELECT sqlite_rename_table(
        'main', 'table', 't1', $zCreate, $zOld, $zNew, 0
    )}
  }
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
  do_test fkey2-14.2.1.1 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  do_test fkey2-14.2.1.2 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
  } {{CREATE TABLE t1(a REFERENCES t2)}}
  do_test fkey2-14.2.1.3 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
  
  # Test ALTER TABLE RENAME TABLE a bit.
  #
  do_test fkey2-14.2.2.1 {
    drop_all_tables
    execsql {
      CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1);
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055







-







  #
  drop_all_tables
  do_test fkey2-14.1tmp.1 {
    # Adding a column with a REFERENCES clause is not supported.
    execsql { 
      CREATE TEMP TABLE t1(a PRIMARY KEY);
      CREATE TEMP TABLE t2(a, b);
      INSERT INTO temp.t2 VALUES(1,2);
    }
    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
  } {0 {}}
  do_test fkey2-14.1tmp.2 {
    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
  } {0 {}}
  do_test fkey2-14.1tmp.3 {
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
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







-
+









-
+







      PRAGMA foreign_keys = off;
      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
      PRAGMA foreign_keys = on;
      SELECT sql FROM temp.sqlite_master WHERE name='t2';
    }
  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}

  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
  do_test fkey2-14.2tmp.1.1 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  do_test fkey2-14.2tmp.1.2 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
  } {{CREATE TABLE t1(a REFERENCES t2)}}
  do_test fkey2-14.2tmp.1.3 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
  
  # Test ALTER TABLE RENAME TABLE a bit.
  #
  do_test fkey2-14.2tmp.2.1 {
    drop_all_tables
    execsql {
      CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1);
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1126
1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137
1138
1139







-







  drop_all_tables
  do_test fkey2-14.1aux.1 {
    # Adding a column with a REFERENCES clause is not supported.
    execsql { 
      ATTACH ':memory:' AS aux;
      CREATE TABLE aux.t1(a PRIMARY KEY);
      CREATE TABLE aux.t2(a, b);
      INSERT INTO aux.t2(a,b) VALUES(1,2);
    }
    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
  } {0 {}}
  do_test fkey2-14.1aux.2 {
    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
  } {0 {}}
  do_test fkey2-14.1aux.3 {
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
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







-
+









-
+







      PRAGMA foreign_keys = off;
      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
      PRAGMA foreign_keys = on;
      SELECT sql FROM aux.sqlite_master WHERE name='t2';
    }
  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}

  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
  do_test fkey2-14.2aux.1.1 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  do_test fkey2-14.2aux.1.2 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
  } {{CREATE TABLE t1(a REFERENCES t2)}}
  do_test fkey2-14.2aux.1.3 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
  
  # Test ALTER TABLE RENAME TABLE a bit.
  #
  do_test fkey2-14.2aux.2.1 {
    drop_all_tables
    execsql {
      CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1);

Changes to test/fkey5.test.

11
12
13
14
15
16
17
18

19
20
21


22
23
24
25
26
27
28
11
12
13
14
15
16
17

18
19


20
21
22
23
24
25
26
27
28







-
+

-
-
+
+







# This file implements regression tests for SQLite library.
#
# This file tests the PRAGMA foreign_key_check command.
#
# EVIDENCE-OF: R-15402-03103 PRAGMA schema.foreign_key_check; PRAGMA
# schema.foreign_key_check(table-name);
#
# EVIDENCE-OF: R-41653-15278 The foreign_key_check pragma checks the
# EVIDENCE-OF: R-23918-17301 The foreign_key_check pragma checks the
# database, or the table called "table-name", for foreign key
# constraints that are violated. The foreign_key_check pragma returns
# one row output for each foreign key violation.
# constraints that are violated and returns one row of output for each
# violation.

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fkey5

ifcapable {!foreignkey} {
  finish_test
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
426
427
428
429
430
431
432



























































433







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  CREATE TABLE tt(y);
  CREATE TABLE c11(x REFERENCES tt(y));
}
do_catchsql_test 11.1 {
  PRAGMA foreign_key_check;
} {1 {foreign key mismatch - "c11" referencing "tt"}}

# 2020-07-03 Bug in foreign_key_check discovered while working on the
# forum reports that pragma_foreign_key_check does not accept an argument:
# If two separate schemas seem to reference one another, that causes
# problems for foreign_key_check.
#
reset_db
do_execsql_test 12.0 {
  ATTACH ':memory:' as aux;
  CREATE TABLE aux.t1(a INTEGER PRIMARY KEY, b TEXT REFERENCES t2);
  CREATE TABLE main.t2(x TEXT PRIMARY KEY, y INT);
  INSERT INTO main.t2 VALUES('abc',11),('def',22),('xyz',99);
  INSERT INTO aux.t1 VALUES(5,'abc'),(7,'xyz'),(9,'oops');
  PRAGMA foreign_key_check=t1;
} {t1 5 t2 0 t1 7 t2 0 t1 9 t2 0}
do_execsql_test 12.1 {
  CREATE TABLE aux.t2(x TEXT PRIMARY KEY, y INT);
  INSERT INTO aux.t2 VALUES('abc',11),('def',22),('xyz',99);
  PRAGMA foreign_key_check=t1;
} {t1 9 t2 0}

# 2020-07-03: the pragma_foreign_key_check virtual table should
# accept arguments for the table name and/or schema name.
#
ifcapable vtab {
  do_execsql_test 13.0 {
    SELECT *, 'x' FROM pragma_foreign_key_check('t1');
  } {t1 9 t2 0 x}
  do_catchsql_test 13.1 {
    SELECT *, 'x' FROM pragma_foreign_key_check('t1','main');
  } {1 {no such table: main.t1}}
  do_execsql_test 13.2 {
    SELECT *, 'x' FROM pragma_foreign_key_check('t1','aux');
  } {t1 9 t2 0 x}
}

ifcapable vtab {
  reset_db
    do_execsql_test 13.10 {
      PRAGMA foreign_keys=OFF;
      CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT REFERENCES t2);
      CREATE TABLE t2(x TEXT PRIMARY KEY, y INT);
      CREATE TABLE t3(w TEXT, z INT REFERENCES t1);
      INSERT INTO t2 VALUES('abc',11),('def',22),('xyz',99);
      INSERT INTO t1 VALUES(5,'abc'),(7,'xyz'),(9,'oops');
      INSERT INTO t3 VALUES(11,7),(22,19);
    } {}
  do_execsql_test 13.11 {
    SELECT x.*, '|'
      FROM sqlite_schema, pragma_foreign_key_check(name) AS x
      WHERE type='table'
      ORDER BY x."table";
  } {t1 9 t2 0 | t3 2 t1 0 |}
  do_execsql_test 13.12 {
    SELECT *, '|'
      FROM pragma_foreign_key_check AS x
      ORDER BY x."table";
  } {t1 9 t2 0 | t3 2 t1 0 |}
}

finish_test

Changes to test/fkey7.test.

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
78
79
80
81
82
83
84




































85







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

    INSERT INTO c4 VALUES(1), (2), (3);

    ANALYZE;
    INSERT INTO p4(id) VALUES(4);
  }
}


do_execsql_test 4.0 {
  PRAGMA foreign_keys = true;
  CREATE TABLE parent(
    p PRIMARY KEY
  );
  CREATE TABLE child(
    c UNIQUE REFERENCES parent(p)
  );
}

do_catchsql_test 4.1 {
  INSERT OR FAIL INTO child VALUES(123), (123);
} {1 {FOREIGN KEY constraint failed}}

do_execsql_test 4.2 {
  SELECT * FROM child;
} {}

do_execsql_test 4.3 {
  PRAGMA foreign_key_check;
} {}

do_catchsql_test 4.4 {
  INSERT INTO parent VALUES(123);
  INSERT OR FAIL INTO child VALUES(123), (123);
} {1 {UNIQUE constraint failed: child.c}}

do_execsql_test 4.5 {
  SELECT * FROM child;
} {123}

do_execsql_test 4.6 {
  PRAGMA foreign_key_check;
} {}

finish_test

Changes to test/fkey8.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
231
193
194
195
196
197
198
199




















200







201












-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
-
-
-
-
-
do_catchsql_test 4.1 {
  INSERT OR REPLACE INTO t1 VALUES(10000, 20000);
} {1 {FOREIGN KEY constraint failed}}
do_execsql_test 4.2 {
  INSERT OR REPLACE INTO t1 VALUES(20000, 20000);
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  PRAGMA foreign_keys = true;
  CREATE TABLE parent(
    p TEXT PRIMARY KEY
  );
  CREATE TABLE child(
    c INTEGER UNIQUE, 
    FOREIGN KEY(c) REFERENCES parent(p) DEFERRABLE INITIALLY DEFERRED
  );
  BEGIN;
    INSERT INTO child VALUES(123);
    INSERT INTO parent VALUES('123');
  COMMIT;
}
do_execsql_test 5.1 {
  PRAGMA integrity_check;
} {ok}

finish_test
do_execsql_test 5.2 {
  INSERT INTO parent VALUES(1200);
  BEGIN;
    INSERT INTO child VALUES(456);
    UPDATE parent SET p = '456' WHERE p=1200;
  COMMIT;
}

do_execsql_test 5.3 {
  PRAGMA integrity_check;
} {ok}

finish_test

Changes to test/fordelete.test.

44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58







-
+







    if {$R(opcode)=="OpenWrite"} {
      set root $R(p2)
      set csr $R(p1)
      if {[info exists T($root)]} { set M($csr) $T($root) }

      set obj $T($root)
      set O($obj) ""
      if {$R(p5) & 0x08} { 
      if {"0x$R(p5)" & 0x08} { 
        set O($obj) *
      } else {
        set O($obj) ""
      }
    }
  }

Changes to test/format4.test.

13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
13
14
15
16
17
18
19

20

21
22
23
24
25
26
27







-
+
-







# This file implements tests to verify that the new serial_type
# values of 8 (integer 0) and 9 (integer 1) work correctly.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#db eval {PRAGMA legacy_file_format=OFF}
db eval {PRAGMA legacy_file_format=OFF}
sqlite3_db_config db LEGACY_FILE_FORMAT 0

# The size of the database depends on whether or not autovacuum
# is enabled.
#
ifcapable autovacuum {
  if {[db one {PRAGMA auto_vacuum}]} {
    set small 3072

Changes to test/fts3atoken.test.

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
125
126
127
128
129
130
131























132
133
134
135
136
137
138







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







           typeof(fts3_tokenizer($blah2name)),
           typeof(fts3_tokenizer('blah2')),
           typeof(fts3_tokenizer($simplename)),
           typeof(fts3_tokenizer('simple'));
  }
} {1 blob blob blob blob}

# 2019-12-31:  The fts3_tokenizer() function can never be invoked from
# within a trigger or view.
#
do_catchsql_test fts3atoken-1.10 {
  CREATE VIEW v110(x) AS
      SELECT fts3_tokenizer('tok110', fts3_tokenizer('simple')) IS NULL;
} {0 {}}
do_catchsql_test fts3atoken-1.11 {
  SELECT * FROM v110;
} {1 {unsafe use of fts3_tokenizer()}}
do_catchsql_test fts3atoken-1.12 {
  CREATE TABLE t110(a,b);
  CREATE TRIGGER r110 AFTER INSERT ON t110 BEGIN
      SELECT fts3_tokenizer('tok110', fts3_tokenizer('simple')) IS NULL;
  END;
} {0 {}}
do_catchsql_test fts3atoken-1.13 {
  INSERT INTO t110(a,b) VALUES(1,2);
} {1 {unsafe use of fts3_tokenizer()}}
do_catchsql_test fts3atoken-1.14 {
  SELECT * FROM t110;
} {0 {}}

#--------------------------------------------------------------------------
# Test cases fts3atoken-2.* test error cases in the scalar function based
# API for getting and setting tokenizers.
#
do_test fts3atoken-2.1 {
  catchsql {
    SELECT fts3_tokenizer('nosuchtokenizer');

Changes to test/fts3auto.test.

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
566
567
568
569
570
571
572







573
574
575
576
577
578
579







-
-
-
-
-
-
-







  do_fts3query_test 4.$tn.3.5 -deferred five t1 {one NEAR/3 five}

  do_fts3query_test 4.$tn.4.1 -deferred fi* t1 {on* AND fi*}
  do_fts3query_test 4.$tn.4.2 -deferred fi* t1 {on* NEAR fi*}
  do_fts3query_test 4.$tn.4.3 -deferred fi* t1 {on* NEAR/1 fi*}
  do_fts3query_test 4.$tn.4.4 -deferred fi* t1 {on* NEAR/2 fi*}
  do_fts3query_test 4.$tn.4.5 -deferred fi* t1 {on* NEAR/3 fi*}

  ifcapable fts4_deferred {
    db eval {UPDATE t1_stat SET value=x'' WHERE id=0}
    do_catchsql_test 4.$tn.4.6 {
      SELECT docid FROM t1 WHERE t1 MATCH 'on* NEAR/3 fi*'
    } {1 {database disk image is malformed}}
  }
}

#--------------------------------------------------------------------------
# The following test cases - fts3auto-5.* - focus on using prefix indexes.
#
set chunkconfig [fts3_configure_incr_load 1 1]
foreach {tn create pending} {

Changes to test/fts3corrupt.test.

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
161
162
163
164
165
166
167



























168
169







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


do_test 5.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB
do_catchsql_test 5.3 {
  UPDATE t1_stat SET value = NULL;
  SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*';
} {1 {database disk image is malformed}}
do_test 5.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB

# 2019-11-18 https://bugs.chromium.org/p/chromium/issues/detail?id=1025467
# bug1
db close
sqlite3 db :memory:
do_catchsql_test 6.10 {
  CREATE VIRTUAL TABLE f using fts3(a,b);
  CREATE TABLE f_stat(id INTEGER PRIMARY KEY, value BLOB);
  INSERT INTO f_segdir VALUES (2000, 0,0,0, '16', '');
  INSERT INTO f_segdir VALUES (1999, 0,0,0, '0 18',
                               x'000131030102000103323334050101010200');
  INSERT INTO f_segments (blockid) values (16);
  INSERT INTO f_segments values (0, x'');
  INSERT INTO f_stat VALUES (1,x'cf0f01');
  INSERT INTO f(f) VALUES ("merge=1");
} {1 {database disk image is malformed}}

# 2020-03-02 https://bugs.chromium.org/p/chromium/issues/detail?id=1057441
# The ticket complains of use of an uninitialized value. That part is harmless.
# The only reason to fix this is the failure to detect a subtly corrupt
# inverted index.
#
reset_db
do_catchsql_test 7.10 {
  CREATE VIRTUAL TABLE f USING fts3(a,b);
  INSERT INTO f_segdir VALUES (0,0,1,0,'0 0',x'01010101020101');
  SELECT  matchinfo( f , 'pcx')  FROM f WHERE b MATCH x'c533';
} {1 {database disk image is malformed}}

finish_test

Changes to test/fts3corrupt2.test.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25







-







set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
ifcapable !fts3 { finish_test ; return }

set ::testprefix fts3corrupt2
sqlite3_fts3_may_be_corrupt 1

set data [list]
lappend data {*}{
   "amxtvoo adqwroyhz auq aithtir avniqnuynvf axp ahibayfynig agbicpm"
   "ajdtebs anteaxr aieynenwmd awpl alo akxcrwow aoxftge aoqvgul"
   "amcfvdr auz apu aebelm ahuxyz aqc asyafdb agulvhvqu"
   "apepwfyz azkhdvkw aenyelxzbk aslnitbyet aycdsdcpgr aqzzdbc agfi axnypydou"
99
100
101
102
103
104
105

106
107
108
109
110
111
98
99
100
101
102
103
104
105
106
107
108
109
110
111







+






        catchsql { SELECT * FROM t2 WHERE t2 MATCH 'a*' }
        set {} {}
      } {}
    }
    execsql { UPDATE t2_segdir SET root = $blob WHERE rowid = $rowid }
  }
}






finish_test

Changes to test/fts3corrupt4.test.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
22
23
24
25
26
27
28


29
30
31
32
33
34
35







-
-







# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
  finish_test
  return
}

sqlite3_fts3_may_be_corrupt 1
database_may_be_corrupt
extra_schema_checks 0

do_execsql_test 1.0 {
  BEGIN;
    CREATE VIRTUAL TABLE ft USING fts3;
    INSERT INTO ft VALUES('aback');
    INSERT INTO ft VALUES('abaft');
    INSERT INTO ft VALUES('abandon');
1944
1945
1946
1947
1948
1949
1950
1951

1952
1953
1954
1955
1956
1957
1958
1942
1943
1944
1945
1946
1947
1948

1949
1950
1951
1952
1953
1954
1955
1956







-
+







|   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 6d 69 7a 65   uild....optimize
| end crash-c666cfde112dee.db
}]} {}

do_catchsql_test 13.1 {
  SELECT quote(matchinfo(t1,'pcxybs'))==0 FROM t1 WHERE b MATCH 'e*';
} {0 {}}
} {0 {0 0}}

#-------------------------------------------------------------------------
reset_db
do_test 14.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename crash-f7b636a855e1d2.db
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2142
2143
2144
2145
2146
2147
2148

2149
2150
2151
2152
2153
2154
2155







-







| page 7 offset 24576
|      0: 0d 00 00 00 01 0f f7 00 0f f7 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 00 00 07 00 03 00 14 08 45 b5 03   .............E..
| end crash-f7b636a855e1d2.db
}]} {}

do_execsql_test 14.1 {
  PRAGMA writable_schema = 1;
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10)
    INSERT INTO t1(a) SELECT randomblob(3000) FROM c;
}

do_catchsql_test 14.2 {
  INSERT INTO t1(t1) VALUES('optimize');
} {1 {database disk image is malformed}}
2825
2826
2827
2828
2829
2830
2831
2832

2833
2834
2835
2836
2837
2838
2839
2822
2823
2824
2825
2826
2827
2828

2829
2830
2831
2832
2833
2834
2835
2836







-
+







|     16: 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 75 69 6c   -check....rebuil
|     32: 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 00 00 00   d....optimize...
| end crash-4ce32d0608aff1.db
}]} {}

do_catchsql_test 18.1 {
  SELECT quote(matchinfo(t1,'pcxybs'))==0 FROM t1 WHERE b MATCH 'e*';
} {0 {}}
} {0 0}

#-------------------------------------------------------------------------
reset_db
do_test 19.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename crash-526ea445f41c02.db
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3044
3045
3046
3047
3048
3049
3050

3051
3052
3053
3054
3055
3056
3057







-







|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+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 6d 69 7a 65   uild....optimize
| end crash-526ea445f41c02.db
}]} {}

do_catchsql_test 19.1 {
  PRAGMA writable_schema = 1;
  SELECT rowid,a,c,snippet(t1,85101090932165,-1,10) FROM t1 WHERE a MATCH 'rtree';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 20.0 {
  sqlite3 db {}
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3245
3246
3247
3248
3249
3250
3251

3252
3253
3254
3255
3256
3257
3258







-







| page 7 offset 24576
|      0: 0d 00 00 00 01 0f f7 00 0f f7 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 00 00 07 00 03 00 14 08 45 b5 03   .............E..
| end crash-afecd03c862e58.db
}]} {}

do_execsql_test 20.1 {
  PRAGMA writable_schema = 1;
  BEGIN;
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10)
    INSERT INTO t1(a) SELECT randomblob(3000) FROM c;
}

do_execsql_test 20.2 {
  INSERT INTO t1(t1) VALUES('optimize');
3472
3473
3474
3475
3476
3477
3478

3479
3480
3481
3482
3483
3484
3485
3486
3487
3467
3468
3469
3470
3471
3472
3473
3474
3475

3476
3477
3478
3479
3480
3481
3482







+

-







|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+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 00 00 00 00 00 00 00 00   uild............
| end crash-18cc014e42e828.db
}]} {}

breakpoint
do_catchsql_test 21.1 {
  PRAGMA writable_schema = 1;
  SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'R*';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 22.0 {
  sqlite3 db {}
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3689
3690
3691
3692
3693
3694
3695

3696
3697
3698
3699
3700
3701
3702







-







|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+integr
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
| end crash-b794c89d922ac9.db
}]} {}

do_catchsql_test 22.1 {
  PRAGMA writable_schema = 1;
  SELECT snippet(t1,'', '', '--',-1,01)==0
    FROM t1 WHERE a MATCH 'rtree OR json1rtree OR json1';
} {0 {0 0 0 0 0 0 0}}

#-------------------------------------------------------------------------
reset_db
do_test 23.0 {
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
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
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
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
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
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
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
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
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
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
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
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
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
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
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
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
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
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
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
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
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
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
5878
5879
5880
5881
5882
5883
5884
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
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
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
6082
6083
6084
6085
6086
6087
6088
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
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
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
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

3908
3909
3910
3911
3912
3913
3914

3915
3916
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































3917
3918
3919







-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


+
|   4032: 6d 65 71 97 65 3d 35 0d 04 02 23 6d 65 72 67 65   meq.e=5...#merge
|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+integr
|   4064: 69 74 79 00 00 00 00 00 00 00 00 00 00 00 00 00   ity.............
| end crash-670b15f2955a36.db
}]} {}

do_catchsql_test 23.1 {
  PRAGMA writable_schema = 1;
  SELECT 'FyzLy'FROM t1 WHERE t1 MATCH 'j';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 24.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-369d042958c29b.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 03 10 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 0e b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72   .5tablet1_segdir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52   r'(level INTEGER
|   3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61   ,idx INTEGER,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74   ock INTEGER,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74   ..E...indexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 10 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e   ..tablet1_segmen
|   3792: 64 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52   dst1_segments.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59    INTEGER PRIMARY
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 4f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1Ocontentt1_cont
|   3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 39 4d   cid INTEGER PR9M
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06   'c1b', 'c2c')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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 26 0b 48 0e 0f d8 0f af 0f 86 0f 74   ....&.H........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 0d ef 0d d5   ...t.[.@.$......
|     48: 0d bb 0d a0 0e 94 03 28 0d 4f 0d 35 0d 1b 05 0b   .......(.O.5....
|     64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a   .......x.W.>.$..
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 72 7f 00   .........?%..r..
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 55 42   4.0 20160609 DUB
|   2928: 55 47 20 45 4e 41 e4 7c 45 20 44 42 53 54 41 54   UG ENA.|E DBSTAT
|   2944: e4 d1 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53   ..TAB ENABLE FTS
|   2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   4 ENABLE FTS5 EN
|   2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   ABLE GEOPOLY ENA
|   2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45   BLE JSON1 ENABLE
|   3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20    MEMSYS5 ENABLE 
|   3024: 42 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59   BTREE MAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4c 49 54 20 4c   =50000000 OLIT L
|   3056: 4f 41 43 20 45 58 54 45 4e 53 49 4f 4e 21 54 48   OAC EXTENSION!TH
|   3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f   READSAFE=0.$..%.
|   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 4b 75 3d 30 58 4d 4f 43 41 53 45 17 22   DSAKu=0XMOCASE..
|   3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 46 3d   ..%..THREADSAFF=
|   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 52 49 4f   IT LOAD EXTENRIO
|   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 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT 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 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 42 b8 20 4d 45 4d 4f 52 59 3d 35 30 30   ..MB. 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 0d a5 0f 19 45 4e 41 42   INARY.......ENAB
|   3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17   LE RTREEXNOCASE.
|   3408: 19 1c 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 14 05 01 25   MSYS5XRTRIM....%
|   3520: 0f 19 45 4e 12 42 4c 45 20 4a 53 4f 4e 31 58 42   ..EN.BLE JSON1XB
|   3536: 49 4e 41 52 59 18 14 05 00 25 09 d9 45 4e 41 42   INARY....%..ENAB
|   3552: 4c 45 20 4a 53 4f 3e 31 58 4e 4f 43 41 53 45 17   LE JSO>1XNOCASE.
|   3568: 13 05 00 25 0f 17 45 4e 40 42 4c 45 20 4a 53 4f   ...%..EN@BLE JSO
|   3584: 4e 31 58 52 54 52 49 4d 1a 12 05 82 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 c9 29 e8 19 46 4e 41 42 4c   NARY....)..FNABL
|   3632: 48 c0 47 45 4f 50 4f 4c 59 58 4e 74 43 41 53 45   H.GEOPOLYXNtCASE
|   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 30 46 54 53 35 58 42 49   ..ENABLE0FTS5XBI
|   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 0e 05   E FTS5XNOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   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 42 42 4c 45 20 44 42 53   ...1..ENBBLE 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 4a 4d 11 06   TAT VTABXRTRJM..
|   3920: 05 f0 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52   .....DEBUGXBINAR
|   3936: 59 11 05 05 00 17 0e 19 44 45 42 55 47 58 4e 4f   Y.......DEBUGXNO
|   3952: 43 41 53 45 10 04 05 00 17 0f 16 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 06 00 43 0f 17 43   9XNOCASE&...C..C
|   4064: 4f 4d 50 49 4b 45 52 3d 67 63 63 2d 35 2e 34 2e   OMPIKER=gcc-5.4.
|   4080: 30 20 32 30 31 36 30 36 40 39 58 29 54 52 49 4d   0 201606@9X)TRIM
| page 4 offset 12288
|      0: 0d 00 10 00 00 10 00 00 00 00 00 00 00 01 00 00   ................
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33   ...........0 253
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36   ..0.%.....201606
|   3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35   09.%....4.%....5
|   3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a   .%....0000000.%.
|   3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00   ...compiler.%...
|   3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75   .dbstat.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09   g.%....enable.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f   .eopoly.%....jso
|   3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6e 6f 72 79   ..max.%....enory
|   3184: 03 25 19 00 03 04 ce 79 73 4d 03 25 15 00 00 04   .%.....ysM.%....
|   3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   omit.%....rtree.
|   3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03   %....threadsafe.
|   3232: 25 0e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01   %....vtab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 09   ................
|   3280: 51 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07   Q....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04   ......5.........
|   3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04   ...0000000......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3376: 00 03 01 02 02 00 02 f1 02 02 00 03 01 02 02 00   ................
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69   ...........compi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 67   ler............g
|   3440: d2 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   .stat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 6f 82 6c 65 3f 07 02 00 01 02 00 01 02   .eno.le?........
|   3488: b0 01 02 00 01 02 00 11 02 00 01 02 00 01 02 00   ................
|   3504: 01 02 00 01 02 00 01 02 00 01 a6 00 01 02 00 01   ................
|   3520: 02 05 51 02 00 01 02 00 01 02 00 01 02 00 01 02   ..Q.............
|   3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 00 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 6f 70 73 6c 79 09   .........eopsly.
|   3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64   ............load
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79   ...........emory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 12 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00   ................
|   3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00   ................
|   3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   .omit...........
|   3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00   .rtree..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02   ...threadsafe...
|   3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04   .........vtab...
|   3904: 00 01 04 00 01 03 ff ff 01 78 b4 01 01 01 01 02   .........x......
|   3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 02 00 01 01 01 07 30 01 01 01 02 00 01 01   ........0.......
|   3968: 01 02 00 11 01 01 02 00 01 01 01 02 00 11 01 01   ................
|   3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 01 ff 01 01 01 02 00 01 01 01 02 00 01   ................
|   4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 09 c2 00 01 01 01 02 00 01 01 01   ................
|   4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| page 7 offset 24576
|      0: 0d 00 00 00 05 0f b8 00 0e f4 0f e9 10 d6 0f c7   ................
|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f   ...........#auto
|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00   =1..............
| end crash-369d042958c29b.db
}]} {}

do_catchsql_test 24.1 {
  PRAGMA writable_schema = 1;
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT '4hE'+x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {1 {database disk image is malformed}}

do_catchsql_test 24.2 {
  UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h';
} {0 {}}

do_catchsql_test 24.3 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {1 {database disk image is malformed}}

do_catchsql_test 24.4 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT null<<x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {0 {}}

do_catchsql_test 24.5 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {1 {database disk image is malformed}}

do_catchsql_test 24.7 {
  INSERT INTO t1(t1) SELECT x FROM t2;
} {0 {}}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
reset_db
do_test 25.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-dde9e76ed8ab2d.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 03 10 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 0e b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72   .5tablet1_segdir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52   r'(level INTEGER
|   3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61   ,idx INTEGER,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74   ock INTEGER,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74   ..E...indexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e   ..tablet1_segmen
|   3792: 64 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52   dst1_segments.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59    INTEGER PRIMARY
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1_contentt1_cont
|   3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 39 4d   cid INTEGER PR9M
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06   'c1b', 'c2c')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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 26 0b 48 0e 0f d8 0f af 0f 86 0f 74   ....&.H........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 0d ef 0d d5   ...t.[.@.$......
|     48: 0d bb 0d a0 0e 94 03 28 0d 4f 0d 35 0d 1b 05 0b   .......(.O.5....
|     64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a   .......x.W.>.$..
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 72 7f 00   .........?%..r..
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 55 42   4.0 20160609 DUB
|   2928: 55 47 20 45 4e 41 e4 7c 45 20 44 42 53 54 41 54   UG ENA.|E DBSTAT
|   2944: e4 46 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53   .FTAB ENABLE FTS
|   2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   4 ENABLE FTS5 EN
|   2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   ABLE GEOPOLY ENA
|   2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45   BLE JSON1 ENABLE
|   3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20    MEMSYS5 ENABLE 
|   3024: 42 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59   BTREE MAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4c 49 54 20 4c   =50000000 OLIT L
|   3056: 4f 41 43 20 45 58 54 45 4e 53 49 4f 4e 21 54 48   OAC EXTENSION!TH
|   3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f   READSAFE=0.$..%.
|   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 4b 75 3d 30 58 4d 4f 43 41 53 45 17 22   DSAKu=0XMOCASE..
|   3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 46 3d   ..%..THREADSAFF=
|   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 52 49 4f   IT LOAD EXTENRIO
|   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 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT 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 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 42 b8 20 4d 45 4d 4f 52 59 3d 35 30 30   ..MB. 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 0d a5 0f 19 45 4e 41 42   INARY.......ENAB
|   3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17   LE RTREEXNOCASE.
|   3408: 19 1c 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 14 05 01 25   MSYS5XRTRIM....%
|   3520: 0f 19 45 4e 12 42 4c 45 20 4a 53 4f 4e 31 58 42   ..EN.BLE JSON1XB
|   3536: 49 4e 41 52 59 18 14 05 00 25 09 d9 45 4e 41 42   INARY....%..ENAB
|   3552: 4c 45 20 4a 53 4f 3e 31 58 4e 4f 43 41 53 45 17   LE JSO>1XNOCASE.
|   3568: 13 05 00 25 0f 17 45 4e 40 42 4c 45 20 4a 53 4f   ...%..EN@BLE JSO
|   3584: 4e 31 58 52 54 52 49 4d 1a 12 05 82 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 c9 29 e8 19 46 4e 41 42 4c   NARY....)..FNABL
|   3632: 48 c0 47 45 4f 50 4f 4c 59 58 4e 74 43 41 53 45   H.GEOPOLYXNtCASE
|   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 30 46 54 53 35 58 42 49   ..ENABLE0FTS5XBI
|   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 0e 05   E FTS5XNOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   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 42 42 4c 45 20 44 42 53   ...1..ENBBLE 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 4a 4d 11 06   TAT VTABXRTRJM..
|   3920: 05 f0 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52   .....DEBUGXBINAR
|   3936: 59 11 05 05 00 17 0e 19 44 45 42 55 47 58 4e 4f   Y.......DEBUGXNO
|   3952: 43 41 53 45 10 04 05 00 17 0f 16 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 06 00 43 0f 17 43   9XNOCASE&...C..C
|   4064: 4f 4d 50 49 4b 45 52 3d 67 63 63 2d 35 2e 34 2e   OMPIKER=gcc-5.4.
|   4080: 30 20 32 30 31 36 30 36 40 39 58 29 54 52 49 4d   0 201606@9X)TRIM
| page 4 offset 12288
|      0: 0d 00 10 00 00 10 00 00 00 00 00 00 00 01 00 00   ................
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33   ...........0 253
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36   ..0.%.....201606
|   3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35   09.%....4.%....5
|   3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a   .%....0000000.%.
|   3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00   ...compiler.%...
|   3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75   .dbstat.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09   g.%....enable.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f   .eopoly.%....jso
|   3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6e 6f 72 79   ..max.%....enory
|   3184: 03 25 19 00 03 04 ce 79 73 4d 03 25 15 00 00 04   .%.....ysM.%....
|   3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   omit.%....rtree.
|   3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03   %....threadsafe.
|   3232: 25 0e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01   %....vtab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 09   ................
|   3280: 51 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07   Q....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04   ......5.........
|   3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04   ...0000000......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3376: 00 03 01 02 02 00 02 f1 02 02 00 03 01 02 02 00   ................
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69   ...........compi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 67   ler............g
|   3440: d2 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   .stat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 6f 82 6c 65 3f 07 02 00 01 02 00 01 02   .eno.le?........
|   3488: b0 01 02 00 01 02 00 11 02 00 01 02 00 01 02 00   ................
|   3504: 01 02 00 01 02 00 01 02 00 01 a6 00 01 02 00 01   ................
|   3520: 02 05 51 02 00 01 02 00 01 02 00 01 02 00 01 02   ..Q.............
|   3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 00 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 6f 70 73 6c 79 09   .........eopsly.
|   3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64   ............load
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79   ...........emory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 12 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00   ................
|   3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00   ................
|   3776: 0e 9f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   ..mit...........
|   3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00   .rtree..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02   ...threadsafe...
|   3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04   .........vtab...
|   3904: 00 01 04 00 01 04 00 00 01 78 b4 01 01 01 01 02   .........x......
|   3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 02 00 01 01 01 07 30 01 01 01 02 00 01 01   ........0.......
|   3968: 01 02 00 11 01 01 02 00 01 01 01 02 00 11 01 01   ................
|   3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 01 ff 01 01 01 02 00 01 01 01 02 00 01   ................
|   4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| page 7 offset 24576
|      0: 0d 00 00 00 05 0f b8 00 0e f4 0f e9 10 d6 0f c7   ................
|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f   ...........#auto
|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00   =1..............
| end crash-dde9e76ed8ab2d.db
}]} {}

do_catchsql_test 25.1 {
  PRAGMA writable_schema = 1;
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x%1 FROM c WHERE x<599237)
    INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ;
} {0 {}}

do_catchsql_test 25.2 {
  UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h*';
} {0 {}}

do_catchsql_test 25.3 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x +x FROM c WHERE 72<x)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {0 {}}

do_catchsql_test 25.4 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x%1 FROM c WHERE 599237<x)
    INSERT INTO t1(a) SELECT randomblob(3000) FROM t2 ;
} {0 {}}

do_catchsql_test 25.5 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x%1 FROM c WHERE x<599237)
    INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ;
} {0 {}}

do_catchsql_test 25.6 {
  INSERT INTO t1(t1) SELECT x FROM t2;
  INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 26.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-26682721375870.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 b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72   .5tablet1_segdir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 51   r'(level INTEGEQ
|   3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61   ,idx INTEGER,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 62 2c 72 6f 6f 74   ock INTEGEb,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74   ..E...indexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 66 6d 65 6e   ..tablet1_sefmen
|   3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52   tst1_segments.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59    INTEGER PRIMARY
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1_contentt1_cont
|   3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   cid INTEGER PRIM
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06   'c1b', 'c2c')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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74   ....%.H........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 0d ef 00 00   ...t.[.@.$......
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7f 00   .........?%.....
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 23 00 20 32 2f 31 36 30 36 30 39 20 44 45 42   4#. 2/160609 DEB
|   2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54   UG ENABLE DBSTAT
|   2944: 20 56 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53    VTAB ENABLE FTS
|   2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   4 ENABLE FTS5 EN
|   2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   ABLE GEOPOLY ENA
|   2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45   BLE JSON1 ENABLE
|   3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20    MEMSYS5 ENABLE 
|   3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59   RTREE MAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c   =50000000 OMIT L
|   3056: 4f 41 44 20 45 58 54 45 4e 53 59 4f 4e 20 54 48   OAD EXTENSYON TH
|   3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f   READSAFE=0.$..%.
|   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 22   DSAFE=0XNOCASE..
|   3136: 05 00 25 0f 17 54 38 52 45 41 44 53 41 46 45 3d   ..%..T8READSAFE=
|   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 fc 53 49 4f   IT LOAD EXTE.SIO
|   3184: 4e 68 42 49 4e 4a c2 59 1f 20 05 00 33 0f 19 4f   NhBINJ.Y. ..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 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT 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 2f 30 30   MAX MEMORY=50/00
|   3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 48 4e 4f 43 41 53 45 1e 1c 05 00 33   0000HNOCASE....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 58 4e 4f 53 41 53 45 17   LE RTREEXNOSASE.
|   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 42 42   INARY....%..ENBB
|   3552: 4d 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17   ME 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 4e 41 1e 4c   NARY....)..ENA.L
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45   E GEOPOLYXNOCASE
|   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 62 54 52 49 4d 17 0f 05 00 23   OPOLYXbTRIM....#
|   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 fc 35 58 4e 4f 43 41 53 45 16 0d 05   E FT.5XNOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 35   ..#..ENABLE FTS5
|   3792: 58 4e 4f 43 40 53 45 16 0a 05 00 23 0f 17 45 4e   XNOC@SE....#..EN
|   3808: 41 42 4c 45 20 56 54 53 34 58 52 54 52 49 4d 1e   ABLE VTS4XRTRIM.
|   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 b3 58 1e   TAT VTABXBINA.X.
|   3856: 08 05 00 31 0f 19 45 4e 40 42 4c 45 20 44 42 53   ...1..EN@BLE 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 45 42 53   ...1..ENABLE EBS
|   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 4b 19 4e 41 52 59 27   20160609XK.NARY'
|   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
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 34 33   ...........0 243
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36   ..0.%.....201606
|   3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35   09.%....4.%....5
|   3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a   .%....0000000.%.
|   3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00   ...compiler.%...
|   3056: 06 64 62 73 74 51 74 03 25 0a 00 01 04 65 62 75   .dbstQt.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09   g.%....enable.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f   .eopoly.%....jso
|   3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79   ..max.%....emory
|   3184: 03 25 19 00 03 04 73 79 73 35 03 25 15 00 00 04   .%....sys5.%....
|   3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   omit.%....rtree.
|   3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03   %....threadsafe.
|   3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01   %....vtab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1e f3 00 01 03 00   ................
|   3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07   .....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04   ......5.........
|   3328: 00 01 07 30 30 30 30 2f 30 30 09 1c 04 00 01 04   ...0000/00......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3376: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00   ................
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69   ...........compi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64   ler............d
|   3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   bstat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 61 62 6c 65 3f 07 02 00 01 02 00 01 02   .enable?........
|   3488: 00 01 02 00 01 02 00 01 01 f0 01 02 00 57 02 00   .............W..
|   3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 10 01   ................
|   3520: 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02   ................
|   3536: 00 00 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 03 00 a9 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09   .........eopoly.
|   3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64   ............load
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 0b 31 02 00 01 02 00 01 05 65 6d 6f 72 79   ...1.......emory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 f3 01 02 02 00 03 01 02 02 00   ................
|   3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00   ................
|   3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   .omit...........
|   3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00   .rtree..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 63 61 66 65 09 22 02   ...threadcafe...
|   3888: 00 01 02 00 02 02 00 00 04 76 74 61 62 09 07 04   .........vtab...
|   3904: 00 01 04 00 01 04 00 00 01 78 b4 01 01 01 01 02   .........x......
|   3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   3968: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 02 00 01 01 01 02 00 01 00 01 02 00 01   ................
|   4032: 01 01 02 00 01 01 00 e2 00 01 01 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| page 7 offset 24576
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 00 00 00   ...........#a...
| end crash-26682721375870.db
}]} {}

do_execsql_test 26.1 {
  PRAGMA writable_schema = 1;
  SELECT count(*) FROM (
    SELECT t1, (t1) FROM t1 WHERE b MATCH 'x'
  )
} 34

#-------------------------------------------------------------------------
reset_db
do_test 27.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-23ddd777a03bfd.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 b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72   .5tablet1_segdir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52   r'(level INTEGER
|   3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61   ,idx INTEGER,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74   ock INTEGER,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74   ..E...indexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e   ..tablet1_segmen
|   3792: 64 73 74 31 5f 73 65 67 6d 65 6e 73 73 04 43 52   dst1_segmenss.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 4e 72 59    INTEGER PRIMNrY
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1_contentt1_cont
|   3904: 65 6e 74 04 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 39 4d   cid INTEGER PR9M
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06   'c1b', 'c2c')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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 26 0b 48 0e 0f d8 0f af 0f 86 0f 74   ....&.H........t
|     16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e 00 00 00 00 00   .a.N./..........
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 72 7f 00   .........?%..r..
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 55 42   4.0 20160609 DUB
|   2928: 55 47 20 45 4e 41 e4 7c 45 20 44 42 53 54 41 54   UG ENA.|E DBSTAT
|   2944: e4 46 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53   .FTAB ENABLE FTS
|   2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   4 ENABLE FTS5 EN
|   2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   ABLE GEOPOLY ENA
|   2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45   BLE JSON1 ENABLE
|   3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20    MEMSYS5 ENABLE 
|   3024: 42 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59   BTREE MAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4c 49 54 20 4c   =50000000 OLIT L
|   3056: 4f 41 43 20 45 58 54 45 4e 53 49 4f 4e 21 54 48   OAC EXTENSION!TH
|   3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f   READSAFE=0.$..%.
|   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 4b 75 3d 30 58 4d 4f 43 41 53 45 17 22   DSAKu=0XMOCASE..
|   3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 46 3d   ..%..THREADSAFF=
|   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 52 49 4f   IT LOAD EXTENRIO
|   3184: 4e 58 42 49 4e 41 52 59 0f 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 43 49   MIT LOAD EXTENCI
|   3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17   ONXNOCASE....3..
|   3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT LOAD EXTENS
|   3248: 49 4f 4e 58 52 5d 12 49 4d 1f 1e 05 00 33 0f 19   IONXR].IM....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 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 4f 4f 43 41 53 45 1e 1c 05 00 33   0000XOOCASE....3
|   3328: 0f 17 4d 41 b8 20 4d 45 4d 4f 52 59 3d 35 30 3c   ..MA. MEMORY=50<
|   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 0d a5 0f 19 45 4e 41 42   INARY.......ENAB
|   3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17   LE RTREEXNOCASE.
|   3408: 19 1c 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 53 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c   NASY....)..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 14 05 01 25   MSYS5XRTRIM....%
|   3520: 0f 19 45 4e 12 42 4c 45 20 4a 53 4f 4e 31 58 42   ..EN.BLE JSON1XB
|   3536: 49 4e 41 52 59 18 14 05 00 25 09 d9 45 4e 41 42   INARY....%..ENAB
|   3552: 4c 45 20 4a 53 4f 3e 31 58 4e 4f 43 41 53 45 17   LE JSO>1XNOCASE.
|   3568: 13 05 00 25 0f 17 45 4e 40 42 4c 45 20 4a 53 4f   ...%..EN@BLE JSO
|   3584: 4e 31 58 52 54 52 49 4d 1a 12 05 82 29 0f 19 45   N1XRTRIM....)..E
|   3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4d 59 58 42 49   NABLE GEOPOMYXBI
|   3616: 4e 41 52 59 1a 11 05 c9 29 e8 19 46 4e 41 42 4c   NARY....)..FNABL
|   3632: 48 c0 47 45 4f 50 4f 4c 59 58 4e 74 43 41 53 45   H.GEOPOLYXNtCASE
|   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 30 46 54 53 35 58 42 49   ..ENABLE0FTS5XBI
|   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 4a e1 53 45 16 0e 05   E FTS5XNOJ.SE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   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 55 4e   XNOCASE....#..UN
|   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 42 42 4c 45 20 44 42 53   ...1..ENBBLE 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 4a 4d 11 06   TAT VTABXRTRJM..
|   3920: 05 f0 17 0f 29 44 45 42 55 47 58 42 49 4e 41 52   ....)DEBUGXBINAR
|   3936: 59 11 05 05 00 17 0e 19 44 45 42 55 47 58 4e 4f   Y.......DEBUGXNO
|   3952: 43 41 53 45 10 04 05 00 17 0f 16 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 06 00 43 0f 17 43   9XNOCASE&...C..C
|   4064: 4f 4d 50 49 4b 45 52 3d 67 63 63 2d 35 2e 34 2e   OMPIKER=gcc-5.4.
|   4080: 30 20 32 30 31 36 30 36 40 39 58 29 54 52 49 4d   0 201606@9X)TRIM
| page 4 offset 12288
|      0: 0d 00 10 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
|     16: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33   ...........0 253
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36   ..0.%.....201606
|   3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35   09.%....4.%....5
|   3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a   .%....0000000.%.
|   3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00   ...compiler.%...
|   3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75   .dbstat.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 7c 65 09 25 09   g.%....enab|e.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f   .eopoly.%....jso
|   3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6e 6f 72 79   ..max.%....enory
|   3184: 03 25 19 00 03 04 ce 79 73 4d 03 25 15 00 00 04   .%.....ysM.%....
|   3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   omit.%....rtree.
|   3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03   %....threadsafe.
|   3232: 25 0e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01   %....vtab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00   ................
|   3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07   .....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04   ......5.........
|   3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04   ...0000000......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3376: 00 03 01 02 02 00 02 f1 02 02 00 03 01 02 02 00   ................
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 01 f2 00 03 01 02 02 00 00 08 63 6f 6d 70 69   ...........compi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 67   ler............g
|   3440: d2 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   .stat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 6f 82 6c 65 3f 07 02 00 01 02 00 01 02   .eno.le?........
|   3488: b0 01 02 00 01 02 00 11 0a f0 01 02 00 01 02 00   ................
|   3504: 01 02 00 01 02 00 01 02 00 01 a6 00 01 02 00 02   ................
|   3520: 02 05 51 02 00 01 02 00 01 02 00 01 02 00 01 02   ..Q.............
|   3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 00 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 6f 70 73 6c 79 09   .........eopsly.
|   3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64   ............load
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79   ...........emory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 12 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00   ................
|   3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00   ................
|   3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   .omit...........
|   3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00   .rtree..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 01 e3 01 02 02 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02   ...threadsafe...
|   3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04   .........vtab...
|   3904: 00 01 04 00 01 04 00 00 01 78 b4 01 01 01 01 02   .........x......
|   3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 01 f0 01 01 01 07 30 01 01 01 02 00 01 01   ........0.......
|   3968: 01 02 00 ea 01 01 02 00 01 01 01 02 00 11 01 01   ................
|   3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 01 ff 01 01 01 02 00 01 01 01 02 00 01   ................
|   4032: 01 01 02 00 01 11 01 02 00 01 01 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 01 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| page 7 offset 24576
|      0: 0d 00 00 00 05 0f b8 00 0e f4 0f e9 10 d6 0f c7   ................
|   4016: 00 00 00 00 00 00 00 00 0f 85 02 23 61 75 74 6f   ...........#auto
|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00   =1..............
| end crash-23ddd777a03bfd.db
}]} {}

do_catchsql_test 27.2 {
  PRAGMA writable_schema = 1;
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x GLOB 2.16770 FROM x)
    INSERT INTO t1(a) SELECT randomblob(3000) FROM t2 ;
} {1 {database disk image is malformed}}
do_catchsql_test 27.3 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<2.653)
    INSERT INTO t1(a) SELECT randomblob(-current_time) FROM c;
} {1 {database disk image is malformed}}
do_catchsql_test 27.4 {
  UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h*h*';
} {0 {}}
do_catchsql_test 27.5 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<2.653)
    INSERT INTO t1(a) SELECT randomblob(-current_time) FROM c;
} {1 {database disk image is malformed}}
do_catchsql_test 27.5 {
  INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}
do_catchsql_test 27.6 {
  INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 28.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-159ac1ca51ed55.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 b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72   .5tablet1_segdir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52   r'(level INTEGER
|   3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61   ,idx INTEGER,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74   ock INTEGER,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74   ..E...indexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 10 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e   ..tablet1_segmen
|   3792: 64 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52   dst1_segments.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59    INTEGER PRIMARY
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 4f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1Ocontentt1_cont
|   3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 43 a5 52 20 50 52 39 4d   cid INTEC.R PR9M
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06   'c1b', 'c2c')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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 26 0b 48 00 00 00 00 00 00 00 00 00   ....&.H.........
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 72 7f 00   .........?%..r..
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 55 42   4.0 20160609 DUB
|   2928: 55 47 20 45 4e 41 e4 7c 45 20 44 42 53 54 41 54   UG ENA.|E DBSTAT
|   2944: e4 46 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53   .FTAB ENABLE FTS
|   2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   4 ENABLE FTS5 EN
|   2976: 41 42 1f 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   AB.E GEOPOLY ENA
|   2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45   BLE JSON1 ENABLE
|   3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20    MEMSYS5 ENABLE 
|   3024: 42 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59   BTREE MAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4c 49 54 20 4c   =50000000 OLIT L
|   3056: 4f 41 43 20 45 58 54 45 4e 53 49 4f 4e 21 54 48   OAC EXTENSION!TH
|   3072: 52 45 41 44 53 41 46 45 3d 2f 18 24 05 00 25 0f   READSAFE=/.$..%.
|   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 4b 75 3d 30 58 4d 4f 43 41 53 45 17 22   DSAKu=0XMOCASE..
|   3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 46 3d   ..%..THREADSAFF=
|   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 52 49 4f   IT LOAD EXTENRIO
|   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 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT 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 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 42 b8 20 4d 45 4d 4f 52 59 3d 35 30 30   ..MB. MEMORY=500
|   3344: 30 30 30 30 30 58 52 54 52 4a 4d 18 1b 05 00 25   00000XRTRJM....%
|   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 0d a5 0f 19 45 4e 41 42   INARY.......ENAB
|   3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17   LE RTREEXNOCASE.
|   3408: 19 1c 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 14 05 01 25   MSYS5XRTRIM....%
|   3520: 0f 19 45 4e 12 42 4c 45 20 4a 53 4f 4e 31 58 42   ..EN.BLE JSON1XB
|   3536: 49 4e 41 52 59 18 14 05 00 25 09 d9 45 4e 41 42   INARY....%..ENAB
|   3552: 4c 45 20 4a 53 4f 3e 31 58 4e 4f 43 41 53 45 17   LE JSO>1XNOCASE.
|   3568: 13 05 00 25 0f 17 44 4e 40 42 4c 45 20 4a 53 4f   ...%..DN@BLE JSO
|   3584: 4e 31 58 52 54 52 49 4d 1a 12 05 82 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 c9 29 e8 19 46 4e 41 42 4c   NARY....)..FNABL
|   3632: 48 c0 47 45 4f 50 4f 4c 59 58 4e 74 43 41 53 45   H.GEOPOLYXNtCASE
|   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 30 46 54 53 35 58 42 49   ..ENABLE0FTS5XBI
|   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 0e 05   E FTS5XNOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   3776: 04 ff 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 42 42 4c 45 20 44 42 53   ...1..ENBBLE 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 4a 4d 11 06   TAT VTABXRTRJM..
|   3920: 05 f0 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52   .....DEBUGXBINAR
|   3936: 59 11 05 09 b0 17 0e 19 44 45 42 55 47 58 4e 4f   Y.......DEBUGXNO
|   3952: 43 41 53 45 10 04 05 00 17 0f 16 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 4d 67   ...C..COMPILERMg
|   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 06 00 43 0f 17 43   9XNOCASE&...C..C
|   4064: 4f 4d 50 49 4b 45 52 3d 67 63 63 2d 35 2e 34 2e   OMPIKER=gcc-5.4.
|   4080: 30 20 32 30 31 36 30 36 40 39 58 29 54 52 49 4d   0 201606@9X)TRIM
| page 4 offset 12288
|      0: 0d 00 10 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 00 00 00 00 00 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33   ...........0 253
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36   ..0.%.....201606
|   3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35   09.%....4.%....5
|   3024: 03 25 04 00 4d 07 30 30 30 30 30 30 30 03 25 1a   .%..M.0000000.%.
|   3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00   ...compiler.%...
|   3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75   .dbstat.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09   g.%....enable.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 6f 6c 79 03 25 10 ff ff f5 6a 73 6f   .eopoly.%....jso
|   3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 71 78 03 25 18 00 01 05 65 6e 6f 72 79   ..mqx.%....enory
|   3184: 03 25 19 00 03 04 ce 79 73 4d 03 25 15 00 00 04   .%.....ysM.%....
|   3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   omit.%....rtree.
|   3216: 25 17 00 00 0a 7f 08 72 65 61 64 73 61 66 65 03   %......readsafe.
|   3232: 25 0e 00 00 04 76 75 61 62 03 25 0b 00 86 50 01   %....vuab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 09   ................
|   3280: 51 03 00 00 09 32 30 31 36 30 36 30 39 09 01 07   Q....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 05 00 00 01 35 09 01 04 00 01 03 ff 01 04   ......5.........
|   3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04   ...0000000......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3376: 00 03 01 02 02 00 02 f1 02 02 00 03 01 02 02 00   ................
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69   ...........compi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 67   ler............g
|   3440: d2 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   .stat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 6f 82 6c 65 3f 07 02 00 01 02 00 01 02   .eno.le?........
|   3488: b0 01 02 00 00 f2 00 11 02 00 01 02 00 01 02 00   ................
|   3504: 01 02 00 01 02 00 01 02 00 01 a6 00 01 02 00 01   ................
|   3520: 02 05 51 02 00 01 02 00 01 02 00 01 02 00 01 02   ..Q.............
|   3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 00 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 6f 70 73 6c 79 09   .........eopsly.
|   3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64   ............load
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79   ...........emory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 12 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00   ................
|   3760: 0f 71 02 02 00 03 01 02 02 00 03 6f 02 02 00 00   .q.........o....
|   3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   .omit...........
|   3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00   .rtree..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02   ...threadsafe...
|   3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04   .........vtab...
|   3904: 00 01 04 00 01 04 00 00 01 78 b4 01 01 01 01 02   .........x......
|   3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 02 00 01 01 01 07 30 01 01 01 02 00 01 01   ........0.......
|   3968: 01 02 00 11 01 01 02 00 01 01 01 02 00 11 01 01   ................
|   3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 01 ff 01 01 01 02 00 01 01 01 02 00 01   ................
|   4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 00 00 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| page 7 offset 24576
|      0: 0d 00 00 00 05 0f b8 00 0e f4 0f e9 10 d6 0f c7   ................
|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f   ...........#auto
|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00   =1..............
| end crash-159ac1ca51ed55.db
}]} {}

do_catchsql_test 28.1 {
  PRAGMA writable_schema = 1;
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {1 {database disk image is malformed}}

do_catchsql_test 28.2 {
  UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h';
} {0 {}}

do_catchsql_test 28.3 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {1 {database disk image is malformed}}

do_catchsql_test 28.4 {
  WITH c(x) AS (VALUES(1) UNION ALL SELECT 3<<x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {0 {}}

do_catchsql_test 28.5 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {1 {database disk image is malformed}}

do_catchsql_test 28.6 {
  WITH c(x) AS (VALUES(1) UNION ALL SELECT 3<<x FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {0 {}}

do_catchsql_test 28.7 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+3 FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {1 {database disk image is malformed}}

do_catchsql_test 28.8 {
  INSERT INTO t1(t1) SELECT x FROM t2;
} {0 {}}

#-------------------------------------------------------------------------
#
reset_db
do_test 29.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-53f41622dd3bf6.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 b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 54 69 72   .5tablet1_segTir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52   r'(level INTEGER
|   3600: 2c 69 64 78 20 49 4d 54 45 47 45 52 2c 73 74 61   ,idx IMTEGER,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74   ock INTEGER,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74   ..E...indexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e   ..tablet1_segmen
|   3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52   tst1_segments.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59    INTEGER PRIMARY
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1_contentt1_cont
|   3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 39 4d   cid INTEGER PR9M
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 12 06   'c1b', 'c2c')8..
|   3984: 17 11 11 08 5f 74 61 6b 3c 65 74 31 74 31 43 52   ...._tak<et1t1CR
|   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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74   ....%.H........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 0d ef 0d d5   ...t.[.@.$......
|     48: 0d bb 0d a0 0d 84 03 28 0d 4f 0d 35 0d 1b 0c fb   .......(.O.5....
|     64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a   .......x.W.>.$..
|     80: 0b 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00   .H..............
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 72 7f 00   .........?%..r..
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 2e 30 20 32 30 31 36 30 36 30 39 21 44 45 42   4.0 20160609!DEB
|   2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54   UG ENABLE DBSTAT
|   2944: 20 56 54 41 42 20 45 4e 41 42 4c 46 20 46 54 53    VTAB ENABLF FTS
|   2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   4 ENABLE FTS5 EN
|   2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   ABLE GEOPOLY ENA
|   2992: 42 4c 55 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45   BLU JSON1 ENABLE
|   3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20    MEMSYS5 ENABLE 
|   3024: 52 54 52 45 45 56 4d 41 58 20 4d 45 4d 4f 52 59   RTREEVMAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c   =50000000 OMIT L
|   3056: 4f 42 43 20 45 58 54 45 4e 53 49 4f 4e 20 54 48   OBC EXTENSION TH
|   3072: 52 45 41 44 53 41 46 45 3d 40 18 24 05 00 25 0f   READSAFE=@.$..%.
|   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 31 58 4e 4f 43 41 53 45 17 22   DSAFE=1XNOCASE..
|   3136: 05 00 25 0f 17 54 48 52 45 41 44 43 41 46 45 3d   ..%..THREADCAFE=
|   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 48   MIT LOAD EXTENSH
|   3216: cf 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17   .NXNOCASE....3..
|   3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT 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 2d 35 30 30 30 30   MAX MEMORY-50000
|   3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 49 18 1a 05 0d a5 0f 19 45 4e 41 42   INARI.......ENAB
|   3392: 4c 45 20 52 54 52 45 45 58 4e 4f be 31 53 45 17   LE RTREEXNO.1SE.
|   3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 51   ...%..ENABLE RTQ
|   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 37 f8 52 54 52 49 4d 18 14 05 00 25   MSYS7.RTRIM....%
|   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 3e 31 58 4e 4f 43 41 53 45 17   LE JSO>1XNOCASE.
|   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 4e 41 42 4c   NARY....)..ENABL
|   3632: 48 c0 47 45 4f 50 4f 4c 40 58 4e 4f 43 41 53 45   H.GEOPOL@XNOCASE
|   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 51 49 4d 17 0f 05 00 23   OPOLYXRTQIM....#
|   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 0d 05   E FTS5XNOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4d 41 52 59 17 0b   LE FTS4XBIMARY..
|   3776: 05 00 23 0f 19 45 4e 31 42 4c 45 20 46 1a 53 34   ..#..EN1BLE F.S4
|   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 96 54 20 56 54 41 42 58 52 54 52 49 4d 11 06   T.T VTABXRTRIM..
|   3920: 05 00 17 0f 1e e4 45 42 55 47 58 42 49 4e 41 52   ......EBUGXBINAR
|   3936: 59 11 05 05 00 17 0e 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 01 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 40 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 4f 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e   OMOILER=gcc-5.4.
|   4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d   0 20160609XRTRIM
| page 4 offset 12288
|      0: 0d 00 00 01 00 10 00 00 00 00 00 00 00 00 00 00   ................
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33   ...........0 253
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36   ..0.%.....201606
|   3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35   09.%....4.%....5
|   3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a   .%....0000000.%.
|   3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00   ...compiler.%...
|   3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75   .dbstat.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09   g.%....enable.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f   .eopoly.%....jso
|   3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79   ..max.%....emory
|   3184: 03 25 19 00 03 04 73 79 73 4d 03 25 15 00 00 04   .%....sysM.%....
|   3200: 6e 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   nmit.%....rtree.
|   3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03   %....threadsafe.
|   3232: 25 0e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01   %....vtab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00   ................
|   3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 bd   .....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 06 00 00 01 35 09 01 04 00 01 04 00 02 04   ......5.........
|   3328: 00 01 07 30 30 e6 30 30 30 30 09 1c 04 00 01 04   ...00.0000......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 04 01 02 02 10 03 01 02 02   ................
|   3376: 00 0f 71 02 12 00 03 01 02 02 00 03 01 65 02 00   ..q..........e..
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 0d a2 00 03 01 02 02 00 00 08 63 3b 6d 70 69   ...........c;mpi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64   ler............d
|   3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   bstat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 61 62 6c 65 3f 07 02 00 01 02 00 01 02   .enable?........
|   3488: 00 01 02 00 01 02 00 01 01 f0 01 02 00 01 02 00   ................
|   3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01   ................
|   3520: 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02   ................
|   3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09   .........eopoly.
|   3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64   ............load
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79   ...........emory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 01 f0   ................
|   3760: 03 01 02 02 05 93 01 02 02 00 03 01 02 02 00 00   ................
|   3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   .omit...........
|   3792: 05 72 8a 72 65 65 09 19 03 00 01 03 00 11 03 00   .r.ree..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02   ...threadsafe...
|   3888: 00 01 02 00 01 02 00 00 04 76 75 61 62 09 07 04   .........vuab...
|   3904: 00 01 04 00 01 04 00 00 61 78 b4 01 01 01 01 02   ........ax......
|   3920: 00 01 01 01 02 00 00 f1 01 02 00 01 01 01 02 00   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   3968: 01 02 00 01 01 01 01 ff 01 01 01 02 00 01 01 01   ................
|   3984: 02 00 01 01 01 02 00 01 01 01 02 09 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 02 00 01 02 01 02 00 01 01 01 02 00 01   ................
|   4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 11 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 0f fb 1f f5 00 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| page 7 offset 24576
|      0: 0d 00 00 00 05 0f b8 00 0f f4 0f e9 10 d6 0f c7   ................
|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f   ...........#auto
|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00   =1..............
| end crash-53f41622dd3bf6.db
}]} {}

do_catchsql_test 29.1 {
  PRAGMA writable_schema = 1;
  INSERT INTO t1(a) SELECT X'819192E578DE3F';
  UPDATE t1 SET b=quote(zeroblob(current_date)) WHERE t1 MATCH 't*';
  INSERT INTO t1(b) VALUES(x'78');
  INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 30.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename crash-e6e3857edf9b26.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 b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72   .5tablet1_segdir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52   r'(level INTEGER
|   3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61   ,idx INTEGER,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 62 2c 72 6f 6f 74   ock INTEGEb,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74   ..E...indexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e   ..tablet1_segmen
|   3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52   tst1_segments.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59    INTEGER PRIMARY
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1_contentt1_cont
|   3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   cid INTEGER PRIM
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06   'c1b', 'c2c')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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74   ....%.H........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 0d ef 00 00   ...t.[.@.$......
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7e f0   .........?%...~.
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 23 00 20 32 30 31 36 30 36 30 39 20 44 45 42   4#. 20160609 DEB
|   2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54   UG ENABLE DBSTAT
|   2944: 20 56 54 41 42 20 45 4e 42 92 4c 45 20 46 54 53    VTAB ENB.LE FTS
|   2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   4 ENABLE FTS5 EN
|   2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   ABLE GEOPOLY ENA
|   2992: 42 4c 45 1f 4a 53 4f 4e 31 20 45 4e 41 42 4c 49   BLE.JSON1 ENABLI
|   3008: 00 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20   .MEMSYS5 ENABLE 
|   3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59   RTREE MAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c   =50000000 OMIT L
|   3056: 4f 41 44 20 45 58 54 45 4e 53 49 4f 4e 20 54 48   OAD EXTENSION TH
|   3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f   READSAFE=0.$..%.
|   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 88 4e 4f 43 41 53 45 17 22   DSAFE=0.NOCASE..
|   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 20 05 00 33 0f 17   ONXNOCASE. ..3..
|   3232: 4f 4d 49 54 20 4c 4f 41 54 20 45 58 54 45 4e 53   OMIT LOAT EXTENS
|   3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 04 00 33 0f 19   IONXRTRIM....3..
|   3264: 82 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30   .AX MEMORY=50000
|   3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 fa 52 59 3d 35 30 20   ..MAX MEM.RY=50 
|   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 53 52 45 45 58 42   ..ENABLE RSREEXB
|   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 58 4e 4f 53 41 53 45 17   LE RTREEXNOSASE.
|   3408: 19 05 00 25 0f 17 45 4e 42 42 4c 45 20 52 54 52   ...%..ENBBLE 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 5a 53 35 58 42 49   NABLE MEMSZS5XBI
|   3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 3c   NARY....)..ENAB<
|   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 31 42 4c 45 20 47 45 4e 50 4f 4c 59 58 42 49   N1BLE GENPOLYXBI
|   3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e f2 1e 4c   NARY....)..EN..L
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45   E GEOPOLYXNOCASE
|   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 3c   NARY....#..ENAB<
|   3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05   E FTS5XNOCASE...
|   3728: 00 23 0f 17 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 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   3776: 05 00 23 0f 19 45 4e 41 43 4c 45 20 46 54 53 35   ..#..ENACLE FTS5
|   3792: 58 4e 4f 43 40 53 45 16 0a 05 00 23 0f 17 45 4e   XNOC@SE....#..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 55 20 56 54 41 42 58 42 49 4e 41 52 59 1e   TAU 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 62 49 4d 11 06   TAT VTABXRTbIM..
|   3920: 05 00 17 0f 19 44 45 42 54 47 58 42 49 4e 41 52   .....DEBTGXBINAR
|   3936: 59 11 05 05 00 17 0f 19 54 45 42 55 47 58 4e 4f   Y.......TEBUGXNO
|   3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47   CASE.......DEBUG
|   3968: 68 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d   hRTRIM'...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 4f 4f 43 41 53 45 26 01 05 00 43 0f 17 43   9XOOCASE&...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 52 49 4d   0 20160609XRTRIM
| page 4 offset 12288
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33   ...........0 253
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36   ..0.%.....201606
|   3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35   09.%....4.%....5
|   3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a   .%....0000000.%.
|   3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00   ...compiler.%...
|   3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75   .dbstat.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09   g.%....enable.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f   .eopoly.%....jso
|   3152: 6e 31 03 25 14 00 e8 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79   ..max.%....emory
|   3184: 03 25 19 00 03 04 73 79 73 35 03 25 15 00 00 04   .%....sys5.%....
|   3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   omit.%....rtree.
|   3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03   %....threadsafe.
|   3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01   %....vtab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00   ................
|   3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07   .....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04   ......5.........
|   3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04   ...0000000......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3376: 00 03 01 02 f2 00 03 01 02 02 00 03 01 02 02 00   ................
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69   ...........compi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64   ler............d
|   3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   bstat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 60 62 6c 65 3f 07 02 00 01 02 00 01 01   .en`ble?........
|   3488: ff f1 b1 00 00 02 3f 01 01 f0 f1 02 00 57 02 00   ......?......W..
|   3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 10 01   ................
|   3520: 02 00 01 02 00 01 02 00 01 02 01 01 02 00 01 02   ................
|   3536: 00 01 02 00 00 f2 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09   .........eopoly.
|   3616: 10 03 00 01 03 00 01 03 00 00 b3 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64   ............load
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79   ...........emory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 03 00 01 03 00 01 03 cc 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00   ................
|   3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00   ................
|   3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   .omit...........
|   3792: 05 72 74 62 65 65 09 19 03 00 01 03 00 01 03 00   .rtbee..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 00 03 01 02 01 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02   ...threadsafe...
|   3888: 00 01 02 00 02 02 00 00 04 76 74 61 62 09 07 04   .........vtab...
|   3904: 00 01 03 00 01 04 00 00 01 78 b4 01 01 01 01 02   .........x......
|   3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   3968: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   3984: 02 01 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   4032: 01 01 02 00 01 01 01 da 00 01 01 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 01 01 ff ff 01 01 02 00 01 01 01   ................
|   4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 01 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| page 7 offset 24576
|      0: 01 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 00   .o..............
| end crash-e6e3857edf9b26.db
}]} {}

do_execsql_test 30.1 {
  UPDATE t1 SET b=a;
}

do_catchsql_test 30.2 {
  SELECT (matchinfo(null)) FROM t1 WHERE t1 MATCH 'ee*e*e*e*e*e*e*Re*e*e*e**' 
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 31.0 {
CREATE VIRTUAL TABLE t1 USING fts3(a,b,c);
INSERT INTO t1_segdir VALUES(0,0,0,0,'0 592',X'00016dcb048ce6fbd3b2d68bfebf0101020200808080808080808020010202008080808080808080100102020080808080808080800801020200808080808080808004010202008080808080808080020102020080808080808080800101020200808080808080804001020200808080808080802001020200808080808080801001020200808080808080800801020200808080808080800401020200808080808080800201020200808080808080800101020200808080808080400102020080808080808020010202008080808080801001020200808080808080080102020080808080808004010202008080808080800201020200808080808080010102020080808080804001020200808080808020010202008080808080100102020080808080800801020200808080808004010202008080808080020102020080808080800101020200808080804001020200808080802001020200808080801001020200808080800801020200808080800401020200808080800201020200808080800101020200808080400102020080808020010202008080801001020200808080080102020080808004010202008080800201020200808080010102020080804001020200808020010202008080100102020080800801020200808004010202008080020102020080800101020200804001020200802001020200801001020200800801020200800401020200800201020200800101020200400102020020010202001001020200080102020004010202000201020200010102020001010202008080808080808080800101020200');
INSERT INTO t1_segdir VALUES(0,1,0,0,'0 18',X'00026d6d0d8ee6fbd3b2d68bfe7f01020200');
}

do_catchsql_test 31.1 {
  SELECT (matchinfo(t1, c ) ) FROM t1 WHERE t1 MATCH 'M*M*M*M*';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 32.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-74fdbc96edbc04.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 b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72   .5tablet1_segdir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52   r'(level INTEGER
|   3600: 2c 69 64 78 20 49 4e 54 45 47 44 52 2c 73 74 61   ,idx INTEGDR,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74   ock INTEGER,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 6a 6e 64 65 78 73 71 6c 69 74   ..E...jndexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e   ..tablet1_segmen
|   3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 03 43 52   tst1_segments.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 5a    INTEGER PRIMARZ
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1_contentt1_cont
|   3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   cid INTEGER PRIM
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06   'c1b', 'c2c')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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74   ....%.H........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 0d ef 0d d5   ...t.[.@.$......
|     48: 0d bb 0d a0 0d 84 0d 68 0d 50 0d 35 0d 1b 0c fb   .......h.P.5....
|     64: 0c da 0c b8 fc 99 0c 78 0c 57 0c 3e 0c 24 0c 0a   .......x.W.>.$..
|     80: 0b 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00   .H..............
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7f 00   .........?%.....
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 45 42   4.0 20160609 DEB
|   2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 7e 54   UG ENABLE DBST~T
|   2944: 20 56 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53    VTAB ENABLE FTS
|   2960: 44 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   D ENABLE FTS5 EN
|   2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   ABLE GEOPOLY ENA
|   2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45   BLE JSON1 ENABLE
|   3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20    MEMSYS5 ENABLE 
|   3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59   RTREE MAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c   =50000000 OMIT L
|   3056: 4f 41 44 20 45 58 54 45 4e 53 49 4f 4e 20 54 48   OAD EXTENSION TH
|   3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f   READSAFE=0.$..%.
|   3088: 19 54 48 52 45 41 44 54 41 46 45 3d 30 58 42 49   .THREADTAFE=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 bd 4e 4f 43 41 53 45 17 22   DSAFE=0.NOCASE..
|   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 4e   IT LOAD EXTENSIN
|   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 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMIT 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 1f 4d 45 4d 4f 52 59 3d 35 30 30 30 30   MAX.MEMORY=50000
|   3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 44 4d 4f 52 59 3d 35 30 30   ..MAX MDMORY=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 55 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17   LU RTREEXNOCASE.
|   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 3f 43 41 53 45   E MEMSYS5XN?CASE
|   3488: 19 16 05 00 29 0f 17 45 4e a1 42 4c 45 20 4d 45   ....)..EN.BLE 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 5f 4c 59 58 42 49   NABLE GEOP_LYXBI
|   3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c   NARY....)..ENABL
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4b bf 43 41 53 45   E GEOPOLYXK.CASE
|   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 55 20 46 54 53 35 58 42 49   ..ENABLU FTS5XBI
|   3696: 4e 4b a2 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c   NK.Y....#..ENABL
|   3712: 45 20 46 54 52 35 58 4e 4f 43 41 53 45 16 0d 05   E FTR5XNOCASE...
|   3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58   .#..ENABLE FTS5X
|   3744: 52 54 52 49 4d 17 0b 05 00 23 0f 19 45 4e 41 42   RTRIM....#..ENAB
|   3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   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 07 e1 0f 19 45 4e 41 42 4c 45 20 44 42 53   ......ENABLE DBS
|   3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e   TAT VTABXBINARY.
|   3856: 18 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 41 18 4e 4f 43 41 53 45 1d   TAT VTAA.NOCASE.
|   3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 32 53   ...1..ENABLE D2S
|   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 00 00 00 00 00 00   Y.......DE......
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 01 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33   ...........0 253
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36   ..0.%.....201606
|   3008: 30 38 03 25 07 00 00 01 34 03 25 05 00 00 01 35   08.%....4.%....5
|   3024: 03 25 13 00 01 07 30 30 30 30 30 30 30 03 25 1a   .%....0000000.%.
|   3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00   ...compiler.%...
|   3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75   .dbstat.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09   g.%....enable.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f   .eopoly.%....jso
|   3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 62 78 03 25 18 00 01 05 65 6d 6f 72 79   ..mbx.%....emory
|   3184: 03 25 19 00 03 04 73 c8 73 35 03 25 15 00 00 04   .%....s.s5.%....
|   3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   omit.%....rtree.
|   3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03   %....threadsafe.
|   3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01   %....vtab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00   ................
|   3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07   .....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 02 04   ......5.........
|   3328: 00 01 07 30 2f 30 30 30 30 30 09 1c 04 00 01 04   ...0/00000......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3376: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00   ................
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69   ...........compi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64   ler............d
|   3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   bstat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 61 6c 2c 65 3f 07 02 00 01 02 00 01 02   .enal,e?........
|   3488: 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00   ................
|   3504: 01 02 00 01 02 00 01 02 00 01 01 ff f1 02 00 01   ................
|   3520: 02 00 01 02 00 01 02 00 f1 02 00 01 02 00 01 4f   ...............O
|   3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 00 f3 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 04 00 01 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09   .........eopoly.
|   3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 02 ff 01 03 00 00 04 6c 6f 61 63   ............loac
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 00 01 02 00 01 02 00 01 05 64 6d 6f 72 79   ...........dmory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 02 f0 01 03 00 01 03 00 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 03 01 02 02 00 4b 01 02 02 00   ...........K....
|   3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00   ................
|   3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   .omit...........
|   3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00   .rtree..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02   ...threadsafe...
|   3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04   .........vtab...
|   3904: 00 01 04 00 01 04 00 00 01 78 b4 01 01 01 01 02   .........x......
|   3920: 00 01 f4 01 02 00 01 02 01 02 00 01 01 01 02 ff   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 02 ae 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   3968: 01 12 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   3984: 12 00 01 01 01 02 01 01 01 01 02 00 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 01 02 00 01 76 01 02 00 01 01 01   .........v......
|   4064: 02 00 01 01 01 02 01 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| end crash-74fdbc96edbc04.db
}]} {}

do_catchsql_test 32.1 {
  UPDATE t1 SET b=quote(zeroblob(6.51158946e+5)) WHERE a MATCH '*t*';
} {1 {database disk image is malformed}}

#do_catchsql_test 32.2 {
#  UPDATE t1 SET b=((- '' )) WHERE a MATCH '0*t';
#} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
ifcapable icu {
  reset_db
  do_catchsql_test 33.0 {
    CREATE VIRTUAL TABLE f USING fts3(a,b,tokenize=icu);
    CREATE TABLE 'f_docsize'(docid INTEGER PRIMARY KEY, size BLOB);
    CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB);
    INSERT INTO f VALUES (1, '1234');
    INSERT INTO f_stat VALUES (1,x'0000000165656565db6569746565c5c52bc5c5c53e3a003bc502ffffffffc5c5c53e3a003bc502fffffffffb8b2afbfb6565f0740100650000000165656565db6569746565c5c52bc5c5c53e3a003bc502ffffffffc5c5c53e3a003b8b00c5c5c5c5c5bfc5');
    INSERT INTO f(f) VALUES ('merge=198,49');
  } {1 {database disk image is malformed}}
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 34.0 {
  CREATE VIRTUAL TABLE f USING fts3(a,b);
  INSERT INTO f VALUES (1, '1234');
  INSERT INTO f_segdir VALUES (1,255,0,0,'1 255',x'00');
  UPDATE f_segdir SET level = 0 WHERE level IN (
    SELECT level FROM f_segdir LIMIT 1 OFFSET 1
  );
  INSERT INTO f_segdir VALUES (255,249,0,121,'0 0',x'00');
  INSERT INTO f_content VALUES (255,0,x'ff');
  INSERT INTO f_segdir VALUES (1,255,16,0,'1 255',x'00');
}

do_catchsql_test 34.1 {
  UPDATE f SET b = x'00' WHERE b IN (SELECT b FROM f LIMIT 1 OFFSET 0);
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 35.0 {
  CREATE VIRTUAL TABLE f USING fts3(a,b);
  INSERT INTO f_segdir VALUES (1,255,0,0,'1 255',x'0001ff000001ff000001ff000001ff000001ff00c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5bec5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5');
}

do_catchsql_test 35.1 {
  INSERT INTO f(f) VALUES ('integrity-check');
} {1 {database disk image is malformed}}

reset_db
do_catchsql_test 36.0 {
  CREATE VIRTUAL TABLE f USING fts3(a,tokenize=porter);
  CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB);
  INSERT INTO f VALUES (1);
  INSERT INTO f_stat VALUES (1,x'00000000000101010119013d00ffff0400fa83717b71a69297979701f63d010101010101010101010101190000000000000000fa83717b71a601f63d01010101010101010101010119013d00ffffff0400fa83717b71a69297979701f63d010101010101010101010101190000000000000000fa83717b71a69201f63d010101f63d01010101010101010101010119013d00ffffff0400fa83717b71a6929797010101010101010101010119013d00ffff01f63d01010101010101010101010119013d00ffffff0400fa83717b71a69297979701f63d00fa03ffffffa69297979701f63d010101000000000101010101197e9797976567656565ffa63535354e');
  INSERT INTO f(f) VALUES ('merge=53,216');
} {0 {}}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 36.0 {
  CREATE VIRTUAL TABLE f USING fts3(a,b);
  CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB);
  INSERT INTO f_stat VALUES (1,x'11014101000101c5c5014b010164c5014b010101c50101c5c5010201010101014101000101c5c5014b010101c5014b010101c50101c5c501010100c50101c5c5010101010101e40201010101014101000201010101014101000101010201010101014101000101c5c503b5fefefe3afeffffc5c5c5c50101010101010201010101014101adadadadadadadadadadadad91adadadadadadadad0101c50101c5c501f9ffffffffffffffff0001010102010101010140f5000101c5c5014b010101c50101c5c501010101e6010201010101014101000101c5c5014b010101c50101c5c5010101114b0101c5c50101010a0101020101e60101');
}

do_catchsql_test 36.1 {
  INSERT INTO f(f) VALUES ('merge=59,59');
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 37.0 {
  CREATE VIRTUAL TABLE f USING fts3(a,b);
  INSERT INTO f_segdir VALUES (28,0,0,0,'0 0',x'00');
  INSERT INTO f_segdir VALUES (0,241,0,0,'0 0',x'0001000030310000f1');
}

do_catchsql_test 37.1 {
  INSERT INTO f VALUES (0,x'00');
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 38.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-1cc4f8a70485ce.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 b1 00 06 0d a4 00 0f 8d 0f 21   ...............!
|    112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00   .....~..........
|   3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c   ...........1tabl
|   3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42   et2t2.CREATE TAB
|   3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01   LE t2(x).3......
|   3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72   .5tablet1_segdir
|   3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45   t1_segdir.CREATE
|   3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69    TABLE 't1_segdi
|   3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52   r'(level INTEGER
|   3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61   ,idx INTEGER,sta
|   3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52   rt_block INTEGER
|   3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   ,leaves_end_bloc
|   3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c   k INTEGER,end_bl
|   3664: 6f 63 6b 20 49 4e 54 45 47 45 62 2c 72 6f 6f 74   ock INTEGEb,root
|   3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45    BLOB,PRIMARY KE
|   3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06   Y(level, idx))1.
|   3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74   ..E...indexsqlit
|   3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73   e_autoindex_t1_s
|   3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72   egdir_1t1_segdir
|   3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01   .........f...##.
|   3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e   ..tablet1_segmen
|   3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52   tst1_segments.CR
|   3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73   EATE TABLE 't1_s
|   3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64   egments'(blockid
|   3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59    INTEGER PRIMARY
|   3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42    KEY, block BLOB
|   3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74   )j...!!...tablet
|   3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74   1_contentt1_cont
|   3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45   ent.CREATE TABLE
|   3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f    't1_content'(do
|   3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   cid INTEGER PRIM
|   3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20   ARY KEY, 'c0a', 
|   3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06   'c1b', 'c2c')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 33   LE t1 USING fts3
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 3 offset 8192
|      0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74   ....%.H........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 0d ef 00 00   ...t.[.@.$......
|   2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7e f0   .........?%...~.
|   2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e   .COMPILER=gcc-5.
|   2912: 34 23 00 20 42 30 31 36 2f 36 30 39 20 44 45 42   4#. B016/609 DEB
|   2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54   UG ENABLE DBSTAT
|   2944: 20 56 54 41 42 20 45 4e 42 92 4c 45 20 46 54 53    VTAB ENB.LE FTS
|   2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e   4 ENABLE FTS5 EN
|   2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41   ABLE GEOPOLY ENA
|   2992: 42 5c 45 1f 4a 53 4f 4e 31 20 45 4e 41 42 4c 45   B.E.JSON1 ENABLE
|   3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20    MEMSYS5 ENABLE 
|   3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59   RTREE MAX MEMORY
|   3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c   =50000000 OMIT L
|   3056: 4f 41 44 20 45 58 54 45 4e 53 49 4f 4e 20 54 48   OAD EXTENSION TH
|   3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f   READSAFE=0.$..%.
|   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 88 4e 4f 43 41 53 45 17 22   DSAFE=0.NOCASE..
|   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 49 54 20 4c 4f 41 54 20 45 58 54 45 4e 53   OMIT LOAT EXTENS
|   3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 04 00 33 0f 19   IONXRTRIM....3..
|   3264: 82 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30   .AX MEMORY=50000
|   3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000XBINARY....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 fa 52 59 3d 35 30 20   ..MAX MEM.RY=50 
|   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 58 4e 4f 43 41 53 45 17   LE RTREEXNOCASE.
|   3408: 19 05 00 25 0f 17 45 4e 42 42 4c 45 20 52 54 52   ...%..ENBBLE 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 3c   NARY....)..ENAB<
|   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 95 12 05 00 29 0f 19 45   N1XRTRIM....)..E
|   3600: 4e 31 42 4c 45 20 47 45 4e 50 4f 4c 59 58 42 49   N1BLE GENPOLYXBI
|   3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 3e f2 1e 4c   NARY....)..E>..L
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45   E GEOPOLYXNOCASE
|   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 3c   NARY....#..ENAB<
|   3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05   E FTS5XNOCASE...
|   3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58   .#..ENABLE FTS5X
|   3744: 5d 24 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42   ]$RIM....#..ENAB
|   3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b   LE FTS4XBINARY..
|   3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 35   ..#..ENABLE FTS5
|   3792: 58 4e 4f 43 40 53 45 16 0a 05 00 23 0f 17 45 4e   XNOC@SE....#..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 4b 45 20 44 42 53   ...1..ENABKE DBS
|   3904: 54 41 54 20 56 53 41 42 58 52 54 62 49 4d 11 06   TAT VSABXRTbIM..
|   3920: 05 00 17 0f 19 44 45 42 54 47 58 42 49 4e 41 52   .....DEBTGXBINAR
|   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: 68 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d   hRTRIM'...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 4f 4f 43 41 53 45 26 01 05 00 43 0f 17 43   9XOOCASE&...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 52 49 4d   0 20160609XRTRIM
| page 4 offset 12288
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
| page 5 offset 16384
|      0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00   ................
|   2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33   ...........0 253
|   2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 8c 36   ..0.%.....2016.6
|   3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35   09.%....4.%....5
|   3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a   .%....0000000.%.
|   3040: 00 00 08 63 6f 5d 70 69 6c 65 72 03 25 02 00 00   ...co]piler.%...
|   3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75   .dbstat.%....ebu
|   3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09   g.%....enable.%.
|   3088: 05 04 04 04 04 04 00 01 08 78 74 65 7e 73 69 6f   .........xte~sio
|   3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03   n.%....fts4.%...
|   3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01   .5.%....gcc.%...
|   3136: 06 65 6f 70 7f 6c 79 03 25 11 00 00 05 6a 73 6f   .eop.ly.%....jso
|   3152: 6e 31 03 25 14 00 e8 04 6c 6f 61 64 03 25 1c 00   n1.%....load.%..
|   3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79   ..max.%....emory
|   3184: 03 25 19 00 03 04 73 79 73 35 03 25 15 00 00 04   .%....sys5.%....
|   3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03   omit.%....rtree.
|   3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03   %....threadsafe.
|   3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01   %....vtab.%...P.
|   3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30   ........0 835..0
|   3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00   ................
|   3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07   .....20160609...
|   3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05   .........4......
|   3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04   ......5.........
|   3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04   ...0000000......
|   3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02   ......binary<...
|   3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3376: 00 03 01 02 c2 00 03 01 02 02 00 03 01 04 82 00   ................
|   3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03   ................
|   3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69   ...........compi
|   3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64   ler............d
|   3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01   bstat...........
|   3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00   .ebug...........
|   3472: 06 65 6e 60 62 6c 65 3f 07 02 00 01 02 92 e1 a4   .en`ble?........
|   3488: ff fc a2 8c 95 b2 3f 01 01 f0 f1 02 00 57 02 00   ......?......W..
|   3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 10 01   ................
|   3520: 02 00 01 02 00 01 02 00 01 02 01 01 02 00 01 02   ................
|   3536: 00 01 02 00 00 f2 00 01 08 78 74 65 6e 73 69 6f   .........xtensio
|   3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73   n............fts
|   3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d   4............5..
|   3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03   ..........gcc...
|   3600: 00 01 03 00 01 03 00 01 06 65 5f 70 6f 6c 79 09   .........e_poly.
|   3616: 10 03 00 01 03 00 01 03 00 00 b3 6a 73 6f 6e 31   ...........json1
|   3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64   ............load
|   3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09   ............max.
|   3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79   ...........emory
|   3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35   ............sys5
|   3696: 09 16 03 00 01 03 00 01 03 cc 00 06 6e 6f 63 61   ............noca
|   3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02   se<.............
|   3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02   ................
|   3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00   ................
|   3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00   ................
|   3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00   .omit...........
|   3792: 05 72 74 62 65 65 09 19 03 00 01 03 00 01 03 00   .rtbee..........
|   3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03   ..im<...........
|   3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01   ................
|   3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02   ................
|   3856: 02 00 03 01 02 02 00 03 01 02 01 00 03 01 02 02   ................
|   3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02   ...threadsafe...
|   3888: 00 01 02 00 02 02 00 00 04 76 74 61 62 09 07 04   .........vtab...
|   3904: 00 01 03 00 01 04 00 00 01 78 b4 01 01 01 01 02   .........x......
|   3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01   ................
|   3968: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01   ................
|   3984: 02 01 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
|   4016: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01   ................
|   4032: 01 01 02 00 01 01 01 da 00 00 f1 01 02 00 01 01   ................
|   4048: 01 02 00 01 01 01 01 ff ff 01 01 02 00 01 01 01   ................
|   4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02   ................
|   4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00   ................
| page 6 offset 20480
|      0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 01 00 00 00   ................
|   4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09   ................
| end crash-1cc4f8a70485ce.db
}]} {}

do_execsql_test 38.1 {
  UPDATE t1 SET b=a;
}

do_catchsql_test 38.2 {
  SELECT b FROM t1 WHERE a MATCH 'e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*'
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
set saved $sqlite_fts3_enable_parentheses
set sqlite_fts3_enable_parentheses 1
do_execsql_test 39.0 {
  CREATE VIRTUAL TABLE t0 USING fts3(
    col0 INTEGER PRIMARY KEY,
    col1 VARCHAR(8),
    col2 BINARY,
    col3 BINARY
  );
  INSERT INTO t0_content VALUES(1,1,'1234','aaaa','bbbb');
  INSERT INTO t0_segdir VALUES(0,0,0,0,'0 42',X'000131030782000103323334050101010200000461616161050101020200000462626262050101030200');
}

do_test 39.1 {
  catch {
    db eval { SELECT rowid FROM t0 WHERE t0 MATCH '1 NEAR 1' }
  }
} 0

do_test 39.2 {
  catch {
    db eval {
  SELECT matchinfo(t0,'yxy') FROM t0 WHERE t0 MATCH x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d';
    }
  }
} 0
set sqlite_fts3_enable_parentheses $saved

#-------------------------------------------------------------------------
reset_db
set saved $sqlite_fts3_enable_parentheses
set sqlite_fts3_enable_parentheses 1

do_execsql_test 40.1 {

  CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY, col1, col2 ,col3 );
  INSERT INTO t0_segdir VALUES(0,0,0,0,'0 42',
      X'0001310301020001033233340500010102000004616161bc050101020200000462626262050101030200'
  );
}

do_execsql_test 40.2 {
  SELECT 0==matchinfo(t0,'sx') FROM t0 WHERE t0 MATCH '1* 2 3 4 5 6 OR 1';
} 0

set sqlite_fts3_enable_parentheses $saved

#-------------------------------------------------------------------------
reset_db
do_execsql_test 41.1 {
  CREATE VIRTUAL TABLE t1 USING fts3(a,b,c);
  INSERT INTO t1_segdir VALUES(0,0,0,0,'0 835',X'000130120106000106000106001f030001030001030000083230313630363039090107000107000107000001340901050001050001050000013509010400010400010400010730303030303030091c0400010400010400000662696e6172793c0301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000008636f3870696c657209010200010200010200000664627374617409070300010300010300010465627567090402000102000102000006656e61626c653f07020001020001020001020001020001020001020001020001020001030001010002020001020001020001020001120001020001020001020001020001020001087874656e73696f6e091f0400010400010400000466747334090a0300010300010400030135090d03000103000103000003676363090103000103000103000106656f706f6c790910030001030001030000056a736f6e310913030001030001030000046c6f6164091f030001030001030000036d6178091c02000102000102000105656d6f7279091c03000103000103000304737973350916030001030001030000066e6f636173653c02010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020000046f6d6974091f020001020001020000057274726565091903000103000103000302696d3c010102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200000a746872656164736166650922020001020001020000047674616209070400010400010400000178b401010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200');
}

do_execsql_test 41.2 {
  SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'rtree ner "json1^enable"';
}

#-------------------------------------------------------------------------
do_execsql_test 42.1 {
  CREATE VIRTUAL TABLE f USING fts3(a, b);
}
do_execsql_test 42.2 {
  INSERT INTO f_segdir VALUES(0,2,1111,0,0,X'00');
  INSERT INTO f_segdir VALUES(0,3,0   ,0,0,X'00013003010200');
}
do_execsql_test 42.3 {
  INSERT INTO f(f) VALUES ('merge=107,2');
}

#-------------------------------------------------------------------------
reset_db
set saved $sqlite_fts3_enable_parentheses
set sqlite_fts3_enable_parentheses 1
do_execsql_test 43.1 {
  CREATE VIRTUAL TABLE def USING fts3(xyz);
  INSERT INTO def_segdir VALUES(0,0,0,0,0, X'0001310301c9000103323334050d81');
} {}

do_execsql_test 43.2 {
  SELECT rowid FROM def WHERE def MATCH '1 NEAR 1'
} {1}

set sqlite_fts3_enable_parentheses $saved

#-------------------------------------------------------------------------
reset_db
do_execsql_test 44.1 {
  CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
  INSERT INTO t0_content VALUES(0,NULL,NULL,NULL,NULL);
  INSERT INTO t0_segdir VALUES(0,0,0,0,'0 42',X'00013103010200010332333405010201ba00000461616161050101020200000462626262050101030200');
}

do_execsql_test 44.2 {
  SELECT matchinfo(t0, t0) IS NULL FROM t0 WHERE t0 MATCH '1*'
} {0}

#-------------------------------------------------------------------------
#
reset_db
do_test 45.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-65c98512cc9e49.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   .....@  ........
|     96: 00 00 00 00 0d 0e fc 00 06 0d bc 00 0f ca 0f 6c   ...............l
|    112: 0f 04 0e 13 0e c9 0d bc 00 00 00 00 00 00 00 00   ................
|   3504: 00 00 00 00 00 00 00 00 00 00 00 00 55 06 07 17   ............U...
|   3520: 1b 1b 01 81 01 74 61 62 6c 65 78 31 5f 73 74 61   .....tablex1_sta
|   3536: 74 78 31 5f 73 74 61 74 06 43 52 45 41 54 45 20   tx1_stat.CREATE 
|   3552: 54 41 42 4c 45 20 27 78 31 5f 73 74 61 74 27 28   TABLE 'x1_stat'(
|   3568: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41   id INTEGER PRIMA
|   3584: 52 59 20 4b 45 59 2c 20 76 61 6c 75 65 20 42 4c   RY KEY, value BL
|   3600: 41 82 29 81 33 04 07 17 1f 1f 01 82 35 74 61 62   A.).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: 60 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 11 0f 77 f0 0f f8 0f f0 0f e8 0f e0   ......w.........
|     16: 0f d8 0f d0 0f c8 0f c0 00 00 00 00 00 00 00 00   ................
|   3952: 00 00 00 00 00 00 00 00 06 11 03 00 13 77 78 79   .............wxy
|   3968: 06 10 03 00 13 74 75 76 06 0f 03 00 13 71 33 73   .....tuv.....q3s
|   3984: 06 0e 03 00 13 6e 6f 70 06 0d 03 00 13 6b 6c 6d   .....nop.....klm
|   4000: 06 0c 03 04 c3 68 69 6a 06 0b 03 00 13 65 66 67   .....hij.....efg
|   4016: 06 0a 03 00 13 62 63 64 06 09 03 00 13 79 7a 61   .....bcd.....yza
|   4032: 06 08 03 00 13 76 77 78 06 07 03 00 13 73 74 75   .....vwx.....stu
|   4048: 06 06 03 00 13 70 71 72 06 05 03 00 13 6d 6e 6f   .....pqr.....mno
|   4064: 06 03 03 00 13 6a 6b 6c 06 03 03 00 13 67 68 69   .....jkl.....ghi
|   4080: 06 02 02 00 03 64 65 66 06 01 03 00 13 61 52 63   .....def.....aRc
| page 3 offset 8192
|      0: 0d 00 00 00 03 0f a7 00 0f b5 0f a7 0f fa 01 00   ................
|   4000: 00 00 00 00 00 00 00 0c 02 03 00 1e 00 03 6b 6c   ..............kl
|   4016: 6d 03 0d 02 00 43 01 04 00 81 0a 00 03 61 62 63   m....C.......abc
|   4032: 03 0b 32 00 00 03 62 63 64 03 0a 02 00 00 03 64   ..2...bcd......d
|   4048: 69 26 03 02 02 00 00 03 65 66 67 03 0b 02 00 00   i&......efg.....
|   4064: 03 67 68 69 03 03 02 00 00 03 68 69 6a 03 0c 02   .ghi......hij...
|   4080: 00 00 03 6a 6a 2c 03 04 02 00 03 81 00 03 00 00   ...jj,..........
| page 4 offset 12288
|      0: 0d 0f 3a 00 05 0f 25 00 0f 9e 0f 88 0f 43 0f 25   ..:...%......C.%
|     16: 0f 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00   .r..............
|   3856: 00 00 00 00 00 00 00 00 00 56 01 08 08 13 1e 03   .........V......
|   3872: 30 20 39 00 03 13 05 07 08 08 18 08 13 1e 30 20   0 9...........0 
|   3888: 39 00 03 77 78 79 03 11 02 00 0f 6c 00 09 01 08   9..wxy.....l....
|   3904: 08 15 54 27 04 07 09 01 08 08 15 42 02 30 20 33   ..T'.......B.0 3
|   3920: 36 00 03 6e 6f 70 03 0e 02 00 00 03 71 72 73 03   6..nop......qrs.
|   3936: 0f 02 00 00 03 74 75 76 03 10 02 00 0f cf b1 06   .....tuv........
|   3952: 01 08 14 06 07 01 08 09 01 1b 14 02 02 31 32 38   .............128
|   3968: 20 2d 37 32 10 01 01 6b 14 03 07 09 09 08 08 15    -72...k........
|   3984: 1e 30 20 33 36 00 03 79 7a 61 03 09 02 00 2f 02   .0 36..yza..../.
|   4000: 07 09 08 08 08 15 54 30 20 33 36 00 03 6d 6e 6f   ......T0 36..mno
|   4016: 03 05 02 00 00 03 70 71 72 03 06 02 00 00 03 73   ......pqr......s
|   4032: 74 75 03 07 02 00 00 03 76 77 78 03 08 02 00 00   tu......vwx.....
|   4048: 00 00 4a 08 08 08 15 54 30 20 33 36 00 03 61 62   ..J....T0 36..ab
|   4064: 63 03 01 02 00 00 03 64 65 66 03 02 02 00 00 03   c......def......
|   4080: 67 68 69 03 03 67 00 00 03 6a 6b 6c 03 04 02 00   ghi..g...jkl....
| page 5 offset 16384
|      0: 0a 0f e7 00 05 0f da 00 0f e1 0f fa 0f f4 0f ed   ................
|     16: 0f da 0f 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4048: 00 00 00 00 00 00 00 1a 01 03 06 04 01 08 01 02   ................
|   4064: 06 05 04 08 08 01 05 00 00 00 06 01 03 06 04 09   ................
|   4080: 02 01 02 04 05 04 09 09 01 03 05 04 09 08 01 02   ................
| page 6 offset 20480
|      0: 0d 00 10 00 01 0f f9 00 0f f9 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 00 00 00 00 05 01 03 00 10 01 03   ................
| end crash-65c98512cc9e49.db
}]} {}

do_catchsql_test 45.2 {
  INSERT INTO x1(x1) VALUES( 'merge=1' )
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
set saved $sqlite_fts3_enable_parentheses
set sqlite_fts3_enable_parentheses 1
do_execsql_test 46.1 {
  CREATE VIRTUAL TABLE t0 USING fts3(a INTEGER PRIMARY KEY,b,c,d);
  INSERT INTO t0_segdir VALUES(0,0,0,0,'0 42',X'0001310301c9000103323334050d8000f200000461616161050101020200000462626262050101030200');
} {}

do_catchsql_test 46.2 {
  SELECT * FROM t0
    WHERE t0 MATCH x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d';
} {1 {database disk image is malformed}}

set sqlite_fts3_enable_parentheses $saved
extra_schema_checks 1

#-------------------------------------------------------------------------
reset_db
do_execsql_test 47.1 {
  CREATE VIRTUAL TABLE t1 USING fts3(a,b,c);
}
do_execsql_test 47.2 {
  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

Deleted test/fts3corrupt5.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



























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 May 22
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
#
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set testprefix fts3corrupt5

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
  finish_test
  return
}

sqlite3_fts3_may_be_corrupt 1

do_execsql_test 1.0 {
  BEGIN;
    CREATE VIRTUAL TABLE ft USING fts3(a, b, c);
    INSERT INTO ft VALUES('one', 'one', 'one');
  COMMIT;
}

do_execsql_test 1.1 {
  SELECT * FROM ft WHERE ft MATCH 'b:one'
} {one one one}

do_execsql_test 1.2 {
  SELECT quote(root) FROM ft_segdir;
} {X'00036F6E6509010201010201020200'}

breakpoint
foreach {tn val q bCorrupt} {
  1 X'00036F6E650901'                   'b:one'  1
  2 X'00036F6E6509010201010201FFFFFF'   'c:one'  1
  3 X'00036F6E6501'                     'b:one'  1
  4 X'00036F6E650101'                   'b:one'  1
  5 X'00036F6E650100'                   'b:one'  0
} {
  do_execsql_test 1.3.$tn.1 "UPDATE ft_segdir SET root = $val"

  set res {0 {}}
  if {$bCorrupt} { set res {1 {database disk image is malformed}}}
  do_catchsql_test 1.3.$tn.2 {
    SELECT * FROM ft WHERE ft MATCH $q
  } $res
}

finish_test

Deleted 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
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




































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 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.
ifcapable !fts3 {
  finish_test
  return
}

set ::saved_sqlite_fts3_enable_parentheses $::sqlite_fts3_enable_parentheses
set sqlite_fts3_enable_parentheses 1
sqlite3_fts3_may_be_corrupt 1
database_may_be_corrupt

do_execsql_test 1.0 {
  BEGIN TRANSACTION;
  CREATE TABLE t_content(col0 INTEGER);
  PRAGMA writable_schema=ON;
  CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
  INSERT INTO t0_content VALUES(0,NULL,NULL,NULL,NULL);
  INSERT INTO t0_segdir VALUES(0,0,0,0,'0 42',X'000131030102000103323334050101010200000461616161050101020200000462626262050101030200');
  COMMIT;
}

do_execsql_test 1.1 {
  SELECT 0+matchinfo(t0,'yxyyxy') FROM t0 WHERE t0 MATCH CAST( x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d' AS TEXT);
} {0}

do_execsql_test 1.2 {
  CREATE VIRTUAL TABLE t1 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
  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/fts3cov.test.

93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115







-
+







-
+







do_test fts3cov-2.2 {
  set root [db one {SELECT root FROM t1_segdir}]
  read_fts3varint [string range $root 1 end] left_child
  execsql { DELETE FROM t1_segments WHERE blockid = $left_child }
} {}
do_error_test fts3cov-2.3 {
  SELECT * FROM t1 WHERE t1 MATCH 'c*'
} {database disk image is malformed}
} {SQL logic error}

# Test the "replaced with NULL" case:
do_test fts3cov-2.4 {
  execsql { INSERT INTO t1_segments VALUES($left_child, NULL) }
} {}
do_error_test fts3cov-2.5 {
  SELECT * FROM t1 WHERE t1 MATCH 'cloud'
} {database disk image is malformed}
} {SQL logic error}

#--------------------------------------------------------------------------
# The following tests are to test the effects of OOM errors while storing
# terms in the pending-hash table. Specifically, while creating doclist
# blobs to store in the table. More specifically, to test OOM errors while
# appending column numbers to doclists. For example, if a doclist consists
# of:

Changes to test/fts3expr5.test.

60
61
62
63
64
65
66

60
61
62
63
64
65
66
67







+
  test_fts3expr {(a:123)(b:234)(c:456)}
} {AND {AND {PHRASE 0 0 123} {PHRASE 1 0 234}} {PHRASE 2 0 456}}
do_test 2.2 {
  list [catch { test_fts3expr {"123" AND ( )} } msg] $msg
} {1 {Error parsing expression}}

finish_test

Deleted test/fts3matchinfo2.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



































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020-05-14
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for the FTS3 module. The focus
# of this file is tables created with the "matchinfo=fts3" option.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
ifcapable !fts3 { finish_test ; return }

set sqlite_fts3_enable_parentheses 1

# Crash case found by cyg0810 at gmail.com 2020-05-14.  Reported to
# chromium (which is not vulnerable) who kindly referred it to us.
#
do_execsql_test 1.0 {
  CREATE TABLE t_content(col0 INTEGER);
  CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
  INSERT INTO t0 VALUES (1, '1234','aaaa','bbbb');
  SELECT hex(matchinfo(t0,'yxy'))  FROM t0 WHERE t0 MATCH  x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d';
} {/000000.*0000000/}


set sqlite_fts3_enable_parentheses 0
finish_test

Changes to test/fts3misc.test.

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
222
223
224
225
226
227
228
































































































229
230







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


    INSERT INTO t6 SELECT 'x x x x x x x x x x x' FROM s;
  COMMIT;
}
do_execsql_test 6.1 {
  SELECT rowid FROM t6 WHERE t6 MATCH 'b OR "x a"'
} {50001 50002 50003 50004}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 7.0 {
  CREATE VIRTUAL TABLE vt0 USING fts3(c0);
  INSERT INTO vt0 VALUES (x'00');
}
do_execsql_test 7.1 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
# Ticket [8a6fa2bb].
#
reset_db
do_execsql_test 7.0.1 {
  CREATE VIRTUAL TABLE vt0 USING fts4(c0, order=DESC);
  INSERT INTO vt0(c0) VALUES (0), (0);
}
do_execsql_test 7.0.2 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}
reset_db
do_execsql_test 7.1.1 {
  CREATE VIRTUAL TABLE vt0 USING fts4(c0, order=ASC);
  INSERT INTO vt0(c0) VALUES (0), (0);
}
do_execsql_test 7.1.2 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}
do_execsql_test 7.2.1 {
  CREATE VIRTUAL TABLE ft USING fts4(c0, c1, order=DESC, prefix=1);
  INSERT INTO ft VALUES('a b c d', 'hello world');
  INSERT INTO ft VALUES('negative', 'positive');
  INSERT INTO ft VALUES('hello world', 'a b c d');
}
do_execsql_test 7.2.2 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
# Ticket [745f1abc].
#
reset_db
do_execsql_test 8.1 {
  CREATE VIRTUAL TABLE vt0 USING fts4(c0, prefix=1);
}
do_execsql_test 8.2 {
  BEGIN;
    INSERT INTO vt0 VALUES (0);
    INSERT INTO vt0(vt0) VALUES('optimize');
  COMMIT;
}
do_execsql_test 8.3 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 9.0 {
  CREATE VIRTUAL TABLE t1 using fts4(mailcontent);
  insert into t1(rowid, mailcontent) values
      (-4764623217061966105, 'we are going to upgrade'),
      (8324454597464624651, 'we are going to upgrade');
}

do_execsql_test 9.1 {
  INSERT INTO t1(t1) VALUES('integrity-check');
}

do_execsql_test 9.2 {
  SELECT rowid FROM t1 WHERE t1 MATCH 'upgrade';
} {
  -4764623217061966105 8324454597464624651
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 10.0 {
  CREATE VIRTUAL TABLE f USING fts3(a,b);
  CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB);
  INSERT INTO f_stat VALUES (1,x'3b3b3b3b3b3b3b28ffffffffffffffffff1807f9073481f1d43bc93b3b3b3b3b3b3b3b3b3b18073b3b3b3b3b3b3b9b003b');
} {}

do_catchsql_test 10.1 {
  INSERT INTO f(f) VALUES ('merge=69,59');
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
do_execsql_test 11.0 {
  CREATE VIRTUAL TABLE xyz USING fts3();
}
do_execsql_test 11.1 {
  SELECT * FROM xyz WHERE xyz MATCH 'a NEAR/4294836224 a';
}

finish_test

Changes to test/fts3snippet.test.

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
558
559
560
561
562
563
564

























565
566
567







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



do_test 4.3 {
  llength [db one {
    SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E'
  }]
} {64}


#-------------------------------------------------------------------------
# Request a snippet from a query with more than 64 phrases.
#
do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE t5 USING fts3(x);
  INSERT INTO t5 VALUES('a1 a2 a3');
  INSERT INTO t5 VALUES('a4 a5 a6');
  INSERT INTO t5 VALUES('a70 a71 a72');
}

do_execsql_test 5.1 {
  SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH 
  'a1 OR a2 OR a3 OR a4 OR a5 OR a6 OR a7 OR a8 OR a9 OR a10 OR ' ||
  'a11 OR a12 OR a13 OR a14 OR a15 OR a16 OR a17 OR a18 OR a19 OR a10 OR ' ||
  'a21 OR a22 OR a23 OR a24 OR a25 OR a26 OR a27 OR a28 OR a29 OR a20 OR ' ||
  'a31 OR a32 OR a33 OR a34 OR a35 OR a36 OR a37 OR a38 OR a39 OR a30 OR ' ||
  'a41 OR a42 OR a43 OR a44 OR a45 OR a46 OR a47 OR a48 OR a49 OR a40 OR ' ||
  'a51 OR a52 OR a53 OR a54 OR a55 OR a56 OR a57 OR a58 OR a59 OR a50 OR ' ||
  'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' ||
  'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70'
} {
  {[a1] [a2] [a3]}
  {[a4] [a5] [a6]}
  {[a70] [a71] [a72]}
}

set sqlite_fts3_enable_parentheses 0
finish_test

Deleted test/fts3snippet2.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




























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020-05-14
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
#
# The tests in this file test the FTS3 auxillary functions offsets(), 
# snippet() and matchinfo() work. At time of writing, running this file 
# provides full coverage of fts3_snippet.c.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fts3snippet

# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
ifcapable !fts3 { finish_test ; return }
source $testdir/fts3_common.tcl

set sqlite_fts3_enable_parentheses 1
#-------------------------------------------------------------------------
# Request a snippet from a query with more than 64 phrases.
#
reset_db
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE f USING fts3(b);
  INSERT INTO f VALUES ( x'746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218');
}

do_execsql_test 1.1 {
  SELECT  length(snippet(f))>0  FROM f WHERE b MATCH x'1065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a010f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c2a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e0f42';
} {1}

reset_db
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
  INSERT INTO t0 VALUES (1, '1234','aaaa','bbbb');
  SELECT snippet(t0)  FROM t0 WHERE t0 MATCH x'0a4d4d4d4d320a4f52d70a310a310a4e4541520a0a31f6ce0a4f520a0a310a310a310a4f520a75fc2a242424' ;
} {<b>1</b>}

reset_db
do_execsql_test 2.1 {
  CREATE VIRTUAL TABLE t0 USING fts3(
      col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY
  );
  INSERT INTO t0 VALUES ('one', '1234','aaaa','bbbb');
}
do_execsql_test 2.2 {
  SELECT snippet(t0)  FROM t0 WHERE t0 MATCH 
  '(def AND (one NEAR abc)) OR one'
} {<b>one</b>}

set sqlite_fts3_enable_parentheses 0
finish_test

Changes to test/fts4aa.test.

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
186
187
188
189
190
191
192






























































193
194







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


set ii 0
foreach {q r} [array get fts4aa_res] {
  incr ii
  do_test fts4aa-4.$ii {
    db eval {SELECT docid FROM t1 WHERE words MATCH $::q ORDER BY docid}
  } $r
}

# 2019-11-16 https://bugs.chromium.org/p/chromium/issues/detail?id=1025472
#
db close
sqlite3 db :memory:
do_execsql_test fts4aa-5.10 {
  CREATE VIRTUAL TABLE t1 USING fts4(a, b, c, d, e,f,g,h,i,j,k,l,m,n,o,p,q,r);
  INSERT INTO t1 VALUES('X Y', '2', '3', '4', '5', '6', '7', '8', '9', '0',
                        'a','b','c','d','e','f','g','h');
  UPDATE t1_docsize SET size=x'88' WHERE docid=1;
} {}
do_catchsql_test fts4aa-5.20 {
  SELECT quote(matchinfo(t1, 'l')) FROM t1 WHERE t1 MATCH 'X Y';
} {1 {database disk image is malformed}}
do_execsql_test fts4aa-5.30 {
  DROP TABLE t1;
  CREATE VIRTUAL TABLE t1 USING fts4(a,b,c,d);
  INSERT INTO t1 VALUES('one two','three four','five six','seven eight');
} {}
do_catchsql_test fts4aa-5.40 {
  UPDATE t1_stat SET value=x'01010101' WHERE id=0;
  SELECT quote(matchinfo(t1,'a')) FROM t1 WHERE t1 MATCH 'one two';
} {1 {database disk image is malformed}}
do_catchsql_test fts4aa-5.50 {
  UPDATE t1_stat SET value=x'010101' WHERE id=0;
  SELECT quote(matchinfo(t1,'a')) FROM t1 WHERE t1 MATCH 'one two';
} {1 {database disk image is malformed}}
do_catchsql_test fts4aa-5.60 {
  UPDATE t1_stat SET value=x'01' WHERE id=0;
  SELECT quote(matchinfo(t1,'a')) FROM t1 WHERE t1 MATCH 'one two';
} {1 {database disk image is malformed}}
do_catchsql_test fts4aa-5.70 {
  UPDATE t1_stat SET value=x'' WHERE id=0;
  SELECT quote(matchinfo(t1,'a')) FROM t1 WHERE t1 MATCH 'one two';
} {1 {database disk image is malformed}}

# 2019-11-18 https://bugs.chromium.org/p/chromium/issues/detail?id=1025467
db close
sqlite3 db :memory:
if {$tcl_platform(byteOrder)=="littleEndian"} {
  set res {X'0200000000000000000000000E0000000E00000001000000010000000100000001000000'}
} else {
  set res {X'0000000200000000000000000000000E0000000E00000001000000010000000100000001'}
}
do_catchsql_test fts4aa-6.10 {
  CREATE VIRTUAL TABLE f USING fts4();
  INSERT INTO f_segdir VALUES (77,91,0,0,'255 77',x'0001308000004d5c4ddddddd4d4d7b4d4d4d614d8019ff4d05000001204d4d2e4d6e4d4d4d4b4d6c4d004d4d4d4d4d4d3d000000004d5d4d4d645d4d004d4d4d4d4d4d4d4d4d454d6910004d05ffff054d646c4d004d5d4d4d4d4d3d000000004d4d4d4d4d4d4d4d4d4d4d69624d4d4d04004d4d4d4d4d604d4ce1404d554d45');
  INSERT INTO f_segdir VALUES (77,108,0,0,'255 77',x'0001310000fa64004d4d4d3c5d4d654d4d4d614d8000ff4d05000001204d4d2e4d6e4d4d4dff4d4d4d4d4d4d00104d4d4d4d000000004d4d4d0400311d4d4d4d4d4d4d4d4d4d684d6910004d05ffff054d4d6c4d004d4d4d4d4d4d3d000000004d4d4d4d644d4d4d4d4d4d69624d4d4d03ed4d4d4d4d4d604d4ce1404d550080');
  INSERT INTO f_stat VALUES (0,x'80808080100000000064004d4d4d3c4d4d654d4d4d614d8000ff4df6ff1a00204d4d2e4d6e4d4d4d104d4d4d4d4d4d00104d4d4d4d4d4d69574d4d4d000031044d4d4d3e4d4d4c4d05004d6910');
  SELECT quote(matchinfo(f,'pnax')) from f where f match '0 1';
} {1 {database disk image is malformed}}

# 2019-11-18 Detect infinite loop in fts3SelectLeaf()
db close
sqlite3 db :memory:
do_catchsql_test fts4aa-7.10 {
  CREATE VIRTUAL TABLE f USING fts4();
  INSERT INTO f_segdir VALUES (63,60,60,60,'60 60',x'3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c483c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c20003c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c283c3c3c3c3c3c3c3c3c3c3c223c3c3c3c3c3c3c3c3c');
  INSERT INTO f_segments VALUES (60,x'3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c5a3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2a3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c5e3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c803c3c3c3c3c3c233c3c3c3c1c3c3c3c3c3c3c3c3c3c3c3c1b3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c273c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1a3c3c3c3c3c3c000200003c3c3c3c3c3c3c3c3c3c3c3c3c383c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d898d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d3c3c3c3c3c3c3c3c3c3cba3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c00023c3c3c3c3c3c383c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cbc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2c3c3c3c403c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c16161616161616163c3c3c3c3c3c3c3c3c3c3c3c3c583c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2b3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1c013c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c20003c3c3c3c3c3c3c3c3c3c3c800000003c3c3c3c3c3c3c2c3c3c3c3c3c3c353c08080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808f4080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808083c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c323c3c3c3c3c3c3c3c3c3c3c4f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cfcfcfcfcfcfcfcfcfcfcfc10fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfd02fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc03e8fcfcfcfc3c3c3c3c3c3c8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c553c3c3c3c3c3c3c3c3c3c3c3c3c573c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c000000803c3c4dd5d5a6d52cf3d5d5d5d5d5d5d5d5d5d5d5d5d5d53c3c3c3c3f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c013c3c3c3c00643c3c3c3ce93c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c263c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c363c3c3c3c3c3c3c3c3c3c3c3c3c3c543c3c3c3c3c3c3c3c3c3c273c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c330000003c3c3c3c3c3c3c3c3c3c3c3c3c3c4d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c000010003c3c3c3c3c3c413c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c403c3c3c3c3c3c3c3c3c3c3c3cec0000fa3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c4c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c5e3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1b3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c593c3c3c3c3c3c243c3c373c3c3c3c3cff3c3c3c3c3c3c3c3c3c3c3c3c3c000080003c3c3c3c3c3c3c3c3c3c353c3c3c3c3c3d3c3c3c3c3c3c3c3c3c3c3c3c4d3c3c3c3c3c3c3c3c3c3c3c3c3c40003c3c3c3c3c293c3c3c3c3c3c3c3c3c3d3c3c3c3c3c3c3c3c353c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c4f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cff7f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ca43c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cbf3c3c3c3c3c3c3c3c3c008000003c3c3c3c3c3c3c3c343c3c373c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c593c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c');
  SELECT * from f where f match '0';
} {1 {database disk image is malformed}}


finish_test

Changes to test/fts4content.test.

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
629
630
631
632
633
634
635




































636
637
638







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



# Test cases 11.*
# 
reset_db

do_catchsql_test 11.1 {
  CREATE VIRTUAL TABLE x1 USING fts4(content=x1);
} {1 {vtable constructor called recursively: x1}}

#---------------------------------------------------------------------------
# Check that an fts4 table cannot be its own content table.
#
reset_db
breakpoint
do_execsql_test 12.1.1 {
  CREATE VIRTUAL TABLE t1 USING fts4(a, content=t1 );
  INSERT INTO t1(rowid, a) VALUES(1, 'abc');
}
do_catchsql_test 12.1.2 { 
  SELECT * FROM t1; 
} {1 {SQL logic error}}
do_catchsql_test 12.1.3 { 
  SELECT * FROM t1('abc'); 
} {1 {SQL logic error}}
do_catchsql_test 12.1.4 { 
  SELECT count(*) FROM t1;
} {1 {SQL logic error}}

reset_db
do_execsql_test 12.2.1 {
  CREATE VIRTUAL TABLE t1 USING fts4(a, content=t2 );
  CREATE VIRTUAL TABLE t2 USING fts4(a, content=t1 );
  INSERT INTO t1(rowid, a) VALUES(1, 'abc');
}
do_catchsql_test 12.2.2 { 
  SELECT * FROM t1; 
} {1 {SQL logic error}}
do_catchsql_test 12.2.3 { 
  SELECT * FROM t1('abc'); 
} {1 {SQL logic error}}
do_catchsql_test 12.2.4 { 
  SELECT count(*) FROM t1;
} {1 {SQL logic error}}



finish_test

Changes to test/fts4langid.test.

485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
485
486
487
488
489
490
491















492







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  } {1 2 5}

  do_execsql_test 5.4.$lid.5 {
    SELECT count(*) FROM t6_segdir;
    SELECT count(*) FROM t6_segments;
  } {1 2}
}

reset_db
do_execsql_test 6.0 {
  CREATE VIRTUAL TABLE vt0 USING fts4(c0, languageid="lid");
  INSERT INTO vt0 VALUES ('a'), ('b');
  BEGIN;
    UPDATE vt0 SET lid = 1 WHERE lid=0;
}
do_execsql_test 6.1 {
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}
do_execsql_test 6.2 {
  COMMIT;
  INSERT INTO vt0(vt0) VALUES('integrity-check');
}
finish_test

Changes to test/fts4merge.test.

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
322
323
324
325
326
327
328

329















330
331
332







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



    expr { ([db total_changes] - $x)>1 }
  } {0}
  do_test 7.5 {
    set x [db total_changes]
    execsql { INSERT INTO t1(t1) VALUES('merge=200,10') }
    expr { ([db total_changes] - $x)>1 }
  } {0}
}


#-------------------------------------------------------------------------
# Test cases 8.* - ticket [bf1aab89].
#
set testprefix fts4merge
reset_db
do_execsql_test 8.0 {
  CREATE VIRTUAL TABLE t1 USING fts4(a, order=DESC);
  INSERT INTO t1(a) VALUES (0);
  INSERT INTO t1(a) VALUES (0);
  UPDATE t1 SET a = NULL;
} 

do_execsql_test 8.1 {
  INSERT INTO t1(t1) VALUES('merge=1,4');
}

finish_test

Deleted test/fts4merge5.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


























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 October 02
#
# 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 FTS4 module.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fts4merge5

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
  finish_test
  return
}

source $testdir/genesis.tcl

do_execsql_test 1.1 { 
  CREATE TABLE t1(docid, words);
}
fts_kjv_genesis

do_execsql_test 1.2 {
  CREATE VIRTUAL TABLE x1 USING fts3; 
  INSERT INTO x1(x1) VALUES('nodesize=64');
  INSERT INTO x1(x1) VALUES('maxpending=64');
}

do_execsql_test 1.3 {
  INSERT INTO x1(docid, content) SELECT * FROM t1;
}

for {set tn 1} {1} {incr tn} {
  set tc1 [db total_changes]
  do_execsql_test 1.4.$tn.1 {
    INSERT INTO x1(x1) VALUES('merge=1,2');
  }
  set tc2 [db total_changes]

  if {($tc2 - $tc1)<2} break

  do_execsql_test 1.4.$tn.1 {
    INSERT INTO x1(x1) VALUES('integrity-check');
  }
}



finish_test

Deleted test/fts4min.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





















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 February 27
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set ::testprefix fts4min

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
  finish_test
  return
}

#------------------------------------------------------------------
do_execsql_test 0.0 {
  CREATE TABLE t1(a NOT NULL, b);
  CREATE INDEX i1 ON t1(a);
}

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE ft USING fts3(c);
  INSERT INTO ft(docid, c) VALUES(22, 'hello world');
  INSERT INTO ft(docid, c) VALUES(44, 'hello world');
  INSERT INTO ft(docid, c) VALUES(11, 'hello world');
}

do_eqp_test 1.1.1 {
  SELECT max(rowid) FROM ft
} {VIRTUAL TABLE INDEX 0:DESC}

do_eqp_test 1.1.2 {
  SELECT min(rowid) FROM ft
} {VIRTUAL TABLE INDEX 0:ASC}

do_execsql_test 1.2.1 {
  SELECT max(rowid) FROM ft
} {44}

do_execsql_test 1.2.2 {
  SELECT min(rowid) FROM ft
} {11}

finish_test

Deleted test/fts4record.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
























































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 September 18
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the FTS4 module.
#
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set testprefix fts4record

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
  finish_test
  return
}

sqlite3_fts3_may_be_corrupt 1

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts4(x);
  INSERT INTO t1 VALUES('terma terma terma termb');
}

do_execsql_test 1.1 {
  SELECT quote(root) FROM t1_segdir
} {
  X'00057465726D6105010203030004016203010500'
}

proc make_record_wrapper {args} { make_fts3record $args }
db func record make_record_wrapper

do_execsql_test 1.2 {
  select quote( 
    record(0,    5, 'terma', 5, 1, 2, 3, 3, 0, 
              4, 1, 'b'    , 3, 1, 5, 0
  ) );
} {
  X'00057465726D6105010203030004016203010500'
}

do_execsql_test 1.3.1 {
  UPDATE t1_segdir SET root = 
    record(0,    5, 'terma', 5, 1, 2, 3, 3, 0, 
              4, 1, 'b'    , 3, 1, 5, 
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
          );
}

do_catchsql_test 1.3.2 {
  SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
} {1 {database disk image is malformed}}

do_execsql_test 1.4.1 {
  UPDATE t1_segdir SET root = 
    record(0,    5, 'terma', 5, 1, 2, 3, 3, 0, 
              4, 1, 'b'    , 4, 1, 5, 
              256, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
          );
}

do_catchsql_test 1.4.2 {
  SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
} {1 {database disk image is malformed}}

do_execsql_test 1.4.3 {
  SELECT quote(root) FROM t1_segdir
} {
  X'00057465726D610501020303000401620401058002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
}

do_execsql_test 1.5.1 {
  UPDATE t1_segdir SET root = 
    record(0,    5, 'terma', 5, 1, 2, 3, 3, 0, 
              4, 1, 'b'    , 4, 1, 5, 
              256, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
          );
}

do_catchsql_test 1.4.2 {
  SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
} {1 {database disk image is malformed}}

do_execsql_test 1.4.3 {
  SELECT quote(root) FROM t1_segdir
} {
  X'00057465726D610501020303000401620401058002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
}


do_execsql_test 1.5.1 {
  UPDATE t1_segdir SET root = 
  X'00057465726D61050102030300040162040105FF00010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
}

do_catchsql_test 1.5.2 {
  SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
} {1 {database disk image is malformed}}

do_catchsql_test 1.5.3 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

finish_test

Deleted test/fts4rename.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











































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 April 30
#
# 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/fts3_common.tcl
set ::testprefix fts4rename

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
  finish_test
  return
}

do_execsql_test 1.0 {
  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;
  DROP TABLE t1;
} {0 {}}

finish_test

Changes to test/fts4unicode.test.

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
563
564
565
566
567
568
569


















570







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

    "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

Deleted test/fts4upfrom.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












































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 February 24
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing UPDATE statements with FROM clauses
# against FTS4 tables.
#
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fts4upfrom

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
  finish_test
  return
}

foreach {tn create_table} {
  0 { CREATE VIRTUAL TABLE ft USING fts5(a, b, c) }
  1 { CREATE VIRTUAL TABLE ft USING fts3(a, b, c) }
  2 { CREATE TABLE ft(a, b, c) }
  3 { 
    CREATE TABLE real(a, b, c);
    CREATE INDEX i1 ON real(a);
    CREATE VIEW ft AS SELECT rowid, a, b, c FROM real;
    CREATE TRIGGER tr1 INSTEAD OF INSERT ON ft BEGIN
      INSERT INTO real(rowid, a, b, c) VALUES(new.rowid, new.a, new.b, new.c);
    END;
    CREATE TRIGGER tr2 INSTEAD OF UPDATE ON ft BEGIN
      UPDATE real SET rowid=new.rowid, a=new.a, b=new.b, c=new.c 
      WHERE rowid=old.rowid;
    END;
  }
} {
  if {$tn==0} { ifcapable !fts5 { continue } }
  catchsql { DROP VIEW IF EXISTS changes }
  catchsql { DROP TABLE IF EXISTS ft }
  catchsql { DROP VIEW IF EXISTS ft }
  execsql $create_table

  do_execsql_test 1.$tn.0 {
    INSERT INTO ft(a, b, c) VALUES('a', NULL, 'apple');
    INSERT INTO ft(a, b, c) VALUES('b', NULL, 'banana');
    INSERT INTO ft(a, b, c) VALUES('c', NULL, 'cherry');
    INSERT INTO ft(a, b, c) VALUES('d', NULL, 'damson plum');
  }
  
  do_execsql_test 1.$tn.1 {
    SELECT a, b, c FROM ft ORDER BY rowid;
  } {
    a {} apple
    b {} banana
    c {} cherry
    d {} {damson plum}
  }
  
  do_execsql_test 1.$tn.2 {
    UPDATE ft SET b=o.c FROM ft AS o WHERE (ft.a == char(unicode(o.a)+1))
  }
  
  do_execsql_test 1.$tn.3 {
    SELECT a, b, c FROM ft ORDER BY rowid;
  } {
    a {} apple
    b apple banana
    c banana cherry
    d cherry {damson plum}
  }

  do_catchsql_test 1.$tn.4 {
    UPDATE ft SET c=v FROM changes WHERE a=k;
  } {1 {no such table: changes}}

  do_execsql_test 1.$tn.5 {
    create view changes(k, v) AS 
      VALUES( 'd', 'dewberry' ) UNION ALL
      VALUES( 'c', 'clementine' ) UNION ALL
      VALUES( 'b', 'blueberry' ) UNION ALL
      VALUES( 'a', 'apricot' ) 
    ;
  }

  do_execsql_test 1.$tn.6 {
    UPDATE ft SET c=v FROM changes WHERE a=k;
  }

  do_execsql_test 1.$tn.7 {
    SELECT rowid, a, b, c FROM ft ORDER BY rowid;
  } {
    1 a {} apricot
    2 b apple blueberry
    3 c banana clementine
    4 d cherry dewberry
  }

  do_execsql_test 1.$tn.8 "
    WITH x1(o, n) AS (
        VALUES(1, 11) UNION ALL
        VALUES(2, 12) UNION ALL
        VALUES(3, 13) UNION ALL
        VALUES(4, 14)
    )
    SELECT ft.rowid, a, b, c, o, n FROM ft, x1 WHERE ft.rowid = o;
  " {
    1 a {} apricot 1 11
    2 b apple blueberry 2 12
    3 c banana clementine 3 13
    4 d cherry dewberry 4 14
  }

  set ROWID rowid
  if {$tn==1} { set ROWID docid }
  do_execsql_test 1.$tn.9 "
    WITH x1(o, n) AS (
        VALUES(1, 11) UNION ALL
        VALUES(2, 12) UNION ALL
        VALUES(3, 13) UNION ALL
        VALUES(4, 14)
    )
    UPDATE ft SET $ROWID = n FROM x1 WHERE ft.rowid = o;
    SELECT rowid, a, b, c FROM ft ORDER BY rowid;
  " {
    11 a {} apricot
    12 b apple blueberry
    13 c banana clementine
    14 d cherry dewberry
  }
}

finish_test

Changes to test/func.test.

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
311
312
313
314
315
316
317



318
319
320
321
322
323
324







-
-
-







  } {99999999999995.0}
  do_test func-4.37 {
    execsql {SELECT round(9999999999999.55,1);}
  } {9999999999999.6}
  do_test func-4.38 {
    execsql {SELECT round(9999999999999.556,2);}
  } {9999999999999.56}
  do_test func-4.39 {
    string tolower [db eval {SELECT round(1e500), round(-1e500);}]
  } {inf -inf}
}

# Test the upper() and lower() functions
#
do_test func-5.1 {
  execsql {SELECT upper(t1) FROM tbl1}
} {THIS PROGRAM IS FREE SOFTWARE}
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424

1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1412
1413
1414
1415
1416
1417
1418



1419




































1420




1421


































1422







-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_execsql_test func-32.140 {
  SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1;
} {0}
do_execsql_test func-32.150 {
  SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y;
} {8}

# 2019-08-15
# Direct-only functions.
#

proc testdirectonly {x} {return [expr {$x*2}]}
do_test func-33.1 {
  db func testdirectonly -directonly testdirectonly
  db eval {SELECT testdirectonly(15)}
} {30}
do_catchsql_test func-33.2 {
  CREATE VIEW v33(y) AS SELECT testdirectonly(15);
  SELECT * FROM v33;
} {1 {unsafe use of testdirectonly()}}
do_execsql_test func-33.3 {
  SELECT * FROM (SELECT testdirectonly(15)) AS v33;
} {30}
do_execsql_test func-33.4 {
  WITH c(x) AS (SELECT testdirectonly(15))
  SELECT * FROM c;
} {30}
do_catchsql_test func-33.5 {
  WITH c(x) AS (SELECT * FROM v33)
  SELECT * FROM c;
} {1 {unsafe use of testdirectonly()}}
do_execsql_test func-33.10 {
  CREATE TABLE t33a(a,b);
  CREATE TABLE t33b(x,y);
  CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
    INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b);
  END;
} {}
do_catchsql_test func-33.11 {
  INSERT INTO t33a VALUES(1,2);
} {1 {unsafe use of testdirectonly()}}
do_execsql_test func-33.20 {
  ALTER TABLE t33a RENAME COLUMN a TO aaa;
  SELECT sql FROM sqlite_master WHERE name='r1';
} {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
    INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b);
  END}}

# 2020-01-09 Yongheng fuzzer find
# The bug is in the register-validity debug logic, not in the SQLite core
# and as such it only impacts debug builds.  Release builds work fine.
#

reset_db
do_execsql_test func-34.10 {
  CREATE TABLE t1(a INT CHECK(
     datetime( 0, 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,a)
   )
  );
  INSERT INTO t1(a) VALUES(1),(2);
  SELECT * FROM t1;
} {1 2}

# 2020-03-11 COALESCE() should short-circuit
# See also ticket 3c9eadd2a6ba0aa5
# Both issues stem from the fact that functions that could
# throw exceptions were being factored out into initialization
# code.  The fix was to put those function calls inside of
# OP_Once instead.
#
reset_db
do_execsql_test func-35.100 {
  CREATE TABLE t1(x);
  SELECT coalesce(x, abs(-9223372036854775808)) FROM t1;
} {}
do_execsql_test func-35.110 {
  SELECT coalesce(x, 'xyz' LIKE printf('%.1000000c','y')) FROM t1;
} {}
do_execsql_test func-35.200 {
  CREATE TABLE t0(c0 CHECK(ABS(-9223372036854775808)));
  PRAGMA integrity_check;
} {ok}

finish_test

Changes to test/func3.test.

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
149
150
151
152
153
154
155













156
157
158
159
160
161
162







-
-
-
-
-
-
-
-
-
-
-
-
-







# the code generator optimizes away so that it consumes no CPU cycles at
# run-time (that is, during calls to sqlite3_step()).
#
do_test func3-5.39 {
  db eval {EXPLAIN SELECT unlikely(min(1.0+'2.0',4*11))}
} [db eval {EXPLAIN SELECT min(1.0+'2.0',4*11)}]

# Unlikely() does not preserve the affinity of X.
# ticket https://www.sqlite.org/src/tktview/0c620df60b
#
do_execsql_test func3-5.40 {
  SELECT likely(CAST(1 AS INT))=='1';
} 0
do_execsql_test func3-5.41 {
  SELECT unlikely(CAST(1 AS INT))=='1';
} 0
do_execsql_test func3-5.41 {
  SELECT likelihood(CAST(1 AS INT),0.5)=='1';
} 0


# EVIDENCE-OF: R-23735-03107 The likely(X) function returns the argument
# X unchanged.
#
do_execsql_test func3-5.50 {
  SELECT likely(9223372036854775807);
} {9223372036854775807}

Changes to test/func4.test.

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
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







-
+




-
+




-
+




-
+




-
+




-
+









-
+









-
+




-
+




-
+




-
+




-
+




-
+









-
+





-
+


-
-
+
+











-
+




-
+




-
+




-
+




-
+




-
+







      x INTEGER CHECK(tointeger(x) IS NOT NULL)
    );
  } {}
  do_test func4-3.2 {
    catchsql {
      INSERT INTO t1 (x) VALUES (NULL);
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.3 {
    catchsql {
      INSERT INTO t1 (x) VALUES (NULL);
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.4 {
    catchsql {
      INSERT INTO t1 (x) VALUES ('');
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.5 {
    catchsql {
      INSERT INTO t1 (x) VALUES ('bad');
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.6 {
    catchsql {
      INSERT INTO t1 (x) VALUES ('1234bad');
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.7 {
    catchsql {
      INSERT INTO t1 (x) VALUES ('1234.56bad');
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.8 {
    catchsql {
      INSERT INTO t1 (x) VALUES (1234);
    }
  } {0 {}}
  do_test func4-3.9 {
    catchsql {
      INSERT INTO t1 (x) VALUES (1234.56);
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.10 {
    catchsql {
      INSERT INTO t1 (x) VALUES ('1234');
    }
  } {0 {}}
  do_test func4-3.11 {
    catchsql {
      INSERT INTO t1 (x) VALUES ('1234.56');
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.12 {
    catchsql {
      INSERT INTO t1 (x) VALUES (ZEROBLOB(4));
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.13 {
    catchsql {
      INSERT INTO t1 (x) VALUES (X'');
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.14 {
    catchsql {
      INSERT INTO t1 (x) VALUES (X'1234');
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.15 {
    catchsql {
      INSERT INTO t1 (x) VALUES (X'12345678');
    }
  } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.16 {
    catchsql {
      INSERT INTO t1 (x) VALUES ('1234.00');
    }
  } {0 {}}
  } {1 {CHECK constraint failed: t1}}
  do_test func4-3.17 {
    catchsql {
      INSERT INTO t1 (x) VALUES (1234.00);
    }
  } {0 {}}
  do_test func4-3.18 {
    catchsql {
      INSERT INTO t1 (x) VALUES ('-9223372036854775809');
    }
  } {0 {}}
  } {1 {CHECK constraint failed: t1}}
  if {$highPrecision(1)} {
    do_test func4-3.19 {
      catchsql {
        INSERT INTO t1 (x) VALUES (9223372036854775808);
      }
    } {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t1}}
  }
  do_execsql_test func4-3.20 {
    SELECT x FROM t1 WHERE x>0 ORDER BY x;
  } {1234 1234 1234 1234}
    SELECT x FROM t1 ORDER BY x;
  } {1234 1234 1234}

  ifcapable floatingpoint {
    do_execsql_test func4-4.1 {
      CREATE TABLE t2(
        x REAL CHECK(toreal(x) IS NOT NULL)
      );
    } {}
    do_test func4-4.2 {
      catchsql {
        INSERT INTO t2 (x) VALUES (NULL);
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.3 {
      catchsql {
        INSERT INTO t2 (x) VALUES (NULL);
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.4 {
      catchsql {
        INSERT INTO t2 (x) VALUES ('');
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.5 {
      catchsql {
        INSERT INTO t2 (x) VALUES ('bad');
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.6 {
      catchsql {
        INSERT INTO t2 (x) VALUES ('1234bad');
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.7 {
      catchsql {
        INSERT INTO t2 (x) VALUES ('1234.56bad');
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.8 {
      catchsql {
        INSERT INTO t2 (x) VALUES (1234);
      }
    } {0 {}}
    do_test func4-4.9 {
      catchsql {
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
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







-
+




-
+




-
+




-
+







        INSERT INTO t2 (x) VALUES ('1234.56');
      }
    } {0 {}}
    do_test func4-4.12 {
      catchsql {
        INSERT INTO t2 (x) VALUES (ZEROBLOB(4));
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.13 {
      catchsql {
        INSERT INTO t2 (x) VALUES (X'');
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.14 {
      catchsql {
        INSERT INTO t2 (x) VALUES (X'1234');
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_test func4-4.15 {
      catchsql {
        INSERT INTO t2 (x) VALUES (X'12345678');
      }
    } {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
    } {1 {CHECK constraint failed: t2}}
    do_execsql_test func4-4.16 {
      SELECT x FROM t2 ORDER BY x;
    } {1234.0 1234.0 1234.56 1234.56}
  }
}

ifcapable floatingpoint {

Changes to test/func5.test.

49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
49
50
51
52
53
54
55

56
57

58
59
60
61
62
63







-


-
+





} {1 2 3 4 5 6 7 8}
sqlite3_create_function db
do_execsql_test func5-2.2 {
  SELECT x, y FROM t2
   WHERE x+counter1('hello')=counter1('hello')+x
   ORDER BY +x;
} {}
set cvalue [db one {SELECT counter2('hello')+1}]
do_execsql_test func5-2.3 {
  SELECT x, y FROM t2
   WHERE x+counter2('hello')=$cvalue+x
   WHERE x+counter2('hello')=counter2('hello')+x
   ORDER BY +x;
} {1 2 3 4 5 6 7 8}


finish_test

Deleted 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/fuzz_common.tcl.

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
359
360
361
362
363
364
365

366
367
368
369
370
371
372







-







  set ::fuzzyopts(-repeats) $::REPEATS
  array set ::fuzzyopts $args

  lappend ::fuzzyopts(-errorlist) {parser stack overflow} 
  lappend ::fuzzyopts(-errorlist) {ORDER BY}
  lappend ::fuzzyopts(-errorlist) {GROUP BY}
  lappend ::fuzzyopts(-errorlist) {datatype mismatch}
  lappend ::fuzzyopts(-errorlist) {non-deterministic functions prohibited}

  for {set ii 0} {$ii < $::fuzzyopts(-repeats)} {incr ii} {
    do_test ${testname}.$ii {
      set ::sql [subst $::fuzzyopts(-template)]
      puts $::log $::sql
      flush $::log
      set rc [catch {execsql $::sql} msg]

Changes to test/fuzzcheck.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14


15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22













-
+
+







/*
** 2015-05-25
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This is a utility program designed to aid running regressions tests on
** the SQLite library using data from external fuzzers.
** the SQLite library using data from an external fuzzer, such as American
** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/).
**
** This program reads content from an SQLite database file with the following
** schema:
**
**     CREATE TABLE db(
**       dbid INTEGER PRIMARY KEY, -- database id
**       dbcontent BLOB            -- database disk file image
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

















+
-
-
-
+
+
+
+







** tables.  Then do "./fuzzcheck new.db" to run the tests.
**
** DEBUGGING HINTS:
**
** If fuzzcheck does crash, it can be run in the debugger and the content
** of the global variable g.zTextName[] will identify the specific XSQL and
** DB values that were running when the crash occurred.
**
** DBSQLFUZZ:
**
** The dbsqlfuzz fuzzer includes both a database file and SQL to run against
** that database in its input.  This utility can now process dbsqlfuzz
** input files.  Load such files using the "--load-dbsql FILE ..." command-line
** option.
**
** Dbsqlfuzz inputs are ordinary text.  The first part of the file is text
** that describes the content of the database (using a lot of hexadecimal),
** then there is a divider line followed by the SQL to run against the
** database.  Because they are ordinary text, dbsqlfuzz inputs are stored
** in the XSQL table, as if they were ordinary SQL inputs.  The isDbSql()
** function can look at a text string and determine whether or not it is
** a valid dbsqlfuzz input.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <assert.h>
#include "sqlite3.h"
#define ISSPACE(X) isspace((unsigned char)(X))
#define ISDIGIT(X) isdigit((unsigned char)(X))


#ifdef __unix__
# include <signal.h>
# include <unistd.h>
#endif

#ifdef SQLITE_OSS_FUZZ
#include <stddef.h>
#if !defined(_MSC_VER)
# include <stdint.h>
# include <stddef.h>
# if !defined(_MSC_VER)
#  include <stdint.h>
# endif
#endif

#if defined(_MSC_VER)
typedef unsigned char uint8_t;
#endif

/*
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
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







-














-
-
-
-
+
+
+
+
+








-
+


-
+
-
-
-
-
-
-
-
-
+
-
-
-
+







#define MX_FILE_SZ 10000000

/*
** All global variables are gathered into the "g" singleton.
*/
static struct GlobalVars {
  const char *zArgv0;              /* Name of program */
  const char *zDbFile;             /* Name of database file */
  VFile aFile[MX_FILE];            /* The virtual filesystem */
  int nDb;                         /* Number of template databases */
  Blob *pFirstDb;                  /* Content of first template database */
  int nSql;                        /* Number of SQL scripts */
  Blob *pFirstSql;                 /* First SQL script */
  unsigned int uRandom;            /* Seed for the SQLite PRNG */
  char zTestName[100];             /* Name of current test */
} g;

/*
** Print an error message and quit.
*/
static void fatalError(const char *zFormat, ...){
  va_list ap;
  fprintf(stderr, "%s", g.zArgv0);
  if( g.zDbFile ) fprintf(stderr, " %s", g.zDbFile);
  if( g.zTestName[0] ) fprintf(stderr, " (%s)", g.zTestName);
  fprintf(stderr, ": ");
  if( g.zTestName[0] ){
    fprintf(stderr, "%s (%s): ", g.zArgv0, g.zTestName);
  }else{
    fprintf(stderr, "%s: ", g.zArgv0);
  }
  va_start(ap, zFormat);
  vfprintf(stderr, zFormat, ap);
  va_end(ap);
  fprintf(stderr, "\n");
  exit(1);
}

/*
** signal handler
** Timeout handler
*/
#ifdef __unix__
static void signalHandler(int signum){
static void timeoutHandler(int NotUsed){
  const char *zSig;
  if( signum==SIGABRT ){
    zSig = "abort";
  }else if( signum==SIGALRM ){
    zSig = "timeout";
  }else if( signum==SIGSEGV ){
    zSig = "segfault";
  }else{
  (void)NotUsed;
    zSig = "signal";
  }
  fatalError(zSig);
  fatalError("timeout\n");
}
#endif

/*
** Set the an alarm to go off after N seconds.  Disable the alarm
** if N==0
*/
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
309
310
311
312
313
314
315

































316
317
318
319
320
321
322







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
  }else{
    sqlite3_free(pBuf);
  }
  fclose(in);
}

/*
** Implementation of the "readtextfile(X)" SQL function.  The text content
** of the file named X through the end of the file or to the first \000
** character, whichever comes first, is read and returned as TEXT.  NULL
** is returned if the file does not exist or is unreadable.
*/
static void readtextfileFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zName;
  FILE *in;
  long nIn;
  char *pBuf;

  zName = (const char*)sqlite3_value_text(argv[0]);
  if( zName==0 ) return;
  in = fopen(zName, "rb");
  if( in==0 ) return;
  fseek(in, 0, SEEK_END);
  nIn = ftell(in);
  rewind(in);
  pBuf = sqlite3_malloc64( nIn+1 );
  if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
    pBuf[nIn] = 0;
    sqlite3_result_text(context, pBuf, -1, sqlite3_free);
  }else{
    sqlite3_free(pBuf);
  }
  fclose(in);
}

/*
** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
** is written into file X.  The number of bytes written is returned.  Or
** NULL is returned if something goes wrong, such as being unable to open
** file X for writing.
*/
static void writefileFunc(
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469
470
397
398
399
400
401
402
403

404





405
406
407
408
409
410
411







-
+
-
-
-
-
-







  while( p ){
    pNext = p->pNext;
    free(p);
    p = pNext;
  }
}

/* Return the current wall-clock time
/* 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;
  }
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
449
450
451
452
453
454
455






456
457
458
459
460



















































461
462
463
464
465
466
467







-
-
-
-
-
-





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








/* Maximum number of progress handler callbacks */
static unsigned int mxProgressCb = 2000;

/* Maximum string length in SQLite */
static int lengthLimit = 1000000;

/* Maximum expression depth */
static int depthLimit = 500;

/* Limit on the amount of heap memory that can be used */
static sqlite3_int64 heapLimit = 100000000;

/* Maximum byte-code program length in SQLite */
static int vdbeOpLimit = 25000;

/* Maximum size of the in-memory database */
static sqlite3_int64 maxDbSize = 104857600;
/* OOM simulation parameters */
static unsigned int oomCounter = 0;    /* Simulate OOM when equals 1 */
static unsigned int oomRepeat = 0;     /* Number of OOMs in a row */
static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */

/* This routine is called when a simulated OOM occurs.  It is broken
** out as a separate routine to make it easy to set a breakpoint on
** the OOM
*/
void oomFault(void){
  if( eVerbosity ){
    printf("Simulated OOM fault\n");
  }
  if( oomRepeat>0 ){
    oomRepeat--;
  }else{
    oomCounter--;
  }
}

/* This routine is a replacement malloc() that is used to simulate
** Out-Of-Memory (OOM) errors for testing purposes.
*/
static void *oomMalloc(int nByte){
  if( oomCounter ){
    if( oomCounter==1 ){
      oomFault();
      return 0;
    }else{
      oomCounter--;
    }
  }
  return defaultMalloc(nByte);
}

/* Register the OOM simulator.  This must occur before any memory
** allocations */
static void registerOomSimulator(void){
  sqlite3_mem_methods mem;
  sqlite3_shutdown();
  sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem);
  defaultMalloc = mem.xMalloc;
  mem.xMalloc = oomMalloc;
  sqlite3_config(SQLITE_CONFIG_MALLOC, &mem);
}

/* Turn off any pending OOM simulation */
static void disableOom(void){
  oomCounter = 0;
  oomRepeat = 0;
}

/*
** Translate a single byte of Hex into an integer.
** This routine only works if h really is a valid hexadecimal
** character:  0..9a..fA..F
*/
static unsigned char hexToInt(unsigned int h){
628
629
630
631
632
633
634
635

636
637
638
639
640
641
642
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526







-
+







*/
static int decodeDatabase(
  const unsigned char *zIn,      /* Input text to be decoded */
  int nIn,                       /* Bytes of input text */
  unsigned char **paDecode,      /* OUT: decoded database file */
  int *pnDecode                  /* OUT: Size of decoded database */
){
  unsigned char *a, *aNew;       /* Database under construction */
  unsigned char *a;              /* Database under construction */
  int mx = 0;                    /* Current size of the database */
  sqlite3_uint64 nAlloc = 4096;  /* Space allocated in a[] */
  unsigned int i;                /* Next byte of zIn[] to read */
  unsigned int j;                /* Temporary integer */
  unsigned int k;                /* half-byte cursor index for output */
  unsigned int n;                /* Number of bytes of input */
  unsigned char b = 0;
674
675
676
677
678
679
680
681
682
683




684
685
686
687
688
689
690
691
692
693
558
559
560
561
562
563
564



565
566
567
568

569

570
571
572
573
574
575
576







-
-
-
+
+
+
+
-

-







          if( newSize>MX_FILE_SZ ){
            if( j>=MX_FILE_SZ ){
              sqlite3_free(a);
              return -1;
            }
            newSize = MX_FILE_SZ;
          }
          aNew = sqlite3_realloc64( a, newSize );
          if( aNew==0 ){
            sqlite3_free(a);
          a = sqlite3_realloc64( a, newSize );
          if( a==0 ){
            fprintf(stderr, "Out of memory!\n");
            exit(1);
            return -1;
          }
          a = aNew;
          assert( newSize > nAlloc );
          memset(a+nAlloc, 0, (size_t)(newSize - nAlloc));
          nAlloc = newSize;
        }
        if( j>=(unsigned)mx ){
          mx = (j + 4095)&~4095;
          if( mx>MX_FILE_SZ ) mx = MX_FILE_SZ;
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
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

620
621
622
623
624
625
626
627
628
629
630
631
632
633
634







635
636
637
638
639
640







641
642
643

644
645
646
647
648
649
650







-
















-
+














-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
-







** 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;
  }
  return rc;
}

/*
** Disallow debugging pragmas such as "PRAGMA vdbe_debug" and
** "PRAGMA parser_trace" since they can dramatically increase the
** amount of output without actually testing anything useful.
**
** Also block ATTACH if attaching a file from the filesystem.
** Also block ATTACH and DETACH
*/
static int block_troublesome_sql(
  void *Notused,
  int eCode,
  const char *zArg1,
  const char *zArg2,
  const char *zArg3,
  const char *zArg4
){
  (void)Notused;
  (void)zArg2;
  (void)zArg3;
  (void)zArg4;
  if( eCode==SQLITE_PRAGMA ){
   if( eVerbosity==0 ){
      if( sqlite3_strnicmp("vdbe_", zArg1, 5)==0
       || sqlite3_stricmp("parser_trace", zArg1)==0
       || sqlite3_stricmp("temp_store_directory", zArg1)==0
      ){
        return SQLITE_DENY;
      }
    if( sqlite3_strnicmp("vdbe_", zArg1, 5)==0
     || sqlite3_stricmp("parser_trace", zArg1)==0
     || sqlite3_stricmp("temp_store_directory", zArg1)==0
    ){
      return SQLITE_DENY;
    }
    }else 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;
  }else if( (eCode==SQLITE_ATTACH || eCode==SQLITE_DETACH)
            && zArg1 && zArg1[0] ){
    return SQLITE_DENY;
    }
  }
  return SQLITE_OK;
}

/*
** Run the SQL text
*/
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
716
717
718
719
720
721
722

723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739


740
741
742
743
744
745
746
747
748
749
750
751
752
753
754

755



756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773
774
775
776
777
778
779





780
781
782
783
784
785
786







-
+
















-
-
+














-
+
-
-
-










-
+













-
-
-
-
-







    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 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 */
  int nSql;                  /* Bytes of SQL text */
  FuzzCtx cx;                /* Fuzzing context */

  if( nByte<10 ) return 0;
  if( sqlite3_initialize() ) return 0;
  if( sqlite3_memory_used()!=0 ){
    int nAlloc = 0;
    int nNotUsed = 0;
    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
    fprintf(stderr,"memory leak prior to test start:"
                   " %lld bytes in %d allocations\n",
    fprintf(stderr,"Memory leak in mutator: %lld bytes in %d allocations\n",
            sqlite3_memory_used(), nAlloc);
    exit(1);
  }
  memset(&cx, 0, sizeof(cx));
  iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb);
  if( iSql<0 ) return 0;
  nSql = (int)(nByte - iSql);
  if( eVerbosity>=3 ){
    printf(
      "****** %d-byte input, %d-byte database, %d-byte script "
      "******\n", (int)nByte, nDb, nSql);
    fflush(stdout);
  }
  rc = sqlite3_open(0, &cx.db);
  if( rc ){
  if( rc ) return 1;
    sqlite3_free(aDb);
    return 1;
  }
  if( bVdbeDebug ){
    sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
  }

  /* 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.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 */
  if( vdbeOpLimit>0 ){
    sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, vdbeOpLimit);
  }
  if( lengthLimit>0 ){
    sqlite3_limit(cx.db, SQLITE_LIMIT_LENGTH, lengthLimit);
  }
  if( depthLimit>0 ){
    sqlite3_limit(cx.db, SQLITE_LIMIT_EXPR_DEPTH, depthLimit);
  }
  sqlite3_limit(cx.db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 100);
  sqlite3_hard_heap_limit64(heapLimit);

  if( nDb>=20 && aDb[18]==2 && aDb[19]==2 ){
    aDb[18] = aDb[19] = 1;
  }
  rc = sqlite3_deserialize(cx.db, "main", aDb, nDb, nDb,
          SQLITE_DESERIALIZE_RESIZEABLE |
          SQLITE_DESERIALIZE_FREEONCLOSE);
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
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







-
-













-
-

-
+

-







"Options:\n"
"  --cell-size-check    Set the PRAGMA cell_size_check=ON\n"
"  --dbid N             Use only the database where dbid=N\n"
"  --export-db DIR      Write databases to files(s) in DIR. Works with --dbid\n"
"  --export-sql DIR     Write SQL to file(s) in DIR. Also works with --sqlid\n"
"  --help               Show this help text\n"
"  --info               Show information about SOURCE-DB w/o running tests\n"
"  --limit-depth N      Limit expression depth to N.  Default: 500\n"
"  --limit-heap N       Limit heap memory to N.  Default: 100M\n"
"  --limit-mem N        Limit memory used by test SQLite instance to N bytes\n"
"  --limit-vdbe         Panic if any test runs for more than 100,000 cycles\n"
"  --load-sql ARGS...   Load SQL scripts fron files into SOURCE-DB\n"
"  --load-db ARGS...    Load template databases from files into SOURCE_DB\n"
"  --load-dbsql ARGS..  Load dbsqlfuzz outputs into the xsql table\n"
"  -m TEXT              Add a description to the database\n"
"  --native-vfs         Use the native VFS for initially empty database files\n"
"  --native-malloc      Turn off MEMSYS3/5 and Lookaside\n"
"  --oss-fuzz           Enable OSS-FUZZ testing\n"
"  --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"
"  --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 */
  int quietFlag = 0;           /* True if --quiet or -q */
  int verboseFlag = 0;         /* True if --verbose or -v */
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
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







-
-











-
-
+
+









-

-

-



-
+
-
-







  int dbSqlOnly = 0;           /* Only use scripts that are dbsqlfuzz */
  int onlySqlid = -1;          /* --sqlid */
  int onlyDbid = -1;           /* --dbid */
  int nativeFlag = 0;          /* --native-vfs */
  int rebuildFlag = 0;         /* --rebuild */
  int vdbeLimitFlag = 0;       /* --limit-vdbe */
  int infoFlag = 0;            /* --info */
  int nSkip = 0;               /* --skip */
  int bSpinner = 0;            /* True for --spinner */
  int timeoutTest = 0;         /* undocumented --timeout-test flag */
  int runFlags = 0;            /* Flags sent to runSql() */
  char *zMsg = 0;              /* Add this message */
  int nSrcDb = 0;              /* Number of source databases */
  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 iTimeout = 120;          /* Default 120-second timeout */
  int nMem = 0;                /* Memory limit */
  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(SIGALRM, timeoutHandler);
  signal(SIGSEGV, signalHandler);
  signal(SIGABRT, signalHandler);
#endif
  g.zArgv0 = argv[0];
  openFlags4Data = SQLITE_OPEN_READONLY;
  zFailCode = getenv("TEST_FAILURE");
  pDfltVfs = sqlite3_vfs_find(0);
  inmemVfsRegister(1);
  for(i=1; i<argc; i++){
1531
1532
1533
1534
1535
1536
1537
1538
1539


1540
1541
1542
1543
1544
1545



1546
1547
1548

1549
1550
1551
1552
1553
1554

1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1572
1573
1574
1575
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







-
-
+
+
-
-
-
-
-
-
+
+
+
-


+





-
+
-











-
+
-







      if( strcmp(z,"help")==0 ){
        showHelp();
        return 0;
      }else
      if( strcmp(z,"info")==0 ){
        infoFlag = 1;
      }else
      if( strcmp(z,"limit-depth")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
      if( strcmp(z,"limit-mem")==0 ){
#if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5)
        depthLimit = integerValue(argv[++i]);
      }else
      if( strcmp(z,"limit-heap")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        heapLimit = integerValue(argv[++i]);
      }else
        fatalError("the %s option requires -DSQLITE_ENABLE_MEMSYS5 or _MEMSYS3",
                   argv[i]);
#else
      if( strcmp(z,"limit-mem")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        nMem = integerValue(argv[++i]);
#endif
      }else
      if( strcmp(z,"limit-vdbe")==0 ){
        vdbeLimitFlag = 1;
      }else
      if( strcmp(z,"load-sql")==0 ){
        zInsSql = "INSERT INTO xsql(sqltext)"
        zInsSql = "INSERT INTO xsql(sqltext)VALUES(CAST(readfile(?1) AS text))";
                  "VALUES(CAST(readtextfile(?1) AS text))";
        iFirstInsArg = i+1;
        openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
        break;
      }else
      if( strcmp(z,"load-db")==0 ){
        zInsSql = "INSERT INTO db(dbcontent) VALUES(readfile(?1))";
        iFirstInsArg = i+1;
        openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
        break;
      }else
      if( strcmp(z,"load-dbsql")==0 ){
        zInsSql = "INSERT INTO xsql(sqltext)"
        zInsSql = "INSERT INTO xsql(sqltext)VALUES(CAST(readfile(?1) AS text))";
                  "VALUES(CAST(readtextfile(?1) AS text))";
        iFirstInsArg = i+1;
        openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
        dbSqlOnly = 1;
        break;
      }else
      if( strcmp(z,"m")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
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
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







-
-
-
-
-
-
-
-
-
-














-
-
-







      if( strcmp(z,"rebuild")==0 ){
        rebuildFlag = 1;
        openFlags4Data = SQLITE_OPEN_READWRITE;
      }else
      if( strcmp(z,"result-trace")==0 ){
        runFlags |= SQL_OUTPUT;
      }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]);
        iTimeout = integerValue(argv[++i]);
      }else
      if( strcmp(z,"timeout-test")==0 ){
        timeoutTest = 1;
#ifndef __unix__
        fatalError("timeout is not available on non-unix systems");
#endif
      }else
      if( strcmp(z,"vdbe-debug")==0 ){
        bVdbeDebug = 1;
      }else
      if( strcmp(z,"verbose")==0 ){
        quietFlag = 0;
        verboseFlag++;
        eVerbosity++;
        if( verboseFlag>1 ) runFlags |= SQL_TRACE;
      }else
      if( (nV = numberOfVChar(z))>=1 ){
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1503
1504
1505
1506
1507
1508
1509

1510
1511
1512
1513
1514
1515
1516







-







    if( zInsSql ){
      fatalError("cannot import into more than one database");
    }
  }

  /* Process each source database separately */
  for(iSrcDb=0; iSrcDb<nSrcDb; iSrcDb++){
    g.zDbFile = azSrcDb[iSrcDb];
    rc = sqlite3_open_v2(azSrcDb[iSrcDb], &db,
                         openFlags4Data, pDfltVfs->zName);
    if( rc ){
      fatalError("cannot open source database %s - %s",
      azSrcDb[iSrcDb], sqlite3_errmsg(db));
    }

1746
1747
1748
1749
1750
1751
1752
1753





1754
1755

1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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







-
+
+
+
+
+


+








-
-







      while( SQLITE_ROW==sqlite3_step(pStmt) ){
        const char *zName = (const char *)sqlite3_column_text(pStmt,0);
        if( zName==0 ) continue;
        if( strcmp(zName, "oss-fuzz")==0 ){
          ossFuzzThisDb = sqlite3_column_int(pStmt,1);
          if( verboseFlag ) printf("Config: oss-fuzz=%d\n", ossFuzzThisDb);
        }
        if( strcmp(zName, "limit-mem")==0 ){
        if( strcmp(zName, "limit-mem")==0 && !nativeMalloc ){
#if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5)
          fatalError("the limit-mem option requires -DSQLITE_ENABLE_MEMSYS5"
                     " or _MEMSYS3");
#else
          nMemThisDb = sqlite3_column_int(pStmt,1);
          if( verboseFlag ) printf("Config: limit-mem=%d\n", nMemThisDb);
#endif
        }
      }
      sqlite3_finalize(pStmt);
    }

    if( zInsSql ){
      sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
                              readfileFunc, 0, 0);
      sqlite3_create_function(db, "readtextfile", 1, SQLITE_UTF8, 0,
                              readtextfileFunc, 0, 0);
      sqlite3_create_function(db, "isdbsql", 1, SQLITE_UTF8, 0,
                              isDbSqlFunc, 0, 0);
      rc = sqlite3_prepare_v2(db, zInsSql, -1, &pStmt, 0);
      if( rc ) fatalError("cannot prepare statement [%s]: %s",
                          zInsSql, sqlite3_errmsg(db));
      rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
      if( rc ) fatalError("cannot start a transaction");
1877
1878
1879
1880
1881
1882
1883
1884
1885

1886
1887
1888
1889
1890
1891





1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909

1910
1911
1912
1913
1914
1915
1916
1917
1918
1919

1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935

1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956

1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1716
1717
1718
1719
1720
1721
1722


1723






1724
1725
1726
1727
1728





1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740

1741
1742

1743
1744






1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757




1758

1759




1760

1761
1762
1763
1764
1765
1766
1767






1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780




1781
1782
1783
1784
1785
1786
1787







-
-
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-












-
+

-


-
-
-
-
-
-
+












-
-
-
-
+
-

-
-
-
-

-







-
-
-
-
-
-
+












-
-
-
-







    sqlite3_close(db);
    if( sqlite3_memory_used()>0 ){
      fatalError("SQLite has memory in use before the start of testing");
    }

    /* Limit available memory, if requested */
    sqlite3_shutdown();

    if( nMemThisDb>0 && nMem==0 ){
    if( nMemThisDb>0 && !nativeMalloc ){
      if( !nativeMalloc ){
        pHeap = realloc(pHeap, nMemThisDb);
        if( pHeap==0 ){
          fatalError("failed to allocate %d bytes of heap memory", nMem);
        }
        sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMemThisDb, 128);
      pHeap = realloc(pHeap, nMemThisDb);
      if( pHeap==0 ){
        fatalError("failed to allocate %d bytes of heap memory", nMem);
      }
      sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMemThisDb, 128);
      }else{
        sqlite3_hard_heap_limit64((sqlite3_int64)nMemThisDb);
      }
    }else{
      sqlite3_hard_heap_limit64(0);
    }

    /* Disable lookaside with the --native-malloc option */
    if( nativeMalloc ){
      sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
    }
  
    /* Reset the in-memory virtual filesystem */
    formatVfs();
    
    /* Run a test using each SQL script against each database.
    */
    if( !verboseFlag && !quietFlag && !bSpinner ) printf("%s:", zDbName);
    if( !verboseFlag && !quietFlag ) 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);
        }else if( verboseFlag ){
        if( verboseFlag ){
          printf("%s\n", g.zTestName);
          fflush(stdout);
        }else if( !quietFlag ){
          static int prevAmt = -1;
          int idx = pSql->seq;
          int amt = idx*10/(g.nSql);
          if( amt!=prevAmt ){
            printf(" %d%%", amt*10);
            fflush(stdout);
            prevAmt = amt;
          }
        }
        if( nSkip>0 ){
          nSkip--;
        }else{
          runCombinedDbSqlInput(pSql->a, pSql->sz, iTimeout);
        runCombinedDbSqlInput(pSql->a, pSql->sz);
        }
        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";
        sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
                         pSql->id, pDb->id);
        if( bSpinner ){
          int nTotal = g.nDb*g.nSql;
          int idx = pSql->seq*g.nDb + pDb->id - 1;
          printf("\r%s: %d/%d   ", zDbName, idx, nTotal);
          fflush(stdout);
        }else if( verboseFlag ){
        if( verboseFlag ){
          printf("%s\n", g.zTestName);
          fflush(stdout);
        }else if( !quietFlag ){
          static int prevAmt = -1;
          int idx = pSql->seq*g.nDb + pDb->id - 1;
          int amt = idx*10/(g.nDb*g.nSql);
          if( amt!=prevAmt ){
            printf(" %d%%", amt*10);
            fflush(stdout);
            prevAmt = amt;
          }
        }
        if( nSkip>0 ){
          nSkip--;
          continue;
        }
        createVFile("main.db", pDb->sz, pDb->a);
        sqlite3_randomness(0,0);
        if( ossFuzzThisDb ){
#ifndef SQLITE_OSS_FUZZ
          fatalError("--oss-fuzz not supported: recompile"
                     " with -DSQLITE_OSS_FUZZ");
#else
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
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







-
+
-
-






-
-
-
-
-
-













-
-
-
-



















-
-
-
+







            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);
          setAlarm(iTimeout);
          /* 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
          sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1, db);
#endif
          if( bVdbeDebug ){
            sqlite3_exec(db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
          }
          do{
            runSql(db, (char*)pSql->a, runFlags);
          }while( timeoutTest );
          setAlarm(0);
          sqlite3_exec(db, "PRAGMA temp_store_directory=''", 0, 0, 0);
          sqlite3_close(db);
        }
        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 ){
          if( zFailCode[0]=='5' && zFailCode[1]==0 ){
            fatalError("simulated failure");
          }else if( zFailCode[0]!=0 ){
            /* If TEST_FAILURE is something other than 5, just exit the test
            ** early */
            printf("\nExit early due to TEST_FAILURE being set\n");
            iSrcDb = nSrcDb-1;
            goto sourcedb_cleanup;
          }
        }
      }
    }
    if( bSpinner ){
      printf("\n");
    }else if( !quietFlag && !verboseFlag ){
    if( !quietFlag && !verboseFlag ){
      printf(" 100%% - %d tests\n", g.nDb*g.nSql);
    }
  
    /* Clean up at the end of processing a single source database
    */
  sourcedb_cleanup:
    blobListFree(g.pFirstSql);

Changes to test/fuzzdata1.db.

cannot compute difference between binary files

Changes to test/fuzzdata7.db.

cannot compute difference between binary files

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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}}
}

#-------------------------------------------------------------------------
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

Deleted test/gencol1.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589













































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-10-31
#
# 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 generated columns.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# ticket 830277d9db6c3ba1 on 2019-10-31
do_execsql_test gencol1-100 {
  CREATE TABLE t0(c0 AS(TYPEOF(c1)), c1);
  INSERT INTO t0(c1) VALUES(0);
  CREATE TABLE t1(x AS (typeof(y)), y);
  INSERT INTO t1 SELECT * FROM t0;
  SELECT * FROM t1;
} {integer 0}

foreach {tn schema} { 
1 {
   CREATE TABLE t1(
     a INT,
     b TEXT,
     c ANY,
     w INT GENERATED ALWAYS AS (a*10),
     x TEXT AS (typeof(c)),
     y TEXT AS (substr(b,a,a+2))
   );
  }
2 {
   CREATE TABLE t1(
     w INT GENERATED ALWAYS AS (a*10),
     x TEXT AS (typeof(c)),
     y TEXT AS (substr(b,a,a+2)),
     a INT,
     b TEXT,
     c ANY
   );
  }
3 {
   CREATE TABLE t1(
     w INT GENERATED ALWAYS AS (a*10),
     a INT,
     x TEXT AS (typeof(c)) STORED,
     b TEXT,
     y TEXT AS (substr(b,a,a+2)),
     c ANY
   );
  }
4 {
   CREATE TABLE t1(
     a INTEGER PRIMARY KEY,
     w INT GENERATED ALWAYS AS (a*10),
     b TEXT,
     x TEXT AS (typeof(c)),
     y TEXT AS (substr(b,a,a+2)) STORED,
     c ANY
   );
  }
5 {
   CREATE TABLE t1(
     w INT GENERATED ALWAYS AS (a*10),
     a INT,
     x TEXT AS (typeof(c)),
     b TEXT,
     y TEXT AS (substr(b,a,a+2)) STORED,
     c ANY,
     PRIMARY KEY(a,b)
   ) WITHOUT ROWID;
  }
6 {
   CREATE TABLE t1(
     w INT GENERATED ALWAYS AS (m*5),
     m INT AS (a*2) STORED,
     a INT,
     x TEXT AS (typeof(c)),
     b TEXT,
     y TEXT AS (substr(b,m/2,m/2+2)) STORED,
     c ANY,
     PRIMARY KEY(a,b)
   );
  }
7 {
   CREATE TABLE t1(
     w INT GENERATED ALWAYS AS (m*5),
     m INT AS (a*2) NOT NULL,
     a INT,
     x TEXT AS (typeof(c)) CHECK (x<>'blank'),
     b TEXT,
     y TEXT AS (substr(b,m/2,m/2+2)) STORED,
     c ANY,
     PRIMARY KEY(b,a)
   ) WITHOUT ROWID;
  }
} {
  catch {db close}
  sqlite3 db :memory:
  db eval $schema
  do_execsql_test gencol1-2.$tn.100 {
    INSERT INTO t1(a,b,c) VALUES(1,'abcdef',5.5),(3,'cantaloupe',NULL);
    SELECT w, x, y, '|' FROM t1 ORDER BY a;
  } {10 real abc | 30 null ntalo |}
  do_execsql_test gencol1-2.$tn.101 {
    SELECT w, x, y, '|' FROM t1 ORDER BY w;
  } {10 real abc | 30 null ntalo |}
  do_execsql_test gencol1-2.$tn.102 {
    SELECT a FROM t1 WHERE w=30;
  } {3}
  do_execsql_test gencol1-2.$tn.103 {
    SELECT a FROM t1 WHERE x='real';
  } {1}
  do_execsql_test gencol1-2.$tn.104 {
    SELECT a FROM t1 WHERE y LIKE '%tal%' OR x='real' ORDER BY b;
  } {1 3}
  do_execsql_test gencol1-2.$tn.110 {
    CREATE INDEX t1w ON t1(w);
    SELECT a FROM t1 WHERE w=10;
  } {1}
  do_execsql_test gencol1-2.$tn.120 {
    CREATE INDEX t1x ON t1(x) WHERE w BETWEEN 20 AND 40;
    SELECT a FROM t1 WHERE x='null' AND w BETWEEN 20 AND 40;
  } {3}
  do_execsql_test gencol1-2.$tn.121 {
    SELECT a FROM t1 WHERE x='real';
  } {1}
  do_execsql_test gencol1-2.$tn.130 {
    VACUUM;
    PRAGMA integrity_check;
  } {ok}
  do_execsql_test gencol1-2.$tn.140 {
    UPDATE t1 SET a=a+100 WHERE w<20;
    SELECT a, w, '|' FROM t1 ORDER BY w;
  } {3 30 | 101 1010 |}
  do_execsql_test gencol1-2.$tn.150 {
    INSERT INTO t1 VALUES(4,'jambalaya','Chef John'),(15,87719874135,0);
    SELECT w, x, y, '|' FROM t1 ORDER BY w;
  } {30 null ntalo | 40 text balaya | 150 integer {} | 1010 real {} |}
}

# 2019-10-31 ticket b9befa4b83a660cc
db close
sqlite3 db :memory:
do_execsql_test gencol1-3.100 {
  PRAGMA foreign_keys = true;
  CREATE TABLE t0(c0 PRIMARY KEY, c1, c2 AS (c0+c1-c3) REFERENCES t0, c3);
  INSERT INTO t0 VALUES (0, 0, 0), (11, 5, 5);
  UPDATE t0 SET c1 = c0, c3 = c0;
  SELECT *, '|' FROM t0 ORDER BY +c0;
} {0 0 0 0 | 11 11 11 11 |}
do_catchsql_test gencol1-3.110 {
  UPDATE t0 SET c1 = c0, c3 = c0+1;
} {1 {FOREIGN KEY constraint failed}}

# 2019-11-01 ticket c28a01da72f8957c
db close
sqlite3 db :memory:
do_execsql_test gencol1-4.100 {
  CREATE TABLE t0 (
    c0,
    c1 a UNIQUE AS (1),
    c2,
    c3 REFERENCES t0(c1)
  );
  PRAGMA foreign_keys = true;
  INSERT INTO t0(c0,c2,c3) VALUES(0,0,1);
} {}
do_catchsql_test gencol1-4.110 {
  REPLACE INTO t0(c0,c2,c3) VALUES(0,0,0),(0,0,0);
} {1 {FOREIGN KEY constraint failed}}

# 2019-11-01 Problem found while adding new foreign key test cases in TH3.
db close
sqlite3 db :memory:
do_execsql_test gencol1-5.100 {
  PRAGMA foreign_keys=ON;
  CREATE TABLE t1(
    gcb AS (b*1),
    a INTEGER PRIMARY KEY,
    gcc AS (c+0),
    b UNIQUE,
    gca AS (1*a+0),
    c UNIQUE
  ) WITHOUT ROWID;
  INSERT INTO t1 VALUES(1,2,3);
  INSERT INTO t1 VALUES(4,5,6);
  INSERT INTO t1 VALUES(7,8,9);
  CREATE TABLE t1a(
    gcx AS (x+0) REFERENCES t1(a) ON DELETE CASCADE,
    id,
    x,
    gcid AS (1*id)
  );
  INSERT INTO t1a VALUES(1, 1);
  INSERT INTO t1a VALUES(2, 4);
  INSERT INTO t1a VALUES(3, 7);
  DELETE FROM t1 WHERE b=5;
  SELECT id,x,'|' FROM t1a ORDER BY id;
} {1 1 | 3 7 |}  

do_catchsql_test gencol1-6.10 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 NOT NULL AS(c1), c1);
  REPLACE INTO t0(c1) VALUES(NULL);
} {1 {NOT NULL constraint failed: t0.c0}}

# 2019-11-06 ticket https://www.sqlite.org/src/info/2399f5986134f79c
# 2019-12-27 ticket https://www.sqlite.org/src/info/5fbc159eeb092130
# 2019-12-27 ticket https://www.sqlite.org/src/info/37823501c68a09f9
#
# All of the above tickets deal with NOT NULL ON CONFLICT REPLACE
# constraints on tables that have generated columns.
#
reset_db
do_execsql_test gencol1-7.10 {
  CREATE TABLE t0 (c0 GENERATED ALWAYS AS (1), c1 UNIQUE, c2 UNIQUE);
  INSERT INTO t0(c1) VALUES (1);
  SELECT quote(0 = t0.c2 OR t0.c1 BETWEEN t0.c2 AND 1) FROM t0;
} {NULL}
do_execsql_test gencol1-7.11 {
  DROP TABLE t0;
  CREATE TABLE t0(c0 NOT NULL DEFAULT 'xyz', c1 AS(c0) NOT NULL);
  REPLACE INTO t0(c0) VALUES(NULL);
  SELECT * FROM t0;
} {xyz xyz}
do_execsql_test gencol1-7.12 {
  DROP TABLE t0;
  CREATE TABLE t0(c0 NOT NULL DEFAULT 'xyz', c1 AS(c0) STORED NOT NULL);
  REPLACE INTO t0(c0) VALUES(NULL);
  SELECT * FROM t0;
} {xyz xyz}
do_execsql_test gencol1-7.20 {
  CREATE TABLE t1(
   a NOT NULL DEFAULT 'aaa',
   b AS(c) NOT NULL,
   c NOT NULL DEFAULT 'ccc');
  REPLACE INTO t1(a,c) VALUES(NULL,NULL);
  SELECT * FROM t1;
} {aaa ccc ccc}
do_execsql_test gencol1-7.21 {
  DROP TABLE t1;
  CREATE TABLE t1(
   a NOT NULL DEFAULT 'aaa',
   b AS(c) STORED NOT NULL,
   c NOT NULL DEFAULT 'ccc');
  REPLACE INTO t1(a,c) VALUES(NULL,NULL);
  SELECT * FROM t1;
} {aaa ccc ccc}
do_execsql_test gencol1-7.30 {
  CREATE TABLE t2(
   a NOT NULL DEFAULT 'aaa',
   b AS(a) NOT NULL,
   c NOT NULL DEFAULT 'ccc');
  REPLACE INTO t2(a,c) VALUES(NULL,NULL);
  SELECT * FROM t2;
} {aaa aaa ccc}
do_execsql_test gencol1-7.31 {
  DROP TABLE t2;
  CREATE TABLE t2(
   a NOT NULL DEFAULT 'aaa',
   b AS(a) STORED NOT NULL,
   c NOT NULL DEFAULT 'ccc');
  REPLACE INTO t2(a,c) VALUES(NULL,NULL);
  SELECT * FROM t2;
} {aaa aaa ccc}
do_execsql_test gencol1-7.40 {
  CREATE TABLE t3(a NOT NULL DEFAULT 123, b AS(a) UNIQUE);
  REPLACE INTO t3 VALUES(NULL);
  SELECT * FROM t3;
} {123 123}
do_execsql_test gencol1-7.41 {
  SELECT * FROM t3 WHERE b=123;
} {123 123}
do_execsql_test gencol1-7.50 {
  CREATE TABLE t4(a NOT NULL DEFAULT 123, b AS(a*10+4) STORED UNIQUE);
  REPLACE INTO t4 VALUES(NULL);
  SELECT * FROM t4;
} {123 1234}
do_execsql_test gencol1-7.51 {
  SELECT * FROM t4 WHERE b=1234;
} {123 1234}

# 2019-11-06 ticket 4fc08501f4e56692
do_execsql_test gencol1-8.10 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(
    c0 AS (('a', 9) < ('b', c1)),
    c1 AS (1),
    c2 CHECK (1 = c1)
  );
  INSERT INTO t0 VALUES (0),(99);
  SELECT * FROM t0;
} {1 1 0 1 1 99}
do_catchsql_test gencol1-8.20 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(
    c0,
    c1 AS(c0 + c2),
    c2 AS(c1) CHECK(c2)
  );
  UPDATE t0 SET c0 = NULL;
} {1 {generated column loop on "c2"}}

# 2019-11-21 Problems in the new generated column logic
# reported by Yongheng Chen and Rui Zhong
reset_db
do_execsql_test gencol1-9.10 {
  PRAGMA foreign_keys=OFF;
  CREATE TABLE t1(aa , bb AS (17) UNIQUE);
  INSERT INTO t1 VALUES(17);
  CREATE TABLE t2(cc);
  INSERT INTO t2 VALUES(41);
  SELECT * FROM t2 JOIN t1 WHERE t1.bb=t1.aa AND t1.bb=17;
} {41 17 17}
do_execsql_test gencol1-9.20 {
  CREATE TABLE t3(aa INT PRIMARY KEY, bb UNIQUE AS(aa));
  INSERT INTO t3 VALUES(1);
  SELECT 100, * FROM t3;
  DELETE FROM t3 WHERE (SELECT bb FROM t3);
  SELECT 200, * FROM t3;
} {100 1 1}

# 2019-12-04 Generated column in a CREATE TABLE IF NOT EXISTS that
# does already exist.
#
sqlite3 db :memory:
do_execsql_test gencol1-10.10 {
  CREATE TABLE t1(aa,bb);
  CREATE TABLE IF NOT EXISTS t1(aa, bb AS (aa+1));
  PRAGMA integrity_check;
} {ok}

# 2019-12-06 Found by mrigger
#
sqlite3 db :memory:
do_execsql_test gencol1-11.10 {
  PRAGMA foreign_keys = true;
  CREATE TABLE t0(
    c0,
    c1 INTEGER PRIMARY KEY,
    c2 BLOB UNIQUE DEFAULT x'00',
    c3 BLOB GENERATED ALWAYS AS (1), 
    FOREIGN KEY(c1) REFERENCES t0(c2)
  );
}
do_catchsql_test gencol1-11.20 {
  INSERT OR REPLACE INTO t0(c0, c1) VALUES (2, 1), (1, 0)
} {1 {FOREIGN KEY constraint failed}}
do_execsql_test gencol1-11.30 {
  DROP TABLE t0;
  CREATE TABLE t0(
    c0,
    c1 INTEGER PRIMARY KEY,
    c3 BLOB GENERATED ALWAYS AS (1), 
    c2 BLOB UNIQUE DEFAULT x'00',
    FOREIGN KEY(c1) REFERENCES t0(c2)
  );
}
do_catchsql_test gencol1-11.40 {
  INSERT OR REPLACE INTO t0(c0, c1) VALUES (2, 1), (1, 0)
} {1 {FOREIGN KEY constraint failed}}
do_execsql_test gencol1-11.50 {
  DROP TABLE t0;
  CREATE TABLE t0(
    c0,
    c3 BLOB GENERATED ALWAYS AS (1), 
    c1 INTEGER PRIMARY KEY,
    c2 BLOB UNIQUE DEFAULT x'00',
    FOREIGN KEY(c1) REFERENCES t0(c2)
  );
}
do_catchsql_test gencol1-11.60 {
  INSERT OR REPLACE INTO t0(c0, c1) VALUES (2, 1), (1, 0)
} {1 {FOREIGN KEY constraint failed}}
do_execsql_test gencol1-11.70 {
  DROP TABLE t0;
  CREATE TABLE t0(
    c3 BLOB GENERATED ALWAYS AS (1), 
    c0,
    c1 INTEGER PRIMARY KEY,
    c2 BLOB UNIQUE DEFAULT x'00',
    FOREIGN KEY(c1) REFERENCES t0(c2)
  );
}
do_catchsql_test gencol1-11.80 {
  INSERT OR REPLACE INTO t0(c0, c1) VALUES (2, 1), (1, 0)
} {1 {FOREIGN KEY constraint failed}}

# 2019-12-09 ticket bd8c280671ba44a7
# With generated columns, the sqlite3ExprGetColumnOfTable() routine might
# generate a code sequence that does not end with OP_Column.  So check to
# make sure that the last instruction generated is an OP_column prior to
# applying the OPFLAG_TYPEOFARG optimization to NOT NULL checks in the
# PRAGMA integrity_check code.
#
sqlite3 db :memory:
do_execsql_test gencol1-12.10 {
  CREATE TABLE t0 (c0, c1 NOT NULL AS (c0==0));
  INSERT INTO t0(c0) VALUES (0);
  PRAGMA integrity_check;
} {ok}

# 2019-12-09 bug report from Yongheng Chen
# Ensure that the SrcList_item.colUsed field is set correctly when a
# generated column appears in the USING clause of a join.
#
do_execsql_test gencol1-13.10 {
  CREATE TABLE t1(x, y AS(x+1));
  INSERT INTO t1 VALUES(10);
  SELECT y FROM t1 JOIN t1 USING (y,y);
} {11}
do_execsql_test gencol1-13.11 {
  SELECT 123 FROM t1 JOIN t1 USING (x);
} {123}
do_execsql_test gencol1-13.11 {
  SELECT 456 FROM t1 JOIN t1 USING (x,x);
} {456}
do_execsql_test gencol1-13.20 {
  CREATE INDEX t1y ON t1(y);
  SELECT y FROM t1 JOIN t1 USING (y,y);
} {11}
do_execsql_test gencol1-13.21 {
  CREATE INDEX t1x ON t1(x);
  SELECT 123 FROM t1 JOIN t1 USING (x);
} {123}
do_execsql_test gencol1-13.22 {
  SELECT 456 FROM t1 JOIN t1 USING (x,x);
} {456}

# 2019-12-14 ticket b439bfcfb7deedc6
#
sqlite3 db :memory:
do_execsql_test gencol1-14.10 {
  CREATE TABLE t0(c0 AS(1 >= 1), c1 UNIQUE AS(TYPEOF(c0)), c2);
  INSERT INTO t0 VALUES(0);
  REINDEX;
  SELECT * FROM t0;
} {1 integer 0}
do_catchsql_test gencol1-14.10 {
  INSERT INTO t0 VALUES(2);
} {1 {UNIQUE constraint failed: t0.c1}}

# 2019-12-14 gramfuzz1 find
# The schema is malformed in that it has a subquery on a generated
# column expression.  This will be loaded if writable_schema=ON.  SQLite
# must not use such an expression during code generation as the code generator
# will add bits of content to the expression tree that might be allocated
# from lookaside.  But the schema is not tied to a particular database
# connection, so the use of lookaside memory is prohibited.  The fix
# is to change the generated column expression to NULL before adding it
# to the schema.
#
reset_db
do_test gencol1-15.10 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename c27.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 02   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04   ................
|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
|     96: 00 2e 3f d8 0d 00 00 00 01 0f ba 00 0f ba 00 00   ..?.............
|   4016: 00 00 00 00 00 00 00 00 00 00 44 01 06 17 11 11   ..........D.....
|   4032: 01 75 74 61 62 6c 65 74 31 74 31 02 43 52 45 41   .utablet1t1.CREA
|   4048: 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 49 4e   TE TABLE t1(a IN
|   4064: 54 2c 20 62 20 41 53 28 28 56 41 4c 55 45 53 28   T, b AS((VALUES(
|   4080: 31 29 29 20 49 53 20 75 6e 6b 6e 6f 77 6e 29 29   1)) IS unknown))
| page 2 offset 4096
|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
| end c27.db
}]} {}
do_execsql_test gencol1-15.20 {
  PRAGMA writable_schema=ON;
  REPLACE INTO t1 VALUES(9);
  SELECT a, quote(b) FROM t1
} {9 NULL}

# 2019-12-16 ticket 3b84b42943644d6f
# When a table is the right table of a LEFT JOIN and the ON clause is
# false, make sure any generated columns evaluate to NULL.
reset_db
do_execsql_test gencol1-16.10 {
  CREATE TABLE t0(c0);
  CREATE TABLE t1(c1, c2 AS(1));
  INSERT INTO t0 VALUES(0);
  SELECT c0, c1, c2 FROM t0 LEFT JOIN t1;
} {0 {} {}}
do_execsql_test gencol1-16.20 {
  DROP TABLE t1;
  CREATE TABLE t1(c1, c2 AS (c1 ISNULL));
  SELECT c0, c1, c2 FROM t0 LEFT JOIN t1;
} {0 {} {}}
do_execsql_test gencol1-16.30 {
  INSERT INTO t1(c1) VALUES(1),(NULL);
  SELECT * FROM t1;
} {1 0 {} 1}
do_execsql_test gencol1-16.40 {
  SELECT c0, c1, c2 FROM t0 LEFT JOIN t1 ON c0=c1;
} {0 {} {}}

# 2019-12-20 ticket e0a8120553f4b082
# Generated columns with REAL affinity need to have an OP_RealAffinity
# opcode applied, even when the column value is extracted from an index.
#
reset_db
do_execsql_test gencol1-17.10 {
  CREATE TABLE t0(c0 REAL AS(1) UNIQUE, c1 INT);
  INSERT INTO t0 VALUES('');
  SELECT quote(c0), quote(c1) from t0;
} {1.0 ''}
do_execsql_test gencol1-17.20 {
  SELECT *, (1 BETWEEN CAST(t0.c0 AS TEXT) AND t0.c0) FROM t0;
} {1.0 {} 0}
do_execsql_test gencol1-17.30 {
  SELECT * FROM t0 WHERE (1 BETWEEN CAST(t0.c0 AS TEXT) AND t0.c0);
} {}
do_execsql_test gencol1-17.40 {
  CREATE TABLE t1(a TEXT AS(b) COLLATE nocase, b TEXT, c INT, d DEFAULT 1);
  INSERT INTO t1(b,c) VALUES('abc',11),('DEF',22),('ghi',33);
  SELECT a FROM t1 WHERE b='DEF' AND a='def';
} {DEF}
do_execsql_test gencol1-17.50 {
  CREATE INDEX t1bca ON t1(b,c,a);
  SELECT a FROM t1 WHERE b='DEF' AND a='def';
} {DEF}

# 2019-12-26 ticket ec8abb025e78f40c
# An index on a virtual column with a constant value (why would anybody
# ever do such a thing?) can cause problems for a one-pass DELETE.
#
reset_db
do_execsql_test gencol1-18.10 {
  CREATE TABLE t0(c0 UNIQUE AS(0), c1, c2);
  INSERT INTO t0(c1) VALUES(0);
  SELECT * FROM t0;
} {0 0 {}}
do_execsql_test gencol1-18.20 {
  UPDATE t0 SET c1=0, c2=0 WHERE c0>=0;
  SELECT * FROM t0;
} {0 0 0}

# 2019-12-27 ticket de4b04149b9fdeae
#
reset_db
do_catchsql_test gencol1-19.10 {
  CREATE TABLE t0(
    c0 INT AS(2) UNIQUE,
    c1 TEXT UNIQUE,
    FOREIGN KEY(c0) REFERENCES t0(c1)
  );
  INSERT INTO t0(c1) VALUES(0.16334143182538696), (0);
} {1 {UNIQUE constraint failed: t0.c0}}

# 2020-06-29 forum bug report.
# https://sqlite.org/forum/forumpost/73b9a8ccfb
#
do_execsql_test gencol1-20.1 {
  CREATE TEMPORARY TABLE tab (
    prim DATE PRIMARY KEY,
    a INTEGER,
    comp INTEGER AS (a),
    b INTEGER,
    x INTEGER
  );
  -- Add some data
  INSERT INTO tab (prim, a, b) VALUES ('2001-01-01', 0, 0);
  -- Check that each column is 0 like I expect
  SELECT * FROM tab;
} {2001-01-01 0 0 0 {}}
do_execsql_test gencol1-20.2 {
  -- Do an UPSERT on the b column
  INSERT INTO tab (prim, b)
  VALUES ('2001-01-01',5)
      ON CONFLICT(prim) DO UPDATE SET  b=excluded.b;
  -- Now b is NULL rather than 5
  SELECT * FROM tab;
} {2001-01-01 0 0 5 {}}


finish_test

Changes to test/having.test.

61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
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"
  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
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
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}

#-------------------------------------------------------------------------
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.

138
139
140
141
142
143
144
145
146



147
148
149
150
151
152
153
138
139
140
141
142
143
144


145
146
147
148
149
150
151
152
153
154







-
-
+
+
+







  catchsql {
    DROP TABLE t1;
  }
  unset -nocomplain ::update_hook
  set ::update_hook {}
  db update_hook [list lappend ::update_hook]
  #
  # EVIDENCE-OF: R-24531-54682 The update hook is not invoked when
  # internal system tables are modified (i.e. sqlite_sequence).
  # EVIDENCE-OF: R-52223-27275 The update hook is not invoked when
  # internal system tables are modified (i.e. sqlite_master and
  # sqlite_sequence).
  #
  execsql {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
    CREATE TABLE t1w(a INT PRIMARY KEY, b) WITHOUT ROWID;
  }
  set ::update_hook
} {}
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
953
954
955
956
957
958
959




960






















































961








-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
    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/icu.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
166
167
142
143
144
145
146
147
148


















149







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  do_catchsql_test icu-5.6 {SELECT 'abc' REGEXP, 1} {1 {near ",": syntax error}}
 
  do_malloc_test icu-6.10 -sqlbody {
    SELECT upper(char(0xfb04,0xdf,0xfb04,0xe8,0xfb04));
  }
}

# 2020-03-19
# The ESCAPE clause on LIKE takes precedence over wildcards
#
do_execsql_test idu-6.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT);
  INSERT INTO t1 VALUES
    (1,'abcde'),
    (2,'abc_'),
    (3,'abc__'),
    (4,'abc%'),
    (5,'abc%%');
  SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%';
} {4}
do_execsql_test icu-6.1 {
  SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_';
} {2}

finish_test

Changes to test/ieee754.test.

19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
19
20
21
22
23
24
25


26
27
28
29
30
31
32
33
34







-
-
+
+








foreach {id float rep} {
   1       1.0                            1,0
   2       2.0                            2,0
   3       0.5                            1,-1
   4       1.5                            3,-1
   5       0.0                            0,-1075
   6       4.9406564584124654e-324        1,-1074
   7       2.2250738585072009e-308        4503599627370495,-1074
   6       4.9406564584124654e-324        4503599627370497,-1075
   7       2.2250738585072009e-308        9007199254740991,-1075
   8       2.2250738585072014e-308        1,-1022
} {
  do_test ieee754-100-$id-1 {
    db eval "SELECT ieee754($float);"
  } "ieee754($rep)"
  do_test ieee754-100-$id-2 {
    db eval "SELECT ieee754($rep)==$float;"

Changes to test/in.test.

328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342







-
+







    SELECT * FROM t5;
  }
} {111}
do_test in-10.2 {
  catchsql {
    INSERT INTO t5 VALUES(4);
  }
} {1 {CHECK constraint failed: a IN (111,222,333)}}
} {1 {CHECK constraint failed: t5}}

# Ticket #1821
#
# Type affinity applied to the right-hand side of an IN operator.
#
do_test in-11.1 {
  execsql {
730
731
732
733
734
735
736
737
738
739

740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
730
731
732
733
734
735
736



737












738















































739







-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


do_execsql_test in-16.2 {
  SELECT * FROM x1 
  WHERE a IN (SELECT a FROM x1 WHERE (a%7)==0) 
  ORDER BY a DESC, b;
} {}

# 2019-06-11
# https://www.sqlite.org/src/info/57353f8243c637c0
#

do_execsql_test in-17.1 {
  SELECT 1 IN ('1');
} 0
do_execsql_test in-17.2 {
  SELECT 1 IN ('1' COLLATE nocase);
} 0
do_execsql_test in-17.3 {
  SELECT 1 IN (CAST('1' AS text));
} 0
do_execsql_test in-17.4 {
  SELECT 1 IN (CAST('1' AS text) COLLATE nocase);
} 0

# 2019-08-27 ticket https://sqlite.org/src/info/dbaf8a6820be1ece
# 
do_execsql_test in-18.1 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 INT UNIQUE);
  INSERT INTO t0(c0) VALUES (1);
  SELECT * FROM t0 WHERE '1' IN (t0.c0);
} {}

# 2019-09-02 ticket https://www.sqlite.org/src/info/2841e99d104c6436
# For the IN_INDEX_NOOP optimization, apply REAL affinity to the LHS
# values prior to comparison if the RHS has REAL affinity.
#
# Also ticket https://sqlite.org/src/info/29f635e0af71234b
#
do_execsql_test in-19.10 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 REAL UNIQUE);
  INSERT INTO t0(c0) VALUES(2.0625E00);
  SELECT 1 FROM t0 WHERE c0 IN ('2.0625');
} {1}
do_execsql_test in-19.20 {
  SELECT c0 IN ('2.0625') FROM t0;
} {1}
do_execsql_test in-19.21 {
  SELECT c0 = ('2.0625') FROM t0;
} {1}
do_execsql_test in-19.22 {
  SELECT c0 = ('0.20625e+01') FROM t0;
} {1}
do_execsql_test in-19.30 {
  SELECT c0 IN ('2.0625',2,3) FROM t0;
} {1}
do_execsql_test in-19.40 {
  DROP TABLE t0;
  CREATE TABLE t0(c0 TEXT, c1 REAL, c2, PRIMARY KEY(c2, c0, c1));
  CREATE INDEX i0 ON t0(c1 IN (c0));
  INSERT INTO t0(c0, c2) VALUES (0, NULL) ON CONFLICT(c2, c1, c0) DO NOTHING;
  PRAGMA integrity_check;
} {ok}

# Ticket f3ff1472887
#
do_execsql_test in-20.1 {
  SELECT (1 IN (2 IS TRUE));
} {1}

finish_test

Changes to test/in4.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22







-







#
#***********************************************************************
#
# $Id: in4.test,v 1.4 2009/06/05 17:09:12 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix in4

do_test in4-1.1 {
  execsql {
    CREATE TABLE t1(a, b);
    CREATE INDEX i1 ON t1(a);
  }
} {}
223
224
225
226
227
228
229
230
231
232
233
234
235
236




237
238
239
240
241
242
243
222
223
224
225
226
227
228







229
230
231
232
233
234
235
236
237
238
239







-
-
-
-
-
-
-
+
+
+
+







do_execsql_test in4-3.42 {
  EXPLAIN
  SELECT * FROM t3 WHERE x IN (10,11);
} {/OpenEphemeral/}
do_execsql_test in4-3.43 {
  SELECT * FROM t3 WHERE x IN (10);
} {10 10 10}

# This test would verify that the "X IN (Y)" -> "X==Y" optimization
# was working.  But we have now taken that optimization out.
#do_execsql_test in4-3.44 {
#  EXPLAIN
#  SELECT * FROM t3 WHERE x IN (10);
#} {~/OpenEphemeral/}
do_execsql_test in4-3.44 {
  EXPLAIN
  SELECT * FROM t3 WHERE x IN (10);
} {~/OpenEphemeral/}
do_execsql_test in4-3.45 {
  SELECT * FROM t3 WHERE x NOT IN (10,11,99999);
} {1 1 1}
do_execsql_test in4-3.46 {
  EXPLAIN
  SELECT * FROM t3 WHERE x NOT IN (10,11,99999);
} {/OpenEphemeral/}
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
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336
337








338














































339







-
+








-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  INSERT INTO t6b VALUES(4,44),(5,55),(6,66);

  SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c);
} {3 4 4 44}
do_execsql_test in4-6.1-eqp {
  EXPLAIN QUERY PLAN
  SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c);
} {~/SCAN TABLE t6a/}
} {~/SCAN/}
do_execsql_test in4-6.2 {
  SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b);
} {3 4 4 44}
do_execsql_test in4-6.2-eqp {
  EXPLAIN QUERY PLAN
  SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b);
} {~/SCAN/}

reset_db
do_execsql_test 7.0 {
  CREATE TABLE t1(a, b, c);
  CREATE TABLE t2(d, e);
  CREATE INDEX t1bc ON t1(c, b);
  INSERT INTO t2(e) VALUES(1);
  INSERT INTO t1 VALUES(NULL, NULL, NULL);
}


do_execsql_test 7.1 {
  SELECT * FROM t2 LEFT JOIN t1 ON c = d AND b IN (10,10,10);
} {{} 1 {} {} {}}

ifcapable rtree {
  reset_db
  do_execsql_test 7.2 {
    CREATE VIRTUAL TABLE t1 USING rtree(a, b, c);
    CREATE TABLE t2(d INTEGER, e INT);
    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/in5.test.

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
244
245
246
247
248
249
250

















251
252







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  CREATE TABLE t9(a INTEGER PRIMARY KEY);
  INSERT INTO t9 VALUES (44), (45);
}
do_execsql_test 9.1 {
  SELECT * FROM t9 WHERE a IN (44, 45, 44, 45)
} {44 45}

#-------------------------------------------------------------------------
# Test that ticket c7a117190 is fixed.
#
reset_db
do_execsql_test 9.0 {
  CREATE TABLE t0(c0);
  CREATE VIEW v0(c0) AS SELECT LOWER(CAST('1e500' AS TEXT)) FROM t0;
  INSERT INTO t0(c0) VALUES (NULL);
}

do_execsql_test 9.1 {
  SELECT lower('1e500') FROM t0 WHERE rowid NOT IN (0, 0, lower('1e500'));
} {1e500}

do_execsql_test 9.2 {
  SELECT lower('1e500') FROM t0 WHERE rowid != lower('1e500');
} {1e500}

finish_test

Changes to test/in6.test.

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
73
74
75
76
77
78
79




















80







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  SELECT d, f FROM t1 LEFT JOIN t2 ON (e=d)
  WHERE a=100
    AND b IN (200,201,202,204)
    AND c IN (300,302,301,305)
  ORDER BY +d;
} {1 {} 2 {} 3 {} 4 {} 5 {} 8 {} 9 {}}

# 2020-03-16 ticket 82b588d342d515d1
# Ensure that the IN-early-out optimization works with LEFT JOINs
#
reset_db
do_execsql_test in6-3.100 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(0);
  CREATE TABLE t2(b, c, d);
  INSERT INTO t2(b,c,d) VALUES(4,5,3),(4,5,4),(4,5,8);
  CREATE INDEX t2bcd ON t2(b, c, d);
  SELECT * FROM t1 LEFT JOIN t2 ON b=NULL AND c=5 AND d IN (2,3,4);
} {0 {} {} {}}
do_execsql_test in6-3.110 {
  CREATE TABLE v0(v1);
  CREATE TABLE v3(v5, v4);
  INSERT INTO v0 VALUES(0);
  CREATE INDEX v9 ON v3(v4, v4, v5);
  SELECT quote(v5) FROM v0 LEFT JOIN v3 ON v4 = NULL AND v5 IN(0);
} {NULL}

finish_test

Changes to test/index.test.

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
734
735
736
737
738
739
740










741

















742
743







-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


     CREATE TEMP TABLE t6(x);
     INSERT INTO temp.t6 values(1),(5),(9);
     CREATE INDEX temp.i21 ON t6(x);
     SELECT x FROM t6 ORDER BY x DESC;
  }
} {0 {9 5 1}}

# 2019-05-01 ticket https://www.sqlite.org/src/info/3be1295b264be2fa
do_execsql_test index-22.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a, b TEXT);
  CREATE UNIQUE INDEX IF NOT EXISTS x1 ON t1(b==0);
  CREATE INDEX IF NOT EXISTS x2 ON t1(a || 0) WHERE b;
  INSERT INTO t1(a,b) VALUES('a',1),('a',0);
  SELECT a, b, '|' FROM t1;
} {a 1 | a 0 |}

   
# 2019-05-10 ticket https://www.sqlite.org/src/info/ae0f637bddc5290b
do_execsql_test index-23.0 {
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, b REAL);
  CREATE UNIQUE INDEX t1x1 ON t1(a GLOB b);
  INSERT INTO t1(a,b) VALUES('0.0','1'),('1.0','1');
  SELECT * FROM t1;
  REINDEX;
} {0.0 1.0 1.0 1.0}
do_execsql_test index-23.1 {
  DROP TABLE t1;
  CREATE TABLE t1(a REAL);
  CREATE UNIQUE INDEX index_0 ON t1(TYPEOF(a));
  INSERT OR IGNORE INTO t1(a) VALUES (0.1),(FALSE);
  SELECT * FROM t1;
  REINDEX;
} {0.1}

finish_test

Changes to test/index6.test.

155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169







-
+







} {500}
do_test index6-2.2 {
  execsql {
    EXPLAIN QUERY PLAN
    SELECT * FROM t2 WHERE a=5;
  }
} {/.* TABLE t2 USING INDEX t2a1 .*/}
ifcapable stat4 {
ifcapable stat4||stat3 {
  execsql ANALYZE
  do_test index6-2.3stat4 {
    execsql {
      EXPLAIN QUERY PLAN
      SELECT * FROM t2 WHERE a IS NOT NULL;
    }
  } {/.* TABLE t2 USING INDEX t2a1 .*/}
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
406
407
408
409
410
411
412
























































































413







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  SELECT 'one', * FROM t2 WHERE x NOT IN (SELECT a FROM t1);
  CREATE INDEX t1a ON t1(a) WHERE b=1;
  SELECT 'two', * FROM t2 WHERE x NOT IN (SELECT a FROM t1);
} {}
do_execsql_test index6-12.2 {
  SELECT x FROM t2 WHERE x IN (SELECT a FROM t1) ORDER BY +x;
} {1 2}

# 2019-05-04
# Ticket https://www.sqlite.org/src/tktview/5c6955204c392ae763a95
# Theorem prover error
#
do_execsql_test index6-13.1 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0);
  CREATE INDEX index_0 ON t0(c0) WHERE c0 NOT NULL;
  INSERT INTO t0(c0) VALUES (NULL);
  SELECT * FROM t0 WHERE c0 OR 1;
} {{}}

# 2019-05-11
# Ticket https://sqlite.org/src/tktview/8025674847
reset_db
do_execsql_test index6-14.1 {
  CREATE TABLE IF NOT EXISTS t0 (c0, c1);
  CREATE INDEX IF NOT EXISTS i0 ON t0(c0, c1) WHERE c0 NOT NULL;
  INSERT INTO t0(c0, c1) VALUES(NULL, 'row');
  SELECT * FROM t0 WHERE t0.c0 IS NOT 1;
} {{} row}

do_execsql_test index6-14.2 {
  SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END;
} {{} row}

# 2019-08-30
# Ticket https://www.sqlite.org/src/info/a6408d42b9f44462
# Ticket https://www.sqlite.org/src/info/fba33c8b1df6a915
# https://sqlite.org/src/info/bac716244fddac1fe841
#
do_execsql_test index6-15.1 {
  DROP TABLE t0;
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES (NULL);
  CREATE INDEX i0 ON t0(1) WHERE c0 NOT NULL;
  SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) IS FALSE;
} {1}
do_execsql_test index6-15.2 {
  SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) BETWEEN FALSE AND TRUE;
} {1}
do_execsql_test index6-15.3 {
  SELECT 1 FROM t0 WHERE TRUE BETWEEN (t0.c0 IS FALSE) AND TRUE;
} {1}
do_execsql_test index6-15.4 {
  SELECT 1 FROM t0 WHERE FALSE BETWEEN FALSE AND (t0.c0 IS FALSE);
} {1}
do_execsql_test index6-15.5 {
  SELECT 1 FROM t0 WHERE (c0 IS FALSE) IN (FALSE);
} {1}

# 2019-09-03
# Ticket https://sqlite.org/src/info/767a8cbc6d20bd68
do_execsql_test index6-16.1 {
  DROP TABLE t0;
  CREATE TABLE t0(c0 COLLATE NOCASE, c1);
  CREATE INDEX i0 ON t0(0) WHERE c0 >= c1;
  INSERT INTO t0 VALUES('a', 'B');
  SELECT c1 <= c0, c0 >= c1 FROM t0;
} {1 0}
do_execsql_test index6-16.2 {
  SELECT 2 FROM t0 WHERE c0 >= c1;
} {}
do_execsql_test index6-16.3 {
  SELECT 3 FROM t0 WHERE c1 <= c0;
} {3}

# 2019-11-02
# Ticket https://sqlite.org/src/tktview/a9efb42811fa41ee286e8
db close
sqlite3 db :memory:
do_execsql_test index6-17.1 {
  CREATE TABLE t0(c0);
  CREATE INDEX i0 ON t0(0) WHERE c0 GLOB c0;
  INSERT INTO t0 VALUES (0);
  CREATE UNIQUE INDEX i1 ON t0(0);
  PRAGMA integrity_check;
} {ok}
do_execsql_test index6-17.2 {
  CREATE UNIQUE INDEX i2 ON t0(0);
  REPLACE INTO t0 VALUES(0);
  PRAGMA integrity_check;
} {ok}
do_execsql_test index6-17.3 {
  SELECT COUNT(*) FROM t0 WHERE t0.c0 GLOB t0.c0;
} {1}

finish_test

Changes to test/index7.test.

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
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







-
+
















-
+







    CREATE INDEX t1c ON t1(c);
    ANALYZE;
    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
    PRAGMA integrity_check;
  }
} {t1 {15 1} t1a {10 1} t1b {8 1} t1c {15 1} ok}

# Queries use partial indices at appropriate times.
# Queries use partial indices as appropriate times.
#
do_test index7-2.1 {
  execsql {
    CREATE TABLE t2(a,b PRIMARY KEY) without rowid;
    INSERT INTO t2(a,b) SELECT value, value FROM nums WHERE value<1000;
    UPDATE t2 SET a=NULL WHERE b%5==0;
    CREATE INDEX t2a1 ON t2(a) WHERE a IS NOT NULL;
    SELECT count(*) FROM t2 WHERE a IS NOT NULL;
  }
} {800}
do_test index7-2.2 {
  execsql {
    EXPLAIN QUERY PLAN
    SELECT * FROM t2 WHERE a=5;
  }
} {/.* TABLE t2 USING COVERING INDEX t2a1 .*/}
ifcapable stat4 {
ifcapable stat4||stat3 {
  do_test index7-2.3stat4 {
    execsql {
      EXPLAIN QUERY PLAN
      SELECT * FROM t2 WHERE a IS NOT NULL;
    }
  } {/.* TABLE t2 USING COVERING INDEX t2a1 .*/}
} else {
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
323
324
325
326
327
328
329






330


















331







-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  SELECT * FROM v4 WHERE d='xyz' AND c='def'
} {SEARCH TABLE t4 USING INDEX i4 (c=?)}

do_catchsql_test index7-6.5 {
  CREATE INDEX t5a ON t5(a) WHERE a=#1;
} {1 {near "#1": syntax error}}

do_execsql_test index7-7.0 {
  CREATE TABLE t6(x, y);
  INSERT INTO t6 VALUES(1, 1);
  INSERT INTO t6 VALUES(0, 0);
  SELECT * FROM t6 WHERE y IS TRUE ORDER BY x;
} {1 1}

do_execsql_test index7-7.1 {
  CREATE INDEX i6 ON t6(x) WHERE y IS NOT TRUE;
  SELECT * FROM t6 WHERE y IS TRUE ORDER BY x;
} {1 1}

# 2020-05-27.  tag-20200527-1.
# Incomplete stat1 information on a table with few rows should still use the
# index.
reset_db
do_execsql_test index7-8.1 {
  CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
  CREATE INDEX t1y ON t1(y) WHERE y IS NOT NULL;
  INSERT INTO t1(x) VALUES(1),(2);
  ANALYZE;
  EXPLAIN QUERY PLAN SELECT 1 FROM t1 WHERE y=5;
} {/SEARCH TABLE t1 USING COVERING INDEX t1y/}


finish_test

Changes to test/indexedby.test.

86
87
88
89
90
91
92
93
94
95



96
97
98

99
100
101
102
103
104
105
86
87
88
89
90
91
92



93
94
95
96
97

98
99
100
101
102
103
104
105







-
-
-
+
+
+


-
+







# EVIDENCE-OF: R-15800-25719 If index-name does not exist or cannot be
# used for the query, then the preparation of the SQL statement fails.
#
do_test indexedby-2.4 {
  catchsql { SELECT * FROM t1 INDEXED BY i3 WHERE a = 'one' AND b = 'two'}
} {1 {no such index: i3}}

# EVIDENCE-OF: R-05301-32681 If the query optimizer is unable to use the
# index specified by the INDEXED BY clause, then the query will fail
# with an error.
# EVIDENCE-OF: R-62112-42456 If the query optimizer is unable to use the
# index specified by the INDEX BY clause, then the query will fail with
# an error.
do_test indexedby-2.4.1 {
  catchsql { SELECT b FROM t1 INDEXED BY i1 WHERE b = 'two' }
} {0 {}}
} {1 {no query solution}}

do_test indexedby-2.5 {
  catchsql { SELECT * FROM t1 INDEXED BY i5 WHERE a = 'one' AND b = 'two'}
} {1 {no such index: i5}}
do_test indexedby-2.6 {
  catchsql { SELECT * FROM t1 INDEXED BY WHERE a = 'one' AND b = 'two'}
} {1 {near "WHERE": syntax error}}
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
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







-
+


-
+















-
+

















-
-
+
+





-
+




-
+




















-
+







  SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
do_eqp_test indexedby-3.3 {
  SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' AND b = 'two'
} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
do_test indexedby-3.4 {
  catchsql { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' }
} {0 {}}
} {1 {no query solution}}
do_test indexedby-3.5 {
  catchsql { SELECT * FROM t1 INDEXED BY i2 ORDER BY a }
} {0 {}}
} {1 {no query solution}}
do_test indexedby-3.6 {
  catchsql { SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' }
} {0 {}}
do_test indexedby-3.7 {
  catchsql { SELECT * FROM t1 INDEXED BY i1 ORDER BY a }
} {0 {}}

do_eqp_test indexedby-3.8 {
  SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 ORDER BY e 
} {SCAN TABLE t3 USING INDEX sqlite_autoindex_t3_1}
do_eqp_test indexedby-3.9 {
  SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE e = 10 
} {SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (e=?)}
do_test indexedby-3.10 {
  catchsql { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE f = 10 }
} {0 {}}
} {1 {no query solution}}
do_test indexedby-3.11 {
  catchsql { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_2 WHERE f = 10 }
} {1 {no such index: sqlite_autoindex_t3_2}}

# Tests for multiple table cases.
#
do_eqp_test indexedby-4.1 {
  SELECT * FROM t1, t2 WHERE a = c 
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SEARCH TABLE t2 USING INDEX i3 (c=?)
}
do_eqp_test indexedby-4.2 {
  SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c 
} {
  QUERY PLAN
  |--SCAN TABLE t1 USING INDEX i1
  `--SEARCH TABLE t2 USING INDEX i3 (c=?)
  |--SCAN TABLE t2
  `--SEARCH TABLE t1 USING INDEX i1 (a=?)
}
do_test indexedby-4.3 {
  catchsql {
    SELECT * FROM t1 INDEXED BY i1, t2 INDEXED BY i3 WHERE a=c
  }
} {0 {}}
} {1 {no query solution}}
do_test indexedby-4.4 {
  catchsql {
    SELECT * FROM t2 INDEXED BY i3, t1 INDEXED BY i1 WHERE a=c
  }
} {0 {}}
} {1 {no query solution}}

# Test embedding an INDEXED BY in a CREATE VIEW statement. This block
# also tests that nothing bad happens if an index refered to by
# a CREATE VIEW statement is dropped and recreated.
#
do_execsql_test indexedby-5.1 {
  CREATE VIEW v2 AS SELECT * FROM t1 INDEXED BY i1 WHERE a > 5;
  EXPLAIN QUERY PLAN SELECT * FROM v2 
} {/*SEARCH TABLE t1 USING INDEX i1 (a>?)*/}
do_execsql_test indexedby-5.2 {
  EXPLAIN QUERY PLAN SELECT * FROM v2 WHERE b = 10 
} {/*SEARCH TABLE t1 USING INDEX i1 (a>?)*/}
do_test indexedby-5.3 {
  execsql { DROP INDEX i1 }
  catchsql { SELECT * FROM v2 }
} {1 {no such index: i1}}
do_test indexedby-5.4 {
  # Recreate index i1 in such a way as it cannot be used by the view query.
  execsql { CREATE INDEX i1 ON t1(b) }
  catchsql { SELECT * FROM v2 }
} {0 {}}
} {1 {no query solution}}
do_test indexedby-5.5 {
  # Drop and recreate index i1 again. This time, create it so that it can
  # be used by the query.
  execsql { DROP INDEX i1 ; CREATE INDEX i1 ON t1(a) }
  catchsql { SELECT * FROM v2 }
} {0 {}}

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
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







-
+




















-
+

















-
+


-
+







  DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
do_eqp_test indexedby-7.5 {
  DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10
} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
do_test indexedby-7.6 {
  catchsql { DELETE FROM t1 INDEXED BY i2 WHERE a = 5}
} {0 {}}
} {1 {no query solution}}

# Test that "INDEXED BY" can be used in an UPDATE statement.
# 
do_eqp_test indexedby-8.1 {
  UPDATE t1 SET rowid=rowid+1 WHERE a = 5 
} {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
do_eqp_test indexedby-8.2 {
  UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5 
} {SCAN TABLE t1}
do_eqp_test indexedby-8.3 {
  UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 
} {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
do_eqp_test indexedby-8.4 {
  UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 AND b = 10
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
do_eqp_test indexedby-8.5 {
  UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5 AND b = 10
} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
do_test indexedby-8.6 {
  catchsql { UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5}
} {0 {}}
} {1 {no query solution}}

# Test that bug #3560 is fixed.
#
do_test indexedby-9.1 {
  execsql {
    CREATE TABLE maintable( id integer);
    CREATE TABLE joinme(id_int integer, id_text text);
    CREATE INDEX joinme_id_text_idx on joinme(id_text);
    CREATE INDEX joinme_id_int_idx on joinme(id_int);
  }
} {}
do_test indexedby-9.2 {
  catchsql {
    select * from maintable as m inner join
    joinme as j indexed by joinme_id_text_idx
    on ( m.id  = j.id_int)
  }
} {0 {}}
} {1 {no query solution}}
do_test indexedby-9.3 {
  catchsql { select * from maintable, joinme INDEXED by joinme_id_text_idx }
} {0 {}}
} {1 {no query solution}}

# Make sure we can still create tables, indices, and columns whose name
# is "indexed".
#
do_test indexedby-10.1 {
  execsql {
    CREATE TABLE indexed(x,y);

Changes to test/indexexpr1.test.

182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196







-
+








do_catchsql_test indexexpr1-300 {
  CREATE TABLE t2(a,b,c); INSERT INTO t2 VALUES(1,2,3);
  CREATE INDEX t2x1 ON t2(a,b+random());
} {1 {non-deterministic functions prohibited in index expressions}}
do_catchsql_test indexexpr1-301 {
  CREATE INDEX t2x1 ON t2(julianday('now',a));
} {1 {non-deterministic use of julianday() in an index}}
} {1 {non-deterministic function in index expression or CHECK constraint}}
do_catchsql_test indexexpr1-310 {
  CREATE INDEX t2x2 ON t2(a,b+(SELECT 15));
} {1 {subqueries prohibited in index expressions}}
do_catchsql_test indexexpr1-320 {
  CREATE TABLE e1(x,y,UNIQUE(y,substr(x,1,5)));
} {1 {expressions prohibited in PRIMARY KEY and UNIQUE constraints}}
do_catchsql_test indexexpr1-330 {
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
441
442
443
444
445
446
447




448


































449







-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  INSERT INTO t1 VALUES('1234',0),('001234',2),('01234',1);
  SELECT b FROM t1 WHERE lower(a)='1234' ORDER BY +b;
} {0 1 2 3}
do_execsql_test indexexpr-1620 {
  SELECT b FROM t1 WHERE lower(a)='01234' ORDER BY +b;
} {}

# 2019-08-09 https://www.sqlite.org/src/info/9080b6227fabb466
# ExprImpliesExpr theorem prover bug:
# "(NULL IS FALSE) IS FALSE" does not imply "NULL IS NULL"
#

do_execsql_test indexexpr-1700 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES (0);
  CREATE INDEX i0 ON t0(NULL > c0) WHERE (NULL NOT NULL);
  SELECT * FROM t0 WHERE ((NULL IS FALSE) IS FALSE);
} {0}

# 2019-09-02 https://www.sqlite.org/src/tktview/57af00b6642ecd6848
# When the expression of an an index-on-expression references a
# table column of type REAL that is actually holding an MEM_IntReal
# value, be sure to use the REAL value and not the INT value when
# computing the expression.
#
ifcapable like_match_blobs {
  do_execsql_test indexexpr-1800 {
    DROP TABLE IF EXISTS t0;
    CREATE TABLE t0(c0 REAL, c1 TEXT);
    CREATE INDEX i0 ON t0(+c0, c0);
    INSERT INTO t0(c0) VALUES(0);
    SELECT CAST(+ t0.c0 AS BLOB) LIKE 0 FROM t0; 
  } {0}
  do_execsql_test indexexpr-1810 {
    SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0; 
  } {1}
  do_execsql_test indexexpr-1820 {
    DROP TABLE IF EXISTS t1;
    CREATE TABLE t1(x REAL);
    CREATE INDEX t1x ON t1(x, +x);
    INSERT INTO t1(x) VALUES(2);
    SELECT +x FROM t1 WHERE x=2;
  } {2.0}
}

finish_test

Changes to test/indexexpr2.test.

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
274
275
276
277
278
279
280





























































































281
282







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  CREATE INDEX x1i2 ON x1( CAST(b AS TEXT) );
  SELECT a, b FROM x1 WHERE CAST(b AS TEXT) = 123;
} {1 123   2 123}
do_eqp_test 6.2.3 {
  SELECT a, b FROM x1 WHERE CAST(b AS TEXT) = 123;
} {SEARCH TABLE x1 USING INDEX x1i2 (<expr>=?)}

do_execsql_test 7.0 {
  CREATE TABLE IF NOT EXISTS t0(c0);
  INSERT INTO t0(c0) VALUES (-9223372036854775808);
  BEGIN;
}
do_catchsql_test 7.1 {
  CREATE INDEX i0 ON t0(ABS(c0));
} {1 {integer overflow}}
do_execsql_test 7.2 {
  COMMIT;
  SELECT sql FROM sqlite_master WHERE tbl_name = 't0';
  CREATE INDEX i0 ON t0(c0);
} {{CREATE TABLE t0(c0)}}
do_execsql_test 7.3 {
  REINDEX;
} {}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 8.0 {
  CREATE TABLE t0(c0);
  CREATE INDEX i0 ON t0(c0) WHERE c0 NOT NULL;
  INSERT INTO t0(c0) VALUES (NULL);
}

do_execsql_test 8.1.1 {
  SELECT * FROM t0 WHERE ~('' BETWEEN t0.c0 AND TRUE);
} {{}}
do_execsql_test 8.1.2 {
  SELECT ~('' BETWEEN t0.c0 AND TRUE) FROM t0;
} {-1}

foreach {tn expr} {
  1 " 0  ==  (34 BETWEEN c0 AND 33)"
  2 " 1  !=  (34 BETWEEN c0 AND 33)"
  3 "-1   <  (34 BETWEEN c0 AND 33)"
  4 "-1  <=  (34 BETWEEN c0 AND 33)"
  5 " 1   >  (34 BETWEEN c0 AND 33)"
  6 " 1  >=  (34 BETWEEN c0 AND 33)"
  7 " 1   -  (34 BETWEEN c0 AND 33)"
  8 "-1   +  (34 BETWEEN c0 AND 33)"
  9 " 1   |  (34 BETWEEN c0 AND 33)"
 10 " 1  <<  (34 BETWEEN c0 AND 33)"
 11 " 1  >>  (34 BETWEEN c0 AND 33)"
 12 " 1  ||  (34 BETWEEN c0 AND 33)"
} {
  do_execsql_test 8.3.$tn.1 "SELECT * FROM t0 WHERE $expr ORDER BY c0" { {} }
  do_execsql_test 8.3.$tn.2 "SELECT ($expr) IS TRUE FROM t0"           { 1 }
}

do_execsql_test 8.4 {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, 2), (3, 4);
  CREATE TABLE t2(x, y);
}

foreach {tn expr} {
  1 " 0  ==  (a=0 AND y=1)"
  2 " 1  !=  (a=0 AND y=1)"
  3 "-1  <   (a=0 AND y=1)"
  4 "-1  <=  (a=0 AND y=1)"
  5 " 1   >  (a=0 AND y=1)"
  6 " 1  >=  (a=0 AND y=1)"
  7 " 1   -  (a=0 AND y=1)"
  8 "-1   +  (a=0 AND y=1)"
  9 " 1   |  (a=0 AND y=1)"
  10 "1  <<  (a=0 AND y=1)"
  11 "1  >>  (a=0 AND y=1)"
  12 "1  ||  (a=0 AND y=1)"

  13 " 0  ==  (10 BETWEEN y AND b)"
  14 " 1  !=  (10 BETWEEN y AND b)"
  15 "-1  <   (10 BETWEEN y AND b)"
  16 "-1  <=  (10 BETWEEN y AND b)"
  17 " 1   >  (10 BETWEEN y AND b)"
  18 " 1  >=  (10 BETWEEN y AND b)"
  19 " 1   -  (10 BETWEEN y AND b)"
  20 "-1   +  (10 BETWEEN y AND b)"
  21 " 1   |  (10 BETWEEN y AND b)"
  22 " 1  <<  (10 BETWEEN y AND b)"
  23 " 1  >>  (10 BETWEEN y AND b)"
  24 " 1  ||  (10 BETWEEN y AND b)"

  25 " 1  ||  (10 BETWEEN y AND b)"
} {
  do_execsql_test 8.5.$tn.1 "
    SELECT * FROM t1 LEFT JOIN t2 WHERE $expr
  " {1 2 {} {} 3 4 {} {}}

  do_execsql_test 8.5.$tn.2 "
    SELECT ($expr) IS TRUE FROM t1 LEFT JOIN t2
  " {1 1}
}

finish_test

Changes to test/insert.test.

1

2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-
+












+







# 2001-09-15
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT statement.
#
# $Id: insert.test,v 1.31 2007/04/05 11:25:59 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Try to insert into a non-existant table.
#
do_test insert-1.1 {
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
454
455
456
457
458
459
460

461
462













































































































































463







-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_execsql_test insert-14.1 {
  DROP TABLE IF EXISTS t14;
  CREATE TABLE t14(x INTEGER PRIMARY KEY);
  INSERT INTO t14 VALUES(CASE WHEN 1 THEN null END);
  SELECT x FROM t14;
} {1}

integrity_check insert-14.2
integrity_check insert-99.0

# 2019-08-12.
#
do_execsql_test insert-15.1 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
  CREATE INDEX i1 ON t1(b);
  CREATE TABLE t2(a, b);
  INSERT INTO t2 VALUES(4, randomblob(31000));
  INSERT INTO t2 VALUES(4, randomblob(32000));
  INSERT INTO t2 VALUES(4, randomblob(33000));
  REPLACE INTO t1 SELECT a, b FROM t2;
  SELECT a, length(b) FROM t1;
} {4 33000}

# 2019-10-16
# ticket https://www.sqlite.org/src/info/a8a4847a2d96f5de
# On a REPLACE INTO, if an AFTER trigger adds back the conflicting
# row, you can end up with the wrong number of rows in an index.
#
db close
sqlite3 db :memory:
do_catchsql_test insert-16.1 {
  PRAGMA recursive_triggers = true;
  CREATE TABLE t0(c0,c1);
  CREATE UNIQUE INDEX i0 ON t0(c0);
  INSERT INTO t0(c0,c1) VALUES(123,1);
  CREATE TRIGGER tr0 AFTER DELETE ON t0
  BEGIN
    INSERT INTO t0 VALUES(123,2);
  END;
  REPLACE INTO t0(c0,c1) VALUES(123,3);
} {1 {UNIQUE constraint failed: t0.c0}}
do_execsql_test insert-16.2 {
  SELECT * FROM t0;
} {123 1}
integrity_check insert-16.3
do_catchsql_test insert-16.4 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  CREATE INDEX t1b ON t1(b);
  INSERT INTO t1 VALUES(1, 'one');
  CREATE TRIGGER tr3 AFTER DELETE ON t1 BEGIN
    INSERT INTO t1 VALUES(1, 'three');
  END;
  REPLACE INTO t1 VALUES(1, 'two');
} {1 {UNIQUE constraint failed: t1.a}}
integrity_check insert-16.5
do_catchsql_test insert-16.6 {
  PRAGMA foreign_keys = 1;
  CREATE TABLE p1(a, b UNIQUE);
  CREATE TABLE c1(c, d REFERENCES p1(b) ON DELETE CASCADE);
  CREATE TRIGGER tr6 AFTER DELETE ON c1 BEGIN
    INSERT INTO p1 VALUES(4, 1);
  END;
  INSERT INTO p1 VALUES(1, 1);
  INSERT INTO c1 VALUES(2, 1);
  REPLACE INTO p1 VALUES(3, 1);2
} {1 {UNIQUE constraint failed: p1.b}}
integrity_check insert-16.7

# 2019-10-25 ticket c1e19e12046d23fe
do_catchsql_test insert-17.1 {
  PRAGMA temp.recursive_triggers = true;
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(aa, bb);
  CREATE UNIQUE INDEX t0bb ON t0(bb);
  CREATE TRIGGER "r17.1" BEFORE DELETE ON t0
    BEGIN INSERT INTO t0(aa,bb) VALUES(99,1);
  END;
  INSERT INTO t0(aa,bb) VALUES(10,20);
  REPLACE INTO t0(aa,bb) VALUES(30,20);
} {1 {UNIQUE constraint failed: t0.rowid}}
integrity_check insert-17.2
do_catchsql_test insert-17.3 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a, b UNIQUE, c UNIQUE);
  INSERT INTO t1(a,b,c) VALUES(1,1,1),(2,2,2),(3,3,3),(4,4,4);
  CREATE TRIGGER "r17.3" AFTER DELETE ON t1 WHEN OLD.c<>3 BEGIN
    INSERT INTO t1(rowid,a,b,c) VALUES(100,100,100,3);
  END;
  REPLACE INTO t1(rowid,a,b,c) VALUES(200,1,2,3);
} {1 {UNIQUE constraint failed: t1.c}}
integrity_check insert-17.4
do_execsql_test insert-17.5 {
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
  CREATE UNIQUE INDEX t2b ON t2(b);
  INSERT INTO t2(a,b) VALUES(1,1),(2,2),(3,3),(4,4);
  CREATE TABLE fire(x);
  CREATE TRIGGER t2r1 AFTER DELETE ON t2 BEGIN
    INSERT INTO fire VALUES(old.a);
  END;
  UPDATE OR REPLACE t2 SET a=4, b=3 WHERE a=1;
  SELECT *, 'x' FROM t2 ORDER BY a;
} {2 2 x 4 3 x}
do_execsql_test insert-17.6 {
  SELECT x FROM fire ORDER BY x;
} {3 4}
do_execsql_test insert-17.7 {
  DELETE FROM t2;
  DELETE FROM fire;
  INSERT INTO t2(a,b) VALUES(1,1),(2,2),(3,3),(4,4);
  UPDATE OR REPLACE t2 SET a=1, b=3 WHERE a=1;
  SELECT *, 'x' FROM t2 ORDER BY a;
} {1 3 x 2 2 x 4 4 x}
do_execsql_test insert-17.8 {
  SELECT x FROM fire ORDER BY x;
} {3}
do_execsql_test insert-17.10 {
  CREATE TABLE t3(a INTEGER PRIMARY KEY, b INT, c INT, d INT);
  CREATE UNIQUE INDEX t3bpi ON t3(b) WHERE c<=d;
  CREATE UNIQUE INDEX t3d ON t3(d);
  INSERT INTO t3(a,b,c,d) VALUES(1,1,1,1),(2,1,3,2),(3,4,5,6);
  CREATE TRIGGER t3r1 AFTER DELETE ON t3 BEGIN
    SELECT 'hi';
  END;
  REPLACE INTO t3(a,b,c,d) VALUES(4,4,8,9);
} {}
do_execsql_test insert-17.11 {
  SELECT *, 'x' FROM t3 ORDER BY a;
} {1 1 1 1 x 2 1 3 2 x 4 4 8 9 x}
do_execsql_test insert-17.12 {
  REPLACE INTO t3(a,b,c,d) VALUES(5,1,11,2);
  SELECT *, 'x' FROM t3 ORDER BY a;
} {1 1 1 1 x 4 4 8 9 x 5 1 11 2 x}

do_execsql_test insert-17.13 {
  DELETE FROM t3;
  INSERT INTO t3(a,b,c,d) VALUES(1,1,1,1),(2,1,3,2),(3,4,5,6);
  DROP TRIGGER t3r1;
  CREATE TRIGGER t3r1 AFTER DELETE ON t3 BEGIN
    INSERT INTO t3(b,c,d) VALUES(old.b,old.c,old.d);
  END;
} {}
do_catchsql_test insert-17.14 {
  REPLACE INTO t3(a,b,c,d) VALUES(4,4,8,9);
} {1 {UNIQUE constraint failed: t3.b}}
do_catchsql_test insert-17.15 {
  REPLACE INTO t3(a,b,c,d) VALUES(5,1,11,2);
} {1 {UNIQUE constraint failed: t3.d}}


finish_test

Changes to test/insert4.test.

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
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







-

+



















-
+







#
proc xferopt_test {testname N} {
  do_test $testname {set ::sqlite3_xferopt_count} $N
}

# Create tables used for testing.
#
sqlite3_db_config db LEGACY_FILE_FORMAT 0
execsql {
  PRAGMA legacy_file_format = 0;
  CREATE TABLE t1(a int, b int, check(b>a));
  CREATE TABLE t2(x int, y int);
  CREATE VIEW v2 AS SELECT y, x FROM t2;
  CREATE TABLE t3(a int, b int);
}

# Ticket #2252.  Make sure the an INSERT from identical tables
# does not violate constraints.
#
do_test insert4-1.1 {
  set sqlite3_xferopt_count 0
  execsql {
    DELETE FROM t1;
    DELETE FROM t2;
    INSERT INTO t2 VALUES(9,1);
  }
  catchsql {
    INSERT INTO t1 SELECT * FROM t2;
  }
} {1 {CHECK constraint failed: b>a}}
} {1 {CHECK constraint failed: t1}}
xferopt_test insert4-1.2 0
do_test insert4-1.3 {
  execsql {
    SELECT * FROM t1;
  }
} {}

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
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







-
+

















-
+







xferopt_test insert4-2.3.2  0
do_test insert4-2.3.3 {
  catchsql {
    DELETE FROM t1;
    INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
    SELECT * FROM t1;
  }
} {1 {CHECK constraint failed: b>a}}
} {1 {CHECK constraint failed: t1}}
xferopt_test insert4-2.3.4 0

# Do not run the transfer optimization if there is a DISTINCT
#
do_test insert4-2.4.1 {
  execsql {
    DELETE FROM t3;
    INSERT INTO t3 SELECT DISTINCT * FROM t2;
    SELECT * FROM t3;
  }
} {9 1 1 9}
xferopt_test insert4-2.4.2 0
do_test insert4-2.4.3 {
  catchsql {
    DELETE FROM t1;
    INSERT INTO t1 SELECT DISTINCT * FROM t2;
  }
} {1 {CHECK constraint failed: b>a}}
} {1 {CHECK constraint failed: t1}}
xferopt_test insert4-2.4.4 0

# The following procedure constructs two tables then tries to transfer
# data from one table to the other.  Checks are made to make sure the
# transfer is successful and that the transfer optimization was used or
# not, as appropriate.
#
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335







-
+








-
+







do_test insert4-6.6 {
  execsql {
    CREATE TABLE t6b(x CHECK( x<>'abc' COLLATE nocase ));
  }
  catchsql {
    INSERT INTO t6b SELECT * FROM t6a;
  }
} {1 {CHECK constraint failed: x<>'abc' COLLATE nocase}}
} {1 {CHECK constraint failed: t6b}}
do_test insert4-6.7 {
  execsql {
    DROP TABLE t6b;
    CREATE TABLE t6b(x CHECK( x COLLATE nocase <>'abc' ));
  }
  catchsql {
    INSERT INTO t6b SELECT * FROM t6a;
  }
} {1 {CHECK constraint failed: x COLLATE nocase <>'abc'}}
} {1 {CHECK constraint failed: t6b}}

# Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
# Disable the xfer optimization if the destination table contains
# a foreign key constraint
#
ifcapable foreignkey {
  do_test insert4-7.1 {

Changes to test/instr.test.

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
253
254
255
256
257
258
259





















260







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

} 0
do_execsql_test instr-1.64 {
  CREATE TABLE x1(a, b);
  INSERT INTO x1 VALUES(X'', 'abc');
  SELECT instr(a, b) FROM x1;
} 0

# 2019-09-16 ticket https://www.sqlite.org/src/info/587791f92620090e
#
do_execsql_test instr-2.0 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 PRIMARY KEY, c1);
  INSERT INTO t0(c0) VALUES (x'bb'), (0);
  SELECT COUNT(*) FROM t0 WHERE INSTR(x'aabb', t0.c0) ORDER BY t0.c0, t0.c1;
} {1}
do_execsql_test instr-2.1 {
  SELECT quote(c0) FROM t0 WHERE INSTR(x'aabb', t0.c0) ORDER BY t0.c0, t0.c1;
} {X'BB'}
do_execsql_test instr-2.2 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x);
  INSERT INTO t1(x) VALUES('text'),(x'bb');
  SELECT quote(x) FROM t1 WHERE instr(x'aabb',x);
} {X'BB'}
do_execsql_test instr-2.3 {
  SELECT quote(x) FROM t1 WHERE x>'zzz' AND instr(x'aabb',x);
} {X'BB'}

finish_test

Changes to test/instrfault.test.

65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79







-
+







    faultsim_test_result {0 31}
    sqlite3_finalize $::stmt
  }

  do_faultsim_test 1.$enc.4 -faults oom-t* -prep {
    set ::stmt [sqlite3_prepare_v2 db "SELECT instr(?, ?)" -1 dummy]
    sqlite3_bind_blob $::stmt 1 $::HAYSTACK [string length $::HAYSTACK]
    sqlite3_bind_blob $::stmt 2 $::NEEDLE [string length $::NEEDLE]
    sqlite3_bind_text $::stmt 2 $::NEEDLE [string length $::NEEDLE]
  } -body {
    set rc [sqlite3_step $::stmt]
    if {$rc=="SQLITE_NOMEM"} { error "out of memory" }
    sqlite3_column_int $::stmt 0
  } -test {
    faultsim_test_result {0 31}
    sqlite3_finalize $::stmt

Changes to test/intarray.test.

43
44
45
46
47
48
49
50

51
52
53
54
55



56
57
58
59
60
61
62
43
44
45
46
47
48
49

50
51
52



53
54
55
56
57
58
59
60
61
62







-
+


-
-
-
+
+
+







  set ia4 [sqlite3_intarray_create db ia4]
  db eval {
    SELECT type, name FROM temp.sqlite_master
     ORDER BY name
  }
} {table ia1 table ia2 table ia3 table ia4}

# Verify the ability to DROP and recreate an intarray virtual table.
# Verify the inability to DROP and recreate an intarray virtual table.
do_test intarray-1.1b {
  db eval {DROP TABLE ia1}
  set rc [catch {sqlite3_intarray_create db ia1} ia1]
  lappend rc $ia1
} {/0 [0-9A-Z]+/} 
  set rc [catch {sqlite3_intarray_create db ia1} msg]
  lappend rc $msg
} {1 SQLITE_MISUSE}

do_test intarray-1.2 {
  db eval {
    SELECT b FROM t1 WHERE a IN ia3 ORDER BY a
  }
} {}

Deleted test/intreal.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


































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-05-03
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# Tests to exercise the MEM_IntReal representation of Mem objects.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix intreal

sqlite3_create_function db
do_execsql_test 100 {
  SELECT intreal(5);
} {5.0}
do_execsql_test 110 {
  SELECT intreal(5)=5, 6=intreal(6);
} {1 1}
do_execsql_test 120 {
  SELECT intreal(7)=7.0, 8.0=intreal(8);
} {1 1}
do_execsql_test 130 {
  SELECT typeof(intreal(9));
} {real}
do_execsql_test 140 {
  SELECT 'a'||intreal(11)||'z';
} {a11.0z}

do_execsql_test 150 {
  SELECT max(1.0,intreal(2),3.0), max(1,intreal(2),3);
} {3.0 3}
do_execsql_test 160 {
  SELECT max(1.0,intreal(4),3.0), max(1,intreal(4),3);
} {4.0 4.0}
do_execsql_test 170 {
  SELECT max(1.0,intreal(2),intreal(3),4.0),
         max(1,intreal(2),intreal(3),4);
} {4.0 4}
do_execsql_test 180 {
  SELECT max(1.0,intreal(5),intreal(3),4.0),
         max(1,intreal(5),intreal(3),4);
} {5.0 5.0}

#-------------------------------------------------------------------------
do_execsql_test 2.1 {
  CREATE TABLE t2(a REAL);
  INSERT INTO t2 VALUES( 836627109860825358 );
  SELECT substr(a,1,4) FROM t2 WHERE a = CAST(836627109860825358 AS REAL);
} {8.36}

do_execsql_test 2.2 {
  CREATE INDEX i2 ON t2(a);
  SELECT substr(a,1,4) FROM t2 WHERE a = CAST(836627109860825358 AS REAL);
} {8.36}

do_execsql_test 2.3 {
  CREATE TABLE t0 (c0);
  CREATE TABLE t1 (c1 REAL);
  INSERT INTO t1(c1) VALUES (8366271098608253588);
  INSERT INTO t0(c0) VALUES ('a');
}
set D [db one {SELECT c1 FROM t1}]

do_execsql_test 2.4 {
  SELECT * FROM t1 WHERE (t1.c1 = CAST(8366271098608253588 AS REAL));
} $D

do_execsql_test 2.5 {
  SELECT * FROM t0, t1 WHERE (t1.c1 = CAST(8366271098608253588 AS REAL));
} [list a $D]

do_execsql_test 2.6 {
  SELECT * FROM t0, t1 
  WHERE (
        t1.c1 >= CAST(8366271098608253588 AS REAL) 
    AND t1.c1 <= CAST(8366271098608253588 AS REAL)
  );
} [list a $D]

# 2019-07-29 ticket ba2f4585cf495231
#
db close
sqlite3 db :memory:
do_execsql_test 3.0 {
  CREATE TABLE t0 (c0 REAL, c1);
  CREATE UNIQUE INDEX i0 ON t0(c1, 0 | c0);
  INSERT INTO t0(c0) VALUES (4750228396194493326), (0);
  UPDATE OR REPLACE t0 SET c0 = 'a', c1 = '';
  SELECT * FROM t0 ORDER BY t0.c1;
  PRAGMA integrity_check;
} {a {} ok}

finish_test

Changes to test/istrue.test.

108
109
110
111
112
113
114
115

116
117
118

119
120
121

122
123
124

125
126
127
128
129
130
131
108
109
110
111
112
113
114

115
116
117

118
119
120

121
122
123

124
125
126
127
128
129
130
131







-
+


-
+


-
+


-
+







     e BOOLEAN CHECK(e IS NOT FALSE)
  );
  INSERT INTO t2 VALUES(1,true,false,null,null);
  SELECT * FROM t2;
} {1 1 0 {} {}}
do_catchsql_test istrue-521 {
  INSERT INTO t2 VALUES(2,false,false,null,null);
} {1 {CHECK constraint failed: b IS TRUE}}
} {1 {CHECK constraint failed: t2}}
do_catchsql_test istrue-522 {
  INSERT INTO t2 VALUES(2,true,true,null,null);
} {1 {CHECK constraint failed: c IS FALSE}}
} {1 {CHECK constraint failed: t2}}
do_catchsql_test istrue-523 {
  INSERT INTO t2 VALUES(2,true,false,true,null);
} {1 {CHECK constraint failed: d IS NOT TRUE}}
} {1 {CHECK constraint failed: t2}}
do_catchsql_test istrue-524 {
  INSERT INTO t2 VALUES(2,true,false,null,false);
} {1 {CHECK constraint failed: e IS NOT FALSE}}
} {1 {CHECK constraint failed: t2}}

foreach {tn val} [list 1 NaN 2 -NaN 3 NaN0 4 -NaN0 5 Inf 6 -Inf] {
  do_execsql_test istrue-600.$tn.1 {
    DROP TABLE IF EXISTS t1;
    CREATE TABLE t1(x);
  }
  do_test istrue-600.$tn.2 {
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
154
155
156
157
158
159
160











































161







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  ALTER TABLE t7 ADD COLUMN d BOOLEAN DEFAULT false;
  ALTER TABLE t7 ADD COLUMN e BOOLEAN DEFAULT true;
  INSERT INTO t7(a,b,c) VALUES(3,true,false);
  INSERT INTO t7 VALUES(4,false,true,true,false);
  SELECT *,'x' FROM t7 ORDER BY a;
} {1 0 1 0 1 x 2 1 0 0 1 x 3 1 0 0 1 x 4 0 1 1 0 x}

do_execsql_test istrue-710 {
  SELECT 0.5 IS TRUE COLLATE NOCASE;
  SELECT 0.5 IS TRUE COLLATE RTRIM;
  SELECT 0.5 IS TRUE COLLATE BINARY;

  SELECT 0.5 IS TRUE;
  SELECT 0.5 COLLATE NOCASE IS TRUE;
  SELECT 0.0 IS FALSE;

  SELECT 0.0 IS FALSE COLLATE NOCASE;
  SELECT 0.0 IS FALSE COLLATE RTRIM;
  SELECT 0.0 IS FALSE COLLATE BINARY;
} {1 1 1   1 1 1  1 1 1}

# 2020-06-12 bug report from Chromium
# https://bugs.chromium.org/p/chromium/issues/detail?id=1094247
do_catchsql_test istrue-800 {
  SELECT 9 IN (false.false);
} {1 {no such column: false.false}}
do_execsql_test istrue-810 {
  CREATE TABLE t8(a INT, true INT, false INT, d INT);
  INSERT INTO t8(a,true,false,d) VALUES(5,6,7,8),(4,3,2,1),('a','b','c','d');
  SELECT * FROM t8 ORDER BY false;
} {4 3 2 1 5 6 7 8 a b c d}
do_catchsql_test istrue-820 {
  SELECT 9 IN (false.false) FROM t8;
} {1 {no such column: false.false}}
do_execsql_test istrue-830 {
  CREATE TABLE false(true INT, false INT, x INT CHECK (5 IN (false.false)));
} {}
do_execsql_test istrue-840 {
  INSERT INTO False VALUES(4,5,6);
} {}
do_catchsql_test istrue-841 {
  INSERT INTO False VALUES(5,6,7);
} {1 {CHECK constraint failed: 5 IN (false.false)}}
do_execsql_test istrue-850 {
  SELECT 9 IN (false.false) FROM false;
} {0}
do_execsql_test istrue-851 {
  SELECT 5 IN (false.false) FROM false;
} {1}

finish_test

Changes to test/join.test.

808
809
810
811
812
813
814
815

816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
808
809
810
811
812
813
814

815
816
817
818
819





820
821
822
823
824
825
826







-
+




-
-
-
-
-







   WHERE CASE WHEN FALSE THEN a=x ELSE 1 END;
} {1 2 {} {} x 3 4 {} {} x}
do_execsql_test join-15.105 {
  SELECT *, 'x'
    FROM t1 LEFT JOIN t2
   WHERE a IN (1,3,x,y);
} {1 2 {} {} x 3 4 {} {} x}
do_execsql_test join-15.106a {
do_execsql_test join-15.106 {
  SELECT *, 'x' 
    FROM t1 LEFT JOIN t2 
   WHERE NOT ( 'x'='y' AND t2.y=1 );
} {1 2 {} {} x 3 4 {} {} x}
do_execsql_test join-15.106b {
  SELECT *, 'x' 
    FROM t1 LEFT JOIN t2 
   WHERE ~ ( 'x'='y' AND t2.y=1 );
} {1 2 {} {} x 3 4 {} {} x}
do_execsql_test join-15.107 {
  SELECT *, 'x' 
    FROM t1 LEFT JOIN t2 
   WHERE t2.y IS NOT 'abc'
} {1 2 {} {} x 3 4 {} {} x}
do_execsql_test join-15.110 {
  DROP TABLE t1;
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
859
860
861
862
863
864
865
866










































































































































































867








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  CREATE TABLE t1(a INT);
  INSERT INTO t1(a) VALUES(1);
  CREATE TABLE t2(b INT);
  SELECT a, b
    FROM t1 LEFT JOIN t2 ON 0
   WHERE (b IS NOT NULL)=0;
} {1 {}}

# 2019-08-17 ticket https://sqlite.org/src/tktview/6710d2f7a13a299728ab
# Ensure that constants that derive from the right-hand table of a LEFT JOIN
# are never factored out, since they are not really constant.
#
do_execsql_test join-17.100 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x);
  INSERT INTO t1(x) VALUES(0),(1);
  SELECT * FROM t1 LEFT JOIN (SELECT abs(1) AS y FROM t1) ON x WHERE NOT(y='a');
} {1 1 1 1}
do_execsql_test join-17.110 {
  SELECT * FROM t1 LEFT JOIN (SELECT abs(1)+2 AS y FROM t1) ON x
   WHERE NOT(y='a');
} {1 3 1 3}

#-------------------------------------------------------------------------
reset_db
do_execsql_test join-18.1 {
  CREATE TABLE t0(a);
  CREATE TABLE t1(b);
  CREATE VIEW v0 AS SELECT a FROM t1 LEFT JOIN t0;
  INSERT INTO t1 VALUES (1);
} {}

do_execsql_test join-18.2 {
  SELECT * FROM v0 WHERE NOT(v0.a IS FALSE);
} {{}}

do_execsql_test join-18.3 {
  SELECT * FROM t1 LEFT JOIN t0 WHERE NOT(a IS FALSE);
} {1 {}}

do_execsql_test join-18.4 {
  SELECT NOT(v0.a IS FALSE) FROM v0
} {1}

#-------------------------------------------------------------------------
reset_db
do_execsql_test join-19.0 {
  CREATE TABLE t1(a);
  CREATE TABLE t2(b);
  INSERT INTO t1(a) VALUES(0);
  CREATE VIEW v0(c) AS SELECT t2.b FROM t1 LEFT JOIN t2;
}

do_execsql_test join-19.1 {
  SELECT * FROM v0 WHERE v0.c NOTNULL NOTNULL; 
} {{}}

do_execsql_test join-19.2 {
  SELECT * FROM t1 LEFT JOIN t2
} {0 {}}

do_execsql_test join-19.3 {
  SELECT * FROM t1 LEFT JOIN t2 WHERE (b IS NOT NULL) IS NOT NULL; 
} {0 {}}

do_execsql_test join-19.4 {
  SELECT (b IS NOT NULL) IS NOT NULL FROM t1 LEFT JOIN t2
} {1}

do_execsql_test join-19.5 {
  SELECT * FROM t1 LEFT JOIN t2 WHERE 
    (b IS NOT NULL AND b IS NOT NULL) IS NOT NULL; 
} {0 {}}

# 2019-11-02 ticket 623eff57e76d45f6
# The optimization of exclusing the WHERE expression of a partial index
# from the WHERE clause of the query if the index is used does not work
# of the table of the index is the right-hand table of a LEFT JOIN.
#
db close
sqlite3 db :memory:
do_execsql_test join-20.1 {
  CREATE TABLE t1(c1);
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES (0);
  SELECT * FROM t0 LEFT JOIN t1 WHERE NULL IN (c1);
} {}
do_execsql_test join-20.2 {
  CREATE INDEX t1x ON t1(0) WHERE NULL IN (c1);
  SELECT * FROM t0 LEFT JOIN t1 WHERE NULL IN (c1);
} {}

# 2019-11-30 ticket 7f39060a24b47353
# Do not allow a WHERE clause term to qualify a partial index on the
# right table of a LEFT JOIN.
#
do_execsql_test join-21.10 {
  DROP TABLE t0;
  DROP TABLE t1;
  CREATE TABLE t0(aa);
  CREATE TABLE t1(bb);
  INSERT INTO t0(aa) VALUES (1);
  INSERT INTO t1(bb) VALUES (1);
  SELECT 11, * FROM t1 LEFT JOIN t0 WHERE aa ISNULL;
  SELECT 12, * FROM t1 LEFT JOIN t0 WHERE +aa ISNULL;
  SELECT 13, * FROM t1 LEFT JOIN t0 ON aa ISNULL;
  SELECT 14, * FROM t1 LEFT JOIN t0 ON +aa ISNULL;
  CREATE INDEX i0 ON t0(aa) WHERE aa ISNULL;
  SELECT 21, * FROM t1 LEFT JOIN t0 WHERE aa ISNULL;
  SELECT 22, * FROM t1 LEFT JOIN t0 WHERE +aa ISNULL;
  SELECT 23, * FROM t1 LEFT JOIN t0 ON aa ISNULL;
  SELECT 24, * FROM t1 LEFT JOIN t0 ON +aa ISNULL;
} {13 1 {} 14 1 {} 23 1 {} 24 1 {}}

# 2019-12-18 problem with a LEFT JOIN where the RHS is a view.
# Detected by Yongheng and Rui.
# Follows from the optimization attempt of check-in 41c27bc0ff1d3135
# on 2017-04-18
#
reset_db
do_execsql_test join-22.10 {
  CREATE TABLE t0(a, b);
  CREATE INDEX t0a ON t0(a);
  INSERT INTO t0 VALUES(10,10),(10,11),(10,12);
  SELECT DISTINCT c FROM t0 LEFT JOIN (SELECT a+1 AS c FROM t0) ORDER BY c ;
} {11}

# 2019-12-22 ticket 7929c1efb2d67e98
#
reset_db
ifcapable vtab {
do_execsql_test join-23.10 {
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES(123);
  CREATE VIEW v0(c0) AS SELECT 0 GROUP BY 1;
  SELECT t0.c0, v0.c0, vt0.name
   FROM v0, t0 LEFT JOIN pragma_table_info('t0') AS vt0
     ON vt0.name LIKE 'c0'
   WHERE v0.c0 == 0;
} {123 0 c0}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test join-24.1 {
  CREATE TABLE t1(a PRIMARY KEY, x);
  CREATE TABLE t2(b INT);
  CREATE INDEX t1aa ON t1(a, a);

  INSERT INTO t1 VALUES('abc', 'def');
  INSERT INTO t2 VALUES(1);
}

do_execsql_test join-24.2 {
  SELECT * FROM t2 JOIN t1 WHERE a='abc' AND x='def';
} {1 abc def}
do_execsql_test join-24.3 {
  SELECT * FROM t2 JOIN t1 WHERE a='abc' AND x='abc';
} {}

do_execsql_test join-24.2 {
  SELECT * FROM t2 LEFT JOIN t1 ON a=0 WHERE (x='x' OR x IS NULL);
} {1 {} {}}

# 2020-09-30 ticket 66e4b0e271c47145
# The query flattener inserts an "expr AND expr" expression as a substitution
# for the column of a view where that view column is part of an ON expression
# of a LEFT JOIN.
#
reset_db
do_execsql_test join-25.1 {
  CREATE TABLE t0(c0 INT);
  CREATE VIEW v0 AS SELECT (NULL AND 5) as c0 FROM t0;
  INSERT INTO t0(c0) VALUES (NULL);
  SELECT count(*)  FROM v0 LEFT JOIN t0 ON v0.c0;
} {1}


finish_test

Changes to test/join2.test.

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
275
276
277
278
279
280
281




























































282
283







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  CREATE VIEW test AS
    SELECT *, 'x'
      FROM t1 LEFT JOIN (SELECT * FROM t2, t3) ON (c=b AND x=9)
      WHERE c IS NULL;
  SELECT * FROM test;
} {3 4 {} {} {} x 5 6 {} {} {} x}

#-------------------------------------------------------------------------
# Ticket [dfd66334].
#
reset_db
do_execsql_test 8.0 {
  CREATE TABLE t0(c0);
  CREATE TABLE t1(c0);
}

do_execsql_test 8.1 {
  SELECT * FROM t0 LEFT JOIN t1 
  WHERE (t1.c0 BETWEEN 0 AND 0) > ('' AND t0.c0);
}

#-------------------------------------------------------------------------
# Ticket [45f4bf4eb] reported by Manuel Rigger (2020-04-25)
#
# Follow up error reported by Eric Speckman on the SQLite forum
# https://sqlite.org/forum/info/c49496d24d35bd7c (2020-08-19)
#
reset_db
do_execsql_test 9.0 {
  CREATE TABLE t0(c0 INT);
  CREATE VIEW v0(c0) AS SELECT CAST(t0.c0 AS INTEGER) FROM t0;
  INSERT INTO t0(c0) VALUES (0);
}

do_execsql_test 9.1 {
  SELECT typeof(c0), c0 FROM v0 WHERE c0>='0'
} {integer 0}

do_execsql_test 9.2 {
  SELECT * FROM t0, v0 WHERE v0.c0 >= '0';
} {0 0}

do_execsql_test 9.3 {
  SELECT * FROM t0 LEFT JOIN v0 WHERE v0.c0 >= '0';
} {0 0}

do_execsql_test 9.4 {
  SELECT * FROM t0 LEFT JOIN v0 ON v0.c0 >= '0';
} {0 0}

do_execsql_test 9.5 {
  SELECT * FROM t0 LEFT JOIN v0 ON v0.c0 >= '0' WHERE TRUE 
  UNION SELECT 0,0 WHERE 0; 
} {0 0}

do_execsql_test 9.10 {
  CREATE TABLE t1 (aaa);
  INSERT INTO t1 VALUES(23456);
  CREATE TABLE t2(bbb);
  CREATE VIEW v2(ccc) AS SELECT bbb IS 1234 FROM t2;
  SELECT ccc, ccc IS NULL AS ddd FROM t1 LEFT JOIN v2;
} {{} 1}
optimization_control db query-flattener 0
do_execsql_test 9.11 {
  SELECT ccc, ccc IS NULL AS ddd FROM t1 LEFT JOIN v2;
} {{} 1}


finish_test

Changes to test/join5.test.

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
302
303
304
305
306
307
308





















309







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
} {
  QUERY PLAN
  |--SCAN TABLE t3
  `--SEARCH TABLE t4 USING INDEX t4xz (x=?)
} 

reset_db
do_execsql_test 8.0 {
  CREATE TABLE t0 (c0, c1, PRIMARY KEY (c0, c1));
  CREATE TABLE t1 (c0);

  INSERT INTO t1 VALUES (2);

  INSERT INTO t0 VALUES(0, 10);
  INSERT INTO t0 VALUES(1, 10);
  INSERT INTO t0 VALUES(2, 10);
  INSERT INTO t0 VALUES(3, 10);
}

do_execsql_test 8.1 {
  SELECT * FROM t0, t1 
  WHERE (t0.c1 >= 1 OR t0.c1 < 1) AND t0.c0 IN (1, t1.c0) ORDER BY 1;
} {
  1 10 2
  2 10 2
}

finish_test

Changes to test/join6.test.

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
143
144
145
146
147
148
149
















150
151
152
153
154
155
156







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    execsql {
      SELECT * FROM t1 NATURAL JOIN t2 NATURAL JOIN
         (SELECT 5 AS c, 91 AS x, 93 AS z UNION SELECT 6, 99, 95)
    }
  } {1 91 92 3 93 5}
}

do_execsql_test join6-5.1 {
  CREATE TABLE tx(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o PRIMARY KEY) 
  WITHOUT ROWID;
  INSERT INTO tx VALUES(
    1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  );
} {}
do_execsql_test joint6-5.2 {
  SELECT o FROM tx NATURAL JOIN tx;
} {15}

do_execsql_test join6-5.3 {
  CREATE TABLE ty(a,Ñ,x6,x7,x8,Q,I,v,x1,L,E,x2,x3,x4,x5,s,g PRIMARY KEY,b,c)
  WITHOUT ROWID;
  SELECT a FROM ty NATURAL JOIN ty;
}







Changes to test/journal3.test.

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
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







-








-
+











-
+







   1 00644
   2 00666
   3 00600
   4 00755
  } {
    db close
    #set effective [format %.5o [expr $permissions & ~$umask]]
    set res "/[regsub {^00} $permissions {0.}]/"
    if {$tcl_version>=8.7} {
       regsub {^00} $permissions {0o} permissions
    }
    set effective $permissions
    do_test journal3-1.2.$tn.1 {
      catch { forcedelete test.db-journal }
      file attributes test.db -permissions $permissions
      file attributes test.db -permissions
    } $res
    } $permissions
    do_test journal3-1.2.$tn.2 { file exists test.db-journal } {0}
    do_test journal3-1.2.$tn.3 {
      sqlite3 db test.db
      execsql { 
        BEGIN;
          INSERT INTO tx DEFAULT VALUES;
      }
      file exists test.db-journal
    } {1}
    do_test journal3-1.2.$tn.4 {
      file attr test.db-journal -perm
    } $res
    } $effective
    do_execsql_test journal3-1.2.$tn.5 { ROLLBACK } {}
  }


}

finish_test

Changes to test/jrnlmode.test.

61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
61
62
63
64
65
66
67

68









69
70
71
72
73
74
75







-
+
-
-
-
-
-
-
-
-
-







do_test jrnlmode-1.2 {
  execsql {
    PRAGMA journal_mode;
    PRAGMA main.journal_mode;
    PRAGMA temp.journal_mode;
  } 
} [list persist persist [temp_journal_mode persist]]
do_test jrnlmode-1.4a {
do_test jrnlmode-1.4 {
  # When defensive is on, unable to set journal_mode to OFF
  sqlite3_db_config db DEFENSIVE 1
  execsql {
    PRAGMA journal_mode = off;
  } 
} {persist}
do_test jrnlmode-1.4b {
  # When defensive is on, unable to set journal_mode to OFF
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    PRAGMA journal_mode = off;
  } 
} {off}
do_test jrnlmode-1.5 {
  execsql {
    PRAGMA journal_mode;

Changes to test/json101.test.

827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
827
828
829
830
831
832
833















834
835







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
do_execsql_test json-15.120 {
  SELECT * FROM (JSON_EACH('{"a":1, "b":2}'));
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
do_execsql_test json-15.130 {
  SELECT xyz.* FROM (JSON_EACH('{"a":1, "b":2}')) AS xyz;
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}

# 2019-11-10
# Mailing list bug report on the handling of surrogate pairs
# in JSON.
#
do_execsql_test json-16.10 {
  SELECT length(json_extract('"abc\uD834\uDD1Exyz"','$'));
} {7}
do_execsql_test json-16.20 {
  SELECT length(json_extract('"\uD834\uDD1E"','$'));
} {1}
do_execsql_test json-16.30 {
  SELECT unicode(json_extract('"\uD834\uDD1E"','$'));
} {119070}


finish_test

Changes to test/json104.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22







-







#
#***********************************************************************
# This file implements tests for json_patch(A,B) SQL function.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix json104

ifcapable !json1 {
  finish_test
  return
}

# This is the example from pages 2 and 3 of RFC-7396
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
121
122
123
124
125
126
127

128






















129

130







-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-

do_execsql_test json104-313 {
  SELECT json_patch('[1,2]','{"a":"b","c":null}');
} {{{"a":"b"}}}
do_execsql_test json104-314 {
  SELECT json_patch('{}','{"a":{"bb":{"ccc":null}}}');
} {{{"a":{"bb":{}}}}}

#-------------------------------------------------------------------------

do_execsql_test 401 {
  CREATE TABLE obj(x);
  INSERT INTO obj VALUES('{"a":1,"b":2}');
  SELECT * FROM obj;
} {{{"a":1,"b":2}}}
do_execsql_test 402 {
  UPDATE obj SET x = json_insert(x, '$.c', 3);
  SELECT * FROM obj;
} {{{"a":1,"b":2,"c":3}}}
do_execsql_test 403 {
  SELECT json_extract(x, '$.b') FROM obj;
  SELECT json_extract(x, '$."b"') FROM obj;
} {2 2}
do_execsql_test 404 {
  UPDATE obj SET x = json_set(x, '$."b"', 555);
  SELECT json_extract(x, '$.b') FROM obj;
  SELECT json_extract(x, '$."b"') FROM obj;
} {555 555}
do_execsql_test 405 {
  UPDATE obj SET x = json_set(x, '$."d"', 4);
  SELECT json_extract(x, '$."d"') FROM obj;
} {4}


finish_test

Deleted test/json105.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






















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-11-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 tests for "[#]" extension to json-path
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix json104

ifcapable !json1 {
  finish_test
  return
}

# This is the example from pages 2 and 3 of RFC-7396
db eval {
  CREATE TABLE t1(j);
  INSERT INTO t1(j) VALUES('{"a":1,"b":[1,[2,3],4],"c":99}');
}
proc json_extract_test {testnum path result} {
  do_execsql_test json105-1.$testnum "SELECT quote(json_extract(j,$path)) FROM t1" $result
}
json_extract_test 10 {'$.b[#]'}   NULL
json_extract_test 20 {'$.b[#-1]'} 4
json_extract_test 30 {'$.b[#-2]'} {'[2,3]'}
json_extract_test 31 {'$.b[#-02]'} {'[2,3]'}
json_extract_test 40 {'$.b[#-3]'} 1
json_extract_test 50 {'$.b[#-4]'} NULL
json_extract_test 60 {'$.b[#-2][#-1]'} 3
json_extract_test 70 {'$.b[0]','$.b[#-1]'} {'[1,4]'}

json_extract_test 100 {'$.a[#-1]'} NULL
json_extract_test 110 {'$.b[#-000001]'} 4

proc json_remove_test {testnum path result} {
  do_execsql_test json105-2.$testnum "SELECT quote(json_remove(j,$path)) FROM t1" $result
}
json_remove_test 10 {'$.b[#]'}    {'{"a":1,"b":[1,[2,3],4],"c":99}'}
json_remove_test 20 {'$.b[#-0]'}  {'{"a":1,"b":[1,[2,3],4],"c":99}'}
json_remove_test 30 {'$.b[#-1]'}  {'{"a":1,"b":[1,[2,3]],"c":99}'}
json_remove_test 40 {'$.b[#-2]'}  {'{"a":1,"b":[1,4],"c":99}'}
json_remove_test 50 {'$.b[#-3]'}  {'{"a":1,"b":[[2,3],4],"c":99}'}
json_remove_test 60 {'$.b[#-4]'}  {'{"a":1,"b":[1,[2,3],4],"c":99}'}
json_remove_test 70 {'$.b[#-2][#-1]'}  {'{"a":1,"b":[1,[2],4],"c":99}'}

json_remove_test 100 {'$.b[0]','$.b[#-1]'} {'{"a":1,"b":[[2,3]],"c":99}'}
json_remove_test 110 {'$.b[#-1]','$.b[0]'} {'{"a":1,"b":[[2,3]],"c":99}'}
json_remove_test 120 {'$.b[#-1]','$.b[#-2]'} {'{"a":1,"b":[[2,3]],"c":99}'}
json_remove_test 130 {'$.b[#-1]','$.b[#-1]'} {'{"a":1,"b":[1],"c":99}'}
json_remove_test 140 {'$.b[#-2]','$.b[#-1]'} {'{"a":1,"b":[1],"c":99}'}

proc json_insert_test {testnum x result} {
  do_execsql_test json105-3.$testnum "SELECT quote(json_insert(j,$x)) FROM t1" $result
}
json_insert_test 10 {'$.b[#]','AAA'} {'{"a":1,"b":[1,[2,3],4,"AAA"],"c":99}'}
json_insert_test 20 {'$.b[1][#]','AAA'} {'{"a":1,"b":[1,[2,3,"AAA"],4],"c":99}'}
json_insert_test 30 {'$.b[1][#]','AAA','$.b[#]','BBB'} \
     {'{"a":1,"b":[1,[2,3,"AAA"],4,"BBB"],"c":99}'}
json_insert_test 40 {'$.b[#]','AAA','$.b[#]','BBB'} \
     {'{"a":1,"b":[1,[2,3],4,"AAA","BBB"],"c":99}'}

proc json_set_test {testnum x result} {
  do_execsql_test json105-4.$testnum "SELECT quote(json_set(j,$x)) FROM t1" $result
}
json_set_test 10 {'$.b[#]','AAA'} {'{"a":1,"b":[1,[2,3],4,"AAA"],"c":99}'}
json_set_test 20 {'$.b[1][#]','AAA'} {'{"a":1,"b":[1,[2,3,"AAA"],4],"c":99}'}
json_set_test 30 {'$.b[1][#]','AAA','$.b[#]','BBB'} \
     {'{"a":1,"b":[1,[2,3,"AAA"],4,"BBB"],"c":99}'}
json_set_test 40 {'$.b[#]','AAA','$.b[#]','BBB'} \
     {'{"a":1,"b":[1,[2,3],4,"AAA","BBB"],"c":99}'}
json_set_test 50 {'$.b[#-1]','AAA'} {'{"a":1,"b":[1,[2,3],"AAA"],"c":99}'}
json_set_test 60 {'$.b[1][#-1]','AAA'} {'{"a":1,"b":[1,[2,"AAA"],4],"c":99}'}
json_set_test 70 {'$.b[1][#-1]','AAA','$.b[#-1]','BBB'} \
     {'{"a":1,"b":[1,[2,"AAA"],"BBB"],"c":99}'}
json_set_test 80 {'$.b[#-1]','AAA','$.b[#-1]','BBB'} \
     {'{"a":1,"b":[1,[2,3],"BBB"],"c":99}'}

proc json_replace_test {testnum x result} {
  do_execsql_test json105-5.$testnum "SELECT quote(json_replace(j,$x)) FROM t1" $result
}
json_replace_test 10 {'$.b[#]','AAA'} {'{"a":1,"b":[1,[2,3],4],"c":99}'}
json_replace_test 20 {'$.b[1][#]','AAA'} {'{"a":1,"b":[1,[2,3],4],"c":99}'}
json_replace_test 30 {'$.b[1][#]','AAA','$.b[#]','BBB'} \
     {'{"a":1,"b":[1,[2,3],4],"c":99}'}
json_replace_test 40 {'$.b[#]','AAA','$.b[#]','BBB'} \
     {'{"a":1,"b":[1,[2,3],4],"c":99}'}
json_replace_test 50 {'$.b[#-1]','AAA'} {'{"a":1,"b":[1,[2,3],"AAA"],"c":99}'}
json_replace_test 60 {'$.b[1][#-1]','AAA'} {'{"a":1,"b":[1,[2,"AAA"],4],"c":99}'}
json_replace_test 70 {'$.b[1][#-1]','AAA','$.b[#-1]','BBB'} \
     {'{"a":1,"b":[1,[2,"AAA"],"BBB"],"c":99}'}
json_replace_test 80 {'$.b[#-1]','AAA','$.b[#-1]','BBB'} \
     {'{"a":1,"b":[1,[2,3],"BBB"],"c":99}'}

do_catchsql_test json105-6.10 {
  SELECT json_extract(j, '$.b[#-]') FROM t1;
} {1 {JSON path error near '[#-]'}}
do_catchsql_test json105-6.20 {
  SELECT json_extract(j, '$.b[#9]') FROM t1;
} {1 {JSON path error near '[#9]'}}
do_catchsql_test json105-6.30 {
  SELECT json_extract(j, '$.b[#+2]') FROM t1;
} {1 {JSON path error near '[#+2]'}}
do_catchsql_test json105-6.40 {
  SELECT json_extract(j, '$.b[#-1') FROM t1;
} {1 {JSON path error near '[#-1'}}
do_catchsql_test json105-6.50 {
  SELECT json_extract(j, '$.b[#-1x]') FROM t1;
} {1 {JSON path error near '[#-1x]'}}

finish_test

Changes to test/kvtest.c.

903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
903
904
905
906
907
908
909

910
911
912
913
914
915
916
917







-
+







      continue;
    }
    fatalError("unknown option: \"%s\"", argv[i]);
  }
  if( eType==PATH_DB ){
    /* Recover any prior crashes prior to starting the timer */
    sqlite3_open(zDb, &db);
    sqlite3_exec(db, "SELECT rowid FROM sqlite_schema LIMIT 1", 0, 0, 0);
    sqlite3_exec(db, "SELECT rowid FROM sqlite_master LIMIT 1", 0, 0, 0);
    sqlite3_close(db);
    db = 0;
  }
  tmStart = timeOfDay();
  if( eType==PATH_DB ){
    char *zSql;
    rc = sqlite3_open(zDb, &db);

Changes to test/like.test.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26







-







# in particular the optimizations that occur to help those operators
# run faster.
#
# $Id: like.test,v 1.13 2009/06/07 23:45:11 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix like

# Create some sample data to work with.
#
do_test like-1.0 {
  execsql {
    CREATE TABLE t1(x TEXT);
  }
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
1090
1091
1092
1093
1094
1095
1096
1097










































1098








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';
} {22}
do_execsql_test like-15.121 {
  EXPLAIN QUERY PLAN
  SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';
} {/SEARCH/}
}

#-------------------------------------------------------------------------
# Tests for ticket [b1d8c79314].
#
reset_db
do_execsql_test 16.0 {
  CREATE TABLE t1(a INTEGER COLLATE NOCASE);
  CREATE INDEX i1 ON t1(a);
  INSERT INTO t1 VALUES(' 1x');
  INSERT INTO t1 VALUES(' 1-');
}
do_execsql_test 16.1 {
  SELECT * FROM t1 WHERE a LIKE ' 1%';
} {{ 1x} { 1-}}
do_execsql_test 16.2 {
  SELECT * FROM t1 WHERE a LIKE ' 1-';
} {{ 1-}}

# 2020-03-19
# The ESCAPE clause on LIKE takes precedence over wildcards
#
do_execsql_test 17.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT);
  INSERT INTO t1 VALUES
    (1,'abcde'),
    (2,'abc_'),
    (3,'abc__'),
    (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/like3.test.

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
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








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-











-
+

















-
+












-
+



-



} {/abc}
do_eqp_test like3-5.211 {
  SELECT x FROM t5b WHERE x GLOB '/a*';
} {
  QUERY PLAN
  `--SEARCH TABLE t5b USING COVERING INDEX sqlite_autoindex_t5b_1 (x>? AND x<?)
}

# 2019-05-01
# another case of the above reported on the mailing list by Manuel Rigger.
#
do_execsql_test like3-5.300 {
  CREATE TABLE t5c (c0 REAL);
  CREATE INDEX t5c_0 ON t5c(c0 COLLATE NOCASE);
  INSERT INTO t5c(rowid, c0) VALUES (99,'+/');
  SELECT * FROM t5c WHERE (c0 LIKE '+/');
} {+/}

# 2019-05-08
# Yet another case for the above from Manuel Rigger.
#
do_execsql_test like3-5.400 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 INT UNIQUE COLLATE NOCASE);
  INSERT INTO t0(c0) VALUES ('./');
  SELECT * FROM t0 WHERE t0.c0 LIKE './';
} {./}

# 2019-06-14
# Ticket https://www.sqlite.org/src/info/ce8717f0885af975
do_execsql_test like3-5.410 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 INT UNIQUE COLLATE NOCASE);
  INSERT INTO t0(c0) VALUES ('.1%');
  SELECT * FROM t0 WHERE t0.c0 LIKE '.1%';
} {.1%}

# 2019-09-03
# Ticket https://www.sqlite.org/src/info/0f0428096f
do_execsql_test like3-5.420 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 UNIQUE);
  INSERT INTO t0(c0) VALUES(-1);
  SELECT * FROM t0 WHERE t0.c0 GLOB '-*';
} {-1}
do_execsql_test like3-5.421 {
  SELECT t0.c0 GLOB '-*' FROM t0;
} {1}



# 2019-02-27
# Verify that the LIKE optimization works with an ESCAPE clause when
# using PRAGMA case_sensitive_like=ON.
#
ifcapable !icu {
do_execsql_test like3-6.100 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(path TEXT COLLATE nocase PRIMARY KEY,a,b,c) WITHOUT ROWID;
}
do_eqp_test like3-6.110 {
  SELECT * FROM t1 WHERE path LIKE 'a%';
} {
  QUERY PLAN
  `--SEARCH TABLE t1 USING PRIMARY KEY (path>? AND path<?)
}
do_eqp_test like3-6.120 {
  SELECT * FROM t1 WHERE path LIKE 'a%' ESCAPE 'x';
  SELECT * FROM t1 WHERE path LIKE 'a%' ESCAPE '_';
} {
  QUERY PLAN
  `--SEARCH TABLE t1 USING PRIMARY KEY (path>? AND path<?)
}
do_execsql_test like3-6.200 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(path TEXT,x,y,z);
  CREATE INDEX t2path ON t2(path COLLATE nocase);
  CREATE INDEX t2path2 ON t2(path);
}
do_eqp_test like3-6.210 {
  SELECT * FROM t2 WHERE path LIKE 'a%';
} {
  QUERY PLAN
  `--SEARCH TABLE t2 USING INDEX t2path (path>? AND path<?)
}
do_eqp_test like3-6.220 {
  SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '\';
  SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '_';
} {
  QUERY PLAN
  `--SEARCH TABLE t2 USING INDEX t2path (path>? AND path<?)
}
db eval {PRAGMA case_sensitive_like=ON}
do_eqp_test like3-6.230 {
  SELECT * FROM t2 WHERE path LIKE 'a%';
} {
  QUERY PLAN
  `--SEARCH TABLE t2 USING INDEX t2path2 (path>? AND path<?)
}
do_eqp_test like3-6.240 {
  SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '\';
  SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '_';
} {
  QUERY PLAN
  `--SEARCH TABLE t2 USING INDEX t2path2 (path>? AND path<?)
}
}

finish_test

Changes to test/limit.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
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
} {}

# 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

Changes to test/mallocA.test.

91
92
93
94
95
96
97


















98
99
100
101
102
103
104
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







} -test {
  faultsim_test_result [list 0 2]
}
do_faultsim_test 6.2 -faults oom* -body {
  execsql { SELECT rowid FROM t1 WHERE a='abc' AND b<'y' }
} -test {
  faultsim_test_result [list 0 {1 2}]
}
ifcapable stat3 {
  do_test 6.3-prep {
    execsql {
      PRAGMA writable_schema = 1;
      CREATE TABLE sqlite_stat4 AS 
      SELECT tbl, idx, neq, nlt, ndlt, sqlite_record(sample) AS sample 
      FROM sqlite_stat3;
    }
  } {}
  do_faultsim_test 6.3 -faults oom* -body {
    execsql { 
      ANALYZE sqlite_master;
      SELECT rowid FROM t1 WHERE a='abc' AND b<'y';
    }
  } -test {
    faultsim_test_result [list 0 {1 2}]
  }
}

do_execsql_test 7.0 {
  PRAGMA cache_size = 5;
}
do_faultsim_test 7 -faults oom-trans* -prep {
} -body {

Changes to test/minmax2.test.

17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32







-

+







#
# $Id: minmax2.test,v 1.2 2008/01/05 17:39:30 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test minmax2-1.0 {
  sqlite3_db_config db LEGACY_FILE_FORMAT 0
  execsql {
    PRAGMA legacy_file_format=0;
    BEGIN;
    CREATE TABLE t1(x, y);
    INSERT INTO t1 VALUES(1,1);
    INSERT INTO t1 VALUES(2,2);
    INSERT INTO t1 VALUES(3,2);
    INSERT INTO t1 VALUES(4,3);
    INSERT INTO t1 VALUES(5,3);

Changes to test/minmax4.test.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
15
16
17
18
19
20
21

22
23
24
25
26
27
28







-







#
# Demonstration that the value returned for p is on the same row as 
# the maximum q.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix minmax4

ifcapable !compound {
  finish_test
  return
}

do_test minmax4-1.1 {
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
144
145
146
147
148
149
150











151










152































































153







-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

} {1 2 1 4 4 2 3 3 5 5}
do_test minmax4-2.7 {
  db eval {
    SELECT a, min(b), b, min(c), c FROM t2 GROUP BY a ORDER BY a;
  }
} {1 1 {} 2 2 2 3 3 5 5}

#-------------------------------------------------------------------------
foreach {tn sql} {
  1 { CREATE INDEX i1 ON t1(a) }
  2 { CREATE INDEX i1 ON t1(a DESC) }
  3 { }
} {
  reset_db
  do_execsql_test 3.$tn.0 {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(NULL, 1);
  }

  execsql $sql
  do_execsql_test 3.$tn.1 {
    SELECT min(a), b FROM t1;
  } {{} 1}
  do_execsql_test 3.$tn.2 {
    SELECT min(a), b FROM t1 WHERE a<50;
  } {{} {}}
  do_execsql_test 3.$tn.3 {
    INSERT INTO t1 VALUES(2, 2);
  }

  do_execsql_test 3.$tn.4 {
    SELECT min(a), b FROM t1;
  } {2 2}
  do_execsql_test 3.$tn.5 {
    SELECT min(a), b FROM t1 WHERE a<50;
  } {2 2}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE TABLE t0 (c0, c1);
  CREATE INDEX i0 ON t0(c1, c1 + 1 DESC);
  INSERT INTO t0(c0) VALUES (1);
}
do_execsql_test 4.1 {
  SELECT MIN(t0.c1), t0.c0 FROM t0 WHERE t0.c1 ISNULL; 
} {{} 1}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  CREATE TABLE t1 (a, b);
  INSERT INTO t1 VALUES(123, NULL);
  CREATE INDEX i1 ON t1(a, b DESC);
}
do_execsql_test 5.1 {
  SELECT MIN(a) FROM t1 WHERE a=123;
} {123}

#-------------------------------------------------------------------------
# Tests for ticket f8a7060ece.
#
reset_db
do_execsql_test 6.1.0 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(NULL, 1, 'x');
  CREATE INDEX i1 ON t1(a);
}
do_execsql_test 6.1.1 {
  SELECT min(a), b, c FROM t1 WHERE c='x';
} {{} 1 x}
do_execsql_test 6.1.2 {
  INSERT INTO t1 VALUES(1,    2, 'y');
} {}
do_execsql_test 6.1.3 {
  SELECT min(a), b, c FROM t1 WHERE c='x';
} {{} 1 x}

do_execsql_test 6.2.0 {
  CREATE TABLE t0(c0 UNIQUE, c1);
  INSERT INTO t0(c1) VALUES (0);
  INSERT INTO t0(c0) VALUES (0);
  CREATE VIEW v0(c0, c1) AS 
      SELECT t0.c1, t0.c0 FROM t0 WHERE CAST(t0.rowid AS INT) = 1;
}
do_execsql_test 6.2.1 {
  SELECT c0, c1 FROM v0;
} {0 {}}
do_execsql_test 6.2.2 {
  SELECT v0.c0, MIN(v0.c1) FROM v0;
} {0 {}}

finish_test

Changes to test/misc7.test.

451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469
470
471
451
452
453
454
455
456
457

458
459
460
461
462
463

464
465
466
467
468
469
470







-
+





-







    
    do_test misc7-17.4 {
      db close
      sqlite3 db test.db
      catchsql {
        SELECT count(*) FROM t3;
      } 
    } {1 {malformed database schema (t3) - invalid rootpage}}
    } {1 {database disk image is malformed}}
  }
}

# Ticket #2470
#
reset_db
do_test misc7-18.1 {
  execsql {
    CREATE TABLE table_1 (col_10);
    CREATE TABLE table_2 (
      col_1, col_2, col_3, col_4, col_5,
      col_6, col_7, col_8, col_9, col_10
    );

Changes to test/misc8.test.

128
129
130
131
132
133
134
135
136
137



138
139
140
141
128
129
130
131
132
133
134



135
136
137
138
139
140
141







-
-
-
+
+
+




do_execsql_test misc8-4.1 {
  PRAGMA database_list;
} {/0 main .* 2 aux2/}
dbconfig_maindbname_icecube db
do_execsql_test misc8-4.2 {
  SELECT name FROM icecube.sqlite_master;
} {t1}
do_test misc8-4.3 {
  regexp {0 icecube .* 2 aux2} [db eval {PRAGMA database_list}] 
} 1
do_execsql_test misc8-4.3 {
  PRAGMA database_list;
} {/0 icecube .* 2 aux2/}



finish_test

Changes to test/mutex1.test.

34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48







-
+







    incr var(total) $value
  }
}

#-------------------------------------------------------------------------
# Tests mutex1-1.* test that sqlite3_config() returns SQLITE_MISUSE if
# is called at the wrong time. And that the first time sqlite3_initialize
# is called it obtains the 'static_main' mutex 3 times and a recursive
# is called it obtains the 'static_master' mutex 3 times and a recursive
# mutex (sqlite3Config.pInitMutex) twice. Subsequent calls are no-ops
# that do not require any mutexes.
#
do_test mutex1-1.0 {
  install_mutex_counters 1
} {SQLITE_MISUSE}

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
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







-
+










-
+
















-
+





-
+








do_test mutex1-1.6 {
  sqlite3_initialize
} {SQLITE_OK}

do_test mutex1-1.7 {
  mutex_counters counters
  # list $counters(total) $counters(static_main)
  # list $counters(total) $counters(static_master)
  expr {$counters(total)>0}
} {1}

do_test mutex1-1.8 {
  clear_mutex_counters
  sqlite3_initialize
} {SQLITE_OK}

do_test mutex1-1.9 {
  mutex_counters counters
  list $counters(total) $counters(static_main)
  list $counters(total) $counters(static_master)
} {0 0}

#-------------------------------------------------------------------------
# Tests mutex1-2.* test the three thread-safety related modes that
# can be selected using sqlite3_config:
#
#   * Serialized mode,
#   * Multi-threaded mode,
#   * Single-threaded mode.
#
ifcapable threadsafe1&&shared_cache {
  set enable_shared_cache [sqlite3_enable_shared_cache 1]
  foreach {mode mutexes} {
    singlethread {}
    multithread  {
      fast static_app1 static_app2 static_app3
      static_lru static_main static_mem static_open
      static_lru static_master static_mem static_open
      static_prng static_pmem static_vfs1 static_vfs2
      static_vfs3
    }
    serialized  {
      fast recursive static_app1 static_app2
      static_app3 static_lru static_main static_mem
      static_app3 static_lru static_master static_mem
      static_open static_prng static_pmem static_vfs1
      static_vfs2 static_vfs3
    }
  } {

    do_test mutex1.2.$mode.1 {
      catch {db close}

Changes to test/normalize.test.

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
343
344
345
346
347
348
349






























350
351
352
353
354
355
356







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  0x2
  {0 {SELECT x FROM t1 WHERE x=?;}}

  760
  {SELECT x FROM t1 WHERE x IN ([x] IS NOT NULL, NULL, 1, 'a', "b", x'00');}
  0x2
  {0 {SELECT x FROM t1 WHERE x IN(x IS NOT NULL,?,?,?,b,?);}}

  800
  {ATTACH "normalize800.db" AS somefile;}
  0x2
  {0 {ATTACH"normalize800.db"AS somefile;}}

  810
  {ATTACH DATABASE "normalize810.db" AS somefile;}
  0x2
  {0 {ATTACH DATABASE"normalize810.db"AS somefile;}}

  900
  {INSERT INTO t1 (x) VALUES("sl1"), (1), ("sl2"), ('i');}
  0x2
  {0 {INSERT INTO t1(x)VALUES(?),(?),(?),(?);}}

  910
  {UPDATE t1 SET x = "sl1" WHERE x IN (1, "sl2", 'i');}
  0x2
  {0 {UPDATE t1 SET x=?WHERE x IN(?,?,?);}}

  920
  {UPDATE t1 SET x = "y" WHERE x IN (1, "sl1", 'i');}
  0x2
  {0 {UPDATE t1 SET x=y WHERE x IN(?,?,?);}}

  930
  {DELETE FROM t1 WHERE x IN (1, "sl1", 'i');}
  0x2
  {0 {DELETE FROM t1 WHERE x IN(?,?,?);}}
} {
  do_test $tnum {
    set code [catch {
      set STMT [sqlite3_prepare_v3 $DB $sql -1 $flags TAIL]
      sqlite3_normalized_sql $STMT
    } res]
    if {[info exists STMT]} {

Deleted 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
102
103
104
105
106
107
108
109
110
111
112
113

















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 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;
}



#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t0(c0 PRIMARY KEY);
  INSERT INTO t0(c0) VALUES (0);
}
do_execsql_test 3.1 {
  SELECT * FROM t0 WHERE ((c0 NOT NULL) AND 1) OR (c0 == NULL);
} {0}

finish_test

Deleted 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/null.test.

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
292
293
294
295
296
297
298







299
300







-
-
-
-
-
-
-


  SELECT * FROM t5 WHERE a = 1 AND b IS NULL;
} {1 {} one 1 {} i}

do_execsql_test null-9.3 {
  SELECT * FROM t5 WHERE a IS NULL AND b = 'x';
} {{} x two {} x ii}

# 2020-09-30 ticket 5c4e7aa793943803
reset_db
do_execsql_test null-10.1 {
  CREATE TABLE t0(c0 PRIMARY KEY DESC);
  INSERT INTO t0(c0) VALUES (0);
  SELECT * FROM t0 WHERE t0.c0 > NULL;
} {}

finish_test

Deleted test/nulls1.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























































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 August 10
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix nulls1

do_execsql_test 1.0 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a INTEGER);
  INSERT INTO t3 VALUES(NULL), (10), (30), (20), (NULL);
} {}

for {set a 0} {$a < 3} {incr a} {
  foreach {tn limit} {
    1 ""
    2 "LIMIT 10"
  } {
    do_execsql_test 1.$a.$tn.1 "
      SELECT a FROM t3 ORDER BY a nULLS FIRST $limit
    " {{}   {}   10   20   30}
    
    do_execsql_test 1.$a.$tn.2 "
      SELECT a FROM t3 ORDER BY a nULLS LAST $limit
    " {10   20   30   {}   {}}
    
    do_execsql_test 1.$a.$tn.3 "
      SELECT a FROM t3 ORDER BY a DESC nULLS FIRST $limit
    " {{}   {}   30   20   10}
    
    do_execsql_test 1.$a.$tn.4 "
      SELECT a FROM t3 ORDER BY a DESC nULLS LAST $limit
    " {30   20   10   {}   {}}
  }

  switch $a {
    0 {
      execsql { CREATE INDEX i1 ON t3(a) }
    }
    1 {
      execsql { DROP INDEX i1 ; CREATE INDEX i1 ON t3(a DESC) }
    }
  }
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t2(a, b, c);
  CREATE INDEX i2 ON t2(a, b);
  INSERT INTO t2 VALUES(1, 1, 1);
  INSERT INTO t2 VALUES(1, NULL, 2);
  INSERT INTO t2 VALUES(1, NULL, 3);
  INSERT INTO t2 VALUES(1, 4, 4);
}

do_execsql_test 2.1 {
  SELECT * FROM t2 WHERE a=1 ORDER BY b NULLS LAST
} {
  1 1 1    1 4 4   1 {} 2   1 {} 3
}

do_execsql_test 2.2 {
  SELECT * FROM t2 WHERE a=1 ORDER BY b DESC NULLS FIRST
} {
  1 {} 3
  1 {} 2     
  1 4 4     
  1 1 1
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t1(a, b, c, d, UNIQUE (b));
}
foreach {tn sql err}  {
  1 { CREATE INDEX i1 ON t1(a ASC NULLS LAST) }           LAST
  2 { CREATE INDEX i1 ON t1(a ASC NULLS FIRST) }          FIRST
  3 { CREATE INDEX i1 ON t1(a, b ASC NULLS LAST) }        LAST
  4 { CREATE INDEX i1 ON t1(a, b ASC NULLS FIRST) }       FIRST
  5 { CREATE INDEX i1 ON t1(a DESC NULLS LAST) }          LAST
  6 { CREATE INDEX i1 ON t1(a DESC NULLS FIRST) }         FIRST
  7 { CREATE INDEX i1 ON t1(a, b DESC NULLS LAST) }       LAST
  8 { CREATE INDEX i1 ON t1(a, b DESC NULLS FIRST) }      FIRST
  9  { CREATE TABLE t2(a, b, PRIMARY KEY(a DESC, b NULLS FIRST)) } FIRST
  10 { CREATE TABLE t2(a, b, UNIQUE(a DESC NULLS FIRST, b)) }      FIRST
  11 { INSERT INTO t1 VALUES(1, 2, 3, 4)
          ON CONFLICT (b DESC NULLS LAST) DO UPDATE SET a = a+1 } LAST
  12 {
    CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
      INSERT INTO t1 VALUES(1, 2, 3, 4)
      ON CONFLICT (b DESC NULLS FIRST) DO UPDATE SET a = a+1;
    END
  } FIRST
} {
  do_catchsql_test 3.1.$tn $sql "1 {unsupported use of NULLS $err}"
}

do_execsql_test 3.2 {
  CREATE TABLE first(nulls, last);
  INSERT INTO first(last, nulls) VALUES(100,200), (300,400), (200,300);
  SELECT * FROM first ORDER BY nulls;
} {
  200 100
  300 200
  400 300
}

#-------------------------------------------------------------------------
#
ifcapable vtab {
  register_echo_module db
  do_execsql_test 4.0 {
    CREATE TABLE tx(a INTEGER PRIMARY KEY, b, c);
    CREATE INDEX i1 ON tx(b);
    INSERT INTO tx VALUES(1, 1, 1);
    INSERT INTO tx VALUES(2, NULL, 2);
    INSERT INTO tx VALUES(3, 3, 3);
    INSERT INTO tx VALUES(4, NULL, 4);
    INSERT INTO tx VALUES(5, 5, 5);
    CREATE VIRTUAL TABLE te USING echo(tx);
  }

  do_execsql_test 4.1 {
    SELECT * FROM tx ORDER BY b NULLS FIRST;
  } {2 {} 2  4 {} 4  1 1 1  3 3 3  5 5 5}
  do_execsql_test 4.2 {
    SELECT * FROM te ORDER BY b NULLS FIRST;
  } {2 {} 2  4 {} 4  1 1 1  3 3 3  5 5 5}

  do_execsql_test 4.3 {
    SELECT * FROM tx ORDER BY b NULLS LAST;
  } {1 1 1  3 3 3  5 5 5  2 {} 2  4 {} 4}
  do_execsql_test 4.4 {
    SELECT * FROM te ORDER BY b NULLS LAST;
  } {1 1 1  3 3 3  5 5 5  2 {} 2  4 {} 4}
}

#-------------------------------------------------------------------------
#
do_execsql_test 5.0 {
  CREATE TABLE t4(a, b, c);
  INSERT INTO t4 VALUES(1, 1, 11);
  INSERT INTO t4 VALUES(1, 2, 12);
  INSERT INTO t4 VALUES(1, NULL, 1);

  INSERT INTO t4 VALUES(2, NULL, 1);
  INSERT INTO t4 VALUES(2, 2, 12);
  INSERT INTO t4 VALUES(2, 1, 11);

  INSERT INTO t4 VALUES(3, NULL, 1);
  INSERT INTO t4 VALUES(3, 2, 12);
  INSERT INTO t4 VALUES(3, NULL, 3);
}

do_execsql_test 5.1 {
  SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST
} {
  1 1 11   1 2 12   1 {} 1   
  2 1 11   2 2 12   2 {} 1 
  3 2 12   3 {} 1   3 {} 3
}
do_execsql_test 5.2 {
  CREATE INDEX t4ab ON t4(a, b);
  SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST
} {
  1 1 11   1 2 12   1 {} 1   
  2 1 11   2 2 12   2 {} 1 
  3 2 12   3 {} 1   3 {} 3
}
do_eqp_test 5.3 {
  SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST
} {
  QUERY PLAN
  `--SEARCH TABLE t4 USING INDEX t4ab (a=?)
}

do_execsql_test 5.4 {
  SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a DESC, b DESC NULLS FIRST
} {
  3 {} 3   3 {} 1   3 2 12   
  2 {} 1   2 2 12   2 1 11   
  1 {} 1   1 2 12   1 1 11   
}
do_eqp_test 5.5 {
  SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a DESC, b DESC NULLS FIRST
} {
  QUERY PLAN
  `--SEARCH TABLE t4 USING INDEX t4ab (a=?)
}

#-------------------------------------------------------------------------
#
do_execsql_test 6.0 {
  CREATE TABLE t5(a, b, c);
  WITH s(i) AS (
    VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<200
  ) 
  INSERT INTO t5 SELECT i%2, CASE WHEN (i%10)==0 THEN NULL ELSE i END, i FROM s;
}

set res1 [db eval { SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c }]
set res2 [db eval { 
  SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC 
}]

do_execsql_test 6.1.1 {
  CREATE INDEX t5ab ON t5(a, b, c);
  SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c;
} $res1
do_eqp_test 6.1.2 {
  SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c;
} {
  QUERY PLAN
  `--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?)
}
do_execsql_test 6.2.1 {
  SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC 
} $res2
do_eqp_test 6.2.2 {
  SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC 
} {
  QUERY PLAN
  `--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?)
}

#-------------------------------------------------------------------------
do_execsql_test 7.0 {
  CREATE TABLE t71(a, b, c);
  CREATE INDEX t71abc ON t71(a, b, c);

  SELECT * FROM t71 WHERE a=1 AND b=2 ORDER BY c NULLS LAST;
  SELECT * FROM t71 WHERE a=1 AND b=2 ORDER BY c DESC NULLS FIRST;

  SELECT * FROM t71 ORDER BY a NULLS LAST;
  SELECT * FROM t71 ORDER BY a DESC NULLS FIRST;
}

# 2019-12-18 gramfuzz1 find
# NULLS LAST not allows on an INTEGER PRIMARY KEY.
#
do_catchsql_test 8.0 {
  CREATE TABLE t80(a, b INTEGER, PRIMARY KEY(b NULLS LAST)) WITHOUT ROWID;
} {1 {unsupported use of NULLS LAST}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 9.0 {
  CREATE TABLE v0 (c1, c2, c3);
  CREATE INDEX v3 ON v0 (c1, c2, c3);
}
do_execsql_test 9.1 {
  ANALYZE sqlite_master;
  INSERT INTO sqlite_stat1 VALUES('v0','v3','648 324 81');
  ANALYZE sqlite_master;
}

do_execsql_test 9.2 {
  INSERT INTO v0 VALUES
      (1, 10, 'b'),
      (1, 10, 'd'),
      (1, 10, NULL),
      (2, 10, 'a'),
      (2, 10, NULL),
      (1, 10, 'c'),
      (2, 10, 'b'),
      (1, 10, 'a'),
      (1, 10, NULL),
      (2, 10, NULL),
      (2, 10, 'd'),
      (2, 10, 'c');
}

do_execsql_test 9.3 {
  SELECT c1, c2, ifnull(c3, 'NULL') FROM v0 
  WHERE c2=10 ORDER BY c1, c3 NULLS LAST
} {
  1 10 a 1 10 b 1 10 c 1 10 d 1 10 NULL 1 10 NULL
  2 10 a 2 10 b 2 10 c 2 10 d 2 10 NULL 2 10 NULL
}

do_eqp_test 9.4 {
  SELECT c1, c2, ifnull(c3, 'NULL') FROM v0 
  WHERE c2=10 ORDER BY c1, c3 NULLS LAST
} {SEARCH TABLE v0 USING COVERING INDEX v3 (ANY(c1) AND c2=?)}


# 2020-03-01 ticket e12a0ae526bb51c7
# NULLS LAST on a LEFT JOIN
#
reset_db
do_execsql_test 10.10 {
  CREATE TABLE t1(x);
  INSERT INTO t1(x) VALUES('X');
  CREATE TABLE t2(c, d);
  CREATE INDEX t2dc ON t2(d, c);
  SELECT c FROM t1 LEFT JOIN t2 ON d=NULL ORDER BY d, c NULLS LAST;
} {{}}
do_execsql_test 10.20 {
  INSERT INTO t2(c,d) VALUES(5,'X'),(6,'Y'),(7,'Z'),(3,'A'),(4,'B');
  SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d, c NULLS LAST;
} {5}
do_execsql_test 10.30 {
  UPDATE t2 SET d='X';
  UPDATE t2 SET c=NULL WHERE c=6;
  SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d NULLS FIRST, c NULLS FIRST;
} {{} 3 4 5 7}
do_execsql_test 10.40 {
  SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d NULLS LAST, c NULLS LAST;
} {3 4 5 7 {}}
do_execsql_test 10.41 {
  SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY c NULLS LAST;
} {3 4 5 7 {}}
do_execsql_test 10.42 {
  SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY +d NULLS LAST, +c NULLS LAST;
} {3 4 5 7 {}}
do_execsql_test 10.50 {
  INSERT INTO t1(x) VALUES(NULL),('Y');
  SELECT x, c, d, '|' FROM t1 LEFT JOIN t2 ON d=x
   ORDER BY d NULLS LAST, c NULLS LAST;
} {X 3 X | X 4 X | X 5 X | X 7 X | X {} X | {} {} {} | Y {} {} |}
do_execsql_test 10.51 {
  SELECT x, c, d, '|' FROM t1 LEFT JOIN t2 ON d=x
   ORDER BY +d NULLS LAST, +c NULLS LAST;
} {X 3 X | X 4 X | X 5 X | X 7 X | X {} X | {} {} {} | Y {} {} |}





finish_test

Changes to test/optfuzz-db01.c.

941
942
943
944
945
946
947

941
942
943
944
945
946
947
948







+
  41, 32, 85, 78, 73, 79, 78, 32, 65, 76, 76, 32, 83, 69, 76, 69, 67, 84, 32,
 120, 43, 49, 32, 70, 82, 79, 77, 32, 99, 48, 32, 87, 72, 69, 82, 69, 32,120,
  60, 57, 41, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,120, 44, 32, 98, 44, 32,
  99, 44, 32,100, 44, 32,101, 32, 70, 82, 79, 77, 32, 99, 48, 32, 74, 79, 73,
  78, 32,116, 49, 32, 79, 78, 32, 40,116, 49, 46, 97, 61, 53, 48, 45, 99, 48,
  46,120, 41,
};

Changes to test/orderby1.test.

554
555
556
557
558
559
560
561
562
563
564
565
566
554
555
556
557
558
559
560




561
562







-
-
-
-


do_execsql_test 10.0 {
  CREATE TABLE t10(a,b);
  INSERT INTO t10 VALUES(1,2),(8,9),(3,4),(5,4),(0,7);
  CREATE INDEX t10b ON t10(b);
  SELECT b, rowid, '^' FROM t10 ORDER BY b, a LIMIT 4;
} {2 1 ^ 4 3 ^ 4 4 ^ 7 5 ^}

do_catchsql_test 11.0 {
  VALUES(2) EXCEPT SELECT '' ORDER BY abc
} {1 {1st ORDER BY term does not match any column in the result set}}


finish_test

Changes to test/orderby5.test.

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
122
123
124
125
126
127
128

























































129
130







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  DROP TABLE t3;
  CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c, d, e, f) WITHOUT rowid;
  CREATE INDEX t3bcde ON t3(b, c, d, e);
  EXPLAIN QUERY PLAN
  SELECT a FROM t3 WHERE b=2 AND c=3 ORDER BY d DESC, e DESC, b, c, a DESC;
} {~/B-TREE/}

#-------------------------------------------------------------------------
do_execsql_test 4.1.0 {
  CREATE TABLE t4(b COLLATE nocase);
  INSERT INTO t4 VALUES('abc');
  INSERT INTO t4 VALUES('ABC');
  INSERT INTO t4 VALUES('aBC');
}
do_execsql_test 4.1.1 {
  SELECT * FROM t4 ORDER BY b COLLATE binary
} {ABC aBC abc}
do_execsql_test 4.1.2 {
  SELECT * FROM t4 WHERE b='abc' ORDER BY b COLLATE binary
} {ABC aBC abc}

do_execsql_test 4.2.1 {
  CREATE TABLE Records(typeID INTEGER, key TEXT COLLATE nocase, value TEXT);
  CREATE INDEX RecordsIndex ON Records(typeID, key, value);
}
do_execsql_test 4.2.2 {
  explain query plan
  SELECT typeID, key, value FROM Records 
  WHERE typeID = 2 AND key = 'x' 
  ORDER BY key, value;
} {~/TEMP B-TREE/}
do_execsql_test 4.2.3 {
  explain query plan
  SELECT typeID, key, value FROM Records 
  WHERE typeID = 2 AND (key = 'x' COLLATE binary)
  ORDER BY key, value;
} {~/TEMP B-TREE/}
do_execsql_test 4.2.4 {
  explain query plan
  SELECT typeID, key, value FROM Records 
  WHERE typeID = 2 
  ORDER BY key, value;
} {~/TEMP B-TREE/}

db collate hello [list string match]
do_execsql_test 4.3.1 {
  CREATE TABLE t5(a INTEGER PRIMARY KEY, b COLLATE hello, c, d);
}
db close
sqlite3 db test.db
do_catchsql_test 4.3.2 {
  SELECT a FROM t5 WHERE b='def' ORDER BY b;
} {1 {no such collation sequence: hello}}

# 2020-02-13 ticket 41c1456a6e61c0e7
do_execsql_test 4.4.0 {
  DROP TABLE t1;
  CREATE TABLE t1(a);
  DROP TABLE t2;
  CREATE TABLE t2(b INTEGER PRIMARY KEY, c INT);
  SELECT DISTINCT *
    FROM t1 LEFT JOIN t2 ON b=c AND b=(SELECT a FROM t1)
   WHERE c>10;
} {}

finish_test

Deleted test/orderbyA.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



















































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-09-21
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# Specifically, it tests cases where the expressions in a GROUP BY 
# clause are the same as those in the ORDER BY clause.
# 

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix orderbyA

proc do_sortcount_test {tn sql cnt res} {
  set eqp [execsql "EXPLAIN QUERY PLAN $sql"]
  set rcnt [regexp -all {USE TEMP} $eqp]
  uplevel [list do_test         $tn.1 [list set {} $rcnt] $cnt]
  uplevel [list do_execsql_test $tn.2 $sql $res]
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES('one',   1, 11);
  INSERT INTO t1 VALUES('three', 7, 11);
  INSERT INTO t1 VALUES('one',   2, 11);
  INSERT INTO t1 VALUES('one',   3, 11);
  INSERT INTO t1 VALUES('two',   4, 11);
  INSERT INTO t1 VALUES('two',   6, 11);
  INSERT INTO t1 VALUES('three', 8, 11);
  INSERT INTO t1 VALUES('two',   5, 11);
  INSERT INTO t1 VALUES('three', 9, 11);
}

foreach {tn idx} {
  1 {}
  2 {CREATE INDEX i1 ON t1(a)}
  3 {CREATE INDEX i1 ON t1(a DESC)}
} {
  execsql { DROP INDEX IF EXISTS i1 }
  execsql $idx

  # $match is the number of temp-table sorts we expect if the GROUP BY
  # can use the same sort order as the ORDER BY. $nomatch is the number
  # of expected sorts if the GROUP BY and ORDER BY are not compatible.
  set match   1
  set nomatch 2
  if {$tn>=2} {
    set match   0
    set nomatch 1
  }

  do_sortcount_test 1.$tn.1.1 {
    SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a
  } $match {one 6 three 24 two 15}
  do_sortcount_test 1.$tn.1.2 {
    SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a DESC
  } $match {two 15 three 24 one 6}
  
  do_sortcount_test 1.$tn.2.1 {
    SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a||''
  } $nomatch {one 6 three 24 two 15}
  do_sortcount_test 1.$tn.2.2 {
    SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a||'' DESC
  } $nomatch {two 15 three 24 one 6}
  
  do_sortcount_test 1.$tn.3.1 {
    SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a NULLS LAST
  } $nomatch {one 6 three 24 two 15}
  do_sortcount_test 1.$tn.3.2 {
    SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a DESC NULLS FIRST
  } $nomatch {two 15 three 24 one 6}
}

#-------------------------------------------------------------------------
do_execsql_test 2.0 {
  CREATE TABLE t2(a, b, c);
  INSERT INTO t2 VALUES(1, 'one', 1);
  INSERT INTO t2 VALUES(1, 'two', 2);
  INSERT INTO t2 VALUES(1, 'one', 3);
  INSERT INTO t2 VALUES(1, 'two', 4);
  INSERT INTO t2 VALUES(1, 'one', 5);
  INSERT INTO t2 VALUES(1, 'two', 6);

  INSERT INTO t2 VALUES(2, 'one', 7);
  INSERT INTO t2 VALUES(2, 'two', 8);
  INSERT INTO t2 VALUES(2, 'one', 9);
  INSERT INTO t2 VALUES(2, 'two', 10);
  INSERT INTO t2 VALUES(2, 'one', 11);
  INSERT INTO t2 VALUES(2, 'two', 12);

  INSERT INTO t2 VALUES(NULL, 'one', 13);
  INSERT INTO t2 VALUES(NULL, 'two', 14);
  INSERT INTO t2 VALUES(NULL, 'one', 15);
  INSERT INTO t2 VALUES(NULL, 'two', 16);
  INSERT INTO t2 VALUES(NULL, 'one', 17);
  INSERT INTO t2 VALUES(NULL, 'two', 18);
}

foreach {tn idx} {
  1 {}

  2 { CREATE INDEX i2 ON t2(a, b)           }
  3 { CREATE INDEX i2 ON t2(a DESC, b DESC) }

  4 { CREATE INDEX i2 ON t2(a, b DESC)      }
  5 { CREATE INDEX i2 ON t2(a DESC, b)      }
} {
  execsql { DROP INDEX IF EXISTS i2 }
  execsql $idx


  set nSort [expr ($tn==2 || $tn==3) ? 0 : 1]
  do_sortcount_test 2.$tn.1.1 {
    SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b;
  } $nSort {{} one 45  {} two 48  1 one 9  1 two 12  2 one 27  2 two 30}
  do_sortcount_test 2.$tn.1.2 {
    SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b DESC;
  } $nSort {2 two 30  2 one 27  1 two 12  1 one 9  {} two 48  {} one 45}

  set nSort [expr ($tn==4 || $tn==5) ? 0 : 1]
  do_sortcount_test 2.$tn.2.1 {
    SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b DESC;
  } $nSort { {} two 48  {} one 45  1 two 12  1 one 9  2 two 30 2 one 27 }
  do_sortcount_test 2.$tn.2.2 {
    SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b;
  } $nSort { 2 one 27  2 two 30  1 one 9  1 two 12  {} one 45 {} two 48 }

  # ORDER BY can never piggyback on the GROUP BY sort if it uses 
  # non-standard NULLS behaviour.
  set nSort [expr $tn==1 ? 2 : 1]
  do_sortcount_test 2.$tn.3.1 {
    SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b DESC NULLS FIRST;
  } $nSort { {} two 48  {} one 45  1 two 12  1 one 9  2 two 30 2 one 27 }
  do_sortcount_test 2.$tn.3.2 {
    SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b NULLS LAST;
  } $nSort { 2 one 27  2 two 30  1 one 9  1 two 12  {} one 45 {} two 48 }
}


finish_test

Changes to test/oserror.test.

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
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







-
-
-


-
-
-
+
+
+
-
-
-
-
-
+
-
-
-
-
-

-
+
-
-
-
-
-
+
+
+
+
-







#
# The xOpen() method of the unix VFS calls getcwd() as well as open().
# Although this does not appear to be documented in the man page, on OSX
# a call to getcwd() may fail if there are no free file descriptors. So
# an error may be reported for either open() or getcwd() here.
#
if {![clang_sanitize_address]} {
  unset -nocomplain rc
  unset -nocomplain nOpen
  set nOpen 20000
  do_test 1.1.1 {
    set ::log [list]
    set ::rc [catch {
      for {set i 0} {$i < $::nOpen} {incr i} { sqlite3 dbh_$i test.db -readonly 1 }
    } msg]
    list [catch {
      for {set i 0} {$i < 20000} {incr i} { sqlite3 dbh_$i test.db -readonly 1 }
    } msg] $msg
    if {$::rc==0} {
      # Some system (ex: Debian) are able to create 20000+ file descriptiors
      # such systems will not fail here
      set x ok
    } elseif {$::rc==1 && $msg=="unable to open database file"} {
  } {1 {unable to open database file}}
      set x ok
    } else {
      set x [list $::rc $msg]
    }
  } {ok}
  do_test 1.1.2 {
    catch { for {set i 0} {$i < $::nOpen} {incr i} { dbh_$i close } }
    catch { for {set i 0} {$i < 20000} {incr i} { dbh_$i close } }
  } $::rc
  if {$rc} {
    do_re_test 1.1.3 { 
      lindex $::log 0 
    } {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - }
  } {1}
  do_re_test 1.1.3 { 
    lindex $::log 0 
  } {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - }
  }
}


# Test a failure in open() due to the path being a directory.
#
do_test 1.2.1 {
  file mkdir dir.db

Changes to test/ossfuzz.c.

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
151
152
153
154
155
156
157



158
159
160
161
162
163
164







-
-
-







#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 */
  sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, 25000);

  /* Limit total memory available to SQLite to 20MB */
  sqlite3_hard_heap_limit64(20000000);

  /* Set a limit on the maximum length of a string or BLOB.  Without this
  ** limit, fuzzers will invoke randomblob(N) for a large N, and the process
  ** will timeout trying to generate the huge blob */
  sqlite3_limit(cx.db, SQLITE_LIMIT_LENGTH, 50000);

  /* Bit 1 of the selector enables foreign key constraints */
  sqlite3_db_config(cx.db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc);

Changes to test/pager1.test.

272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286







-
+







    INSERT INTO t1 VALUES(1, randomblob(1500));
    INSERT INTO t1 VALUES(2, randomblob(1500));
    INSERT INTO t1 VALUES(3, randomblob(1500));
    SELECT * FROM counter;
} {3 0}
do_catchsql_test pager1-3.1.3 {
    INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1
} {1 {CHECK constraint failed: i<5}}
} {1 {CHECK constraint failed: counter}}
do_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0}
do_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3}
do_execsql_test pager1-3.6 { COMMIT } {}

foreach {tn sql tcl} {
  7  { PRAGMA synchronous = NORMAL ; PRAGMA temp_store = 0 } {
    testvfs tv -default 1
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
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







-














-







db2 close
do_test pager1-18.4 {
  hexio_write test.db [expr ($pgno-1)*1024] 90000000
  sqlite3 db2 test.db
  catchsql { SELECT length(x||'') FROM t2 } db2
} {1 {database disk image is malformed}}
db2 close
extra_schema_checks 0
do_test pager1-18.5 {
  sqlite3 db ""
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(a, b);
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage=5 WHERE tbl_name = 't1';
    PRAGMA writable_schema = 0;
    ALTER TABLE t1 RENAME TO x1;
  }
  catchsql { SELECT * FROM x1 }
} {1 {database disk image is malformed}}
db close
extra_schema_checks 1

do_test pager1-18.6 {
  faultsim_delete_and_reopen
  db func a_string a_string
  execsql {
    PRAGMA page_size = 1024;
    CREATE TABLE t1(x);

Changes to test/permutations.test.

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
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







-









-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
+
-
-







  vtab_err.test walslow.test walcrash.test walcrash3.test
  walthread.test rtree3.test indexfault.test securedel2.test
  sort3.test sort4.test fts4growth.test fts4growth2.test
  bigsort.test walprotocol.test mmap4.test fuzzer2.test
  walcrash2.test e_fkey.test backup.test

  fts4merge.test fts4merge2.test fts4merge4.test fts4check.test
  fts4merge5.test
  fts3cov.test fts3snippet.test fts3corrupt2.test fts3an.test
  fts3defer.test fts4langid.test fts3sort.test fts5unicode.test

  rtree4.test
}]
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
  set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
}
if {[info exists ::env(QUICKTEST_OMIT)]} {
  # If environment variable QUICKTEST_OMIT is set, it is a comma-separated
  # list of regular expressions to match against test file names in
  # the "allquicktests" set. Any matches are excluded. Only the filename
  # is matched, not any directory component of the path.
  set all [list]
  foreach a $allquicktests {
    set bIn 1
    foreach x [split $::env(QUICKTEST_OMIT) ,] {
  foreach x [split $::env(QUICKTEST_OMIT) ,] {
      if {[regexp $x [file tail $a]]} {
        set bIn 0
        break
      }
    }
    if {$bIn} {
      lappend all $a
    }
    regsub -all \\y$x\\y $allquicktests {} allquicktests
  }
  }
  set allquicktests $all
}

# If the TEST_FAILURE environment variable is set, it means that we what to
# deliberately provoke test failures in order to test the test infrastructure.
# Only the main.test module is needed for this.
#
if {[info exists ::env(TEST_FAILURE)]} {
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
166
167
168
169
170
171
172






173
174
175
176
177
178
179







-
-
-
-
-
-







  This test suite is the same as the "quick" tests, except that some files
  that test malloc and IO errors are omitted.
} -files [
  test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \
      *fts5corrupt* *fts5big* *fts5aj*
]

test_suite "shell" -prefix "" -description {
  Run tests of the command-line shell
} -files [
  test_set [glob $testdir/shell*.test]
]

test_suite "extraquick" -prefix "" -description {
  "Extra" quick test suite. Runs in a few minutes on a workstation.
  This test suite is the same as the "veryquick" tests, except that
  slower tests are omitted.
} -files [
  test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \
     wal3.test fts4merge* sort2.test mmap1.test walcrash* \
473
474
475
476
477
478
479
480
481


482
483
484
485
486
487
488
451
452
453
454
455
456
457


458
459
460
461
462
463
464
465
466







-
-
+
+







  walfault.test  walbak.test  journal2.test    tkt-9d68c883.test
} 

test_suite "coverage-analyze" -description {
  Coverage tests for file analyze.c.
} -files {
  analyze3.test analyze4.test analyze5.test analyze6.test
  analyze7.test analyze8.test analyze9.test
  analyze.test mallocA.test
  analyze7.test analyze8.test analyze9.test analyzeA.test
  analyze.test analyzeB.test mallocA.test
} 

test_suite "coverage-sorter" -description {
  Coverage tests for file vdbesort.c.
} -files {
  sort.test sortfault.test
} 
642
643
644
645
646
647
648
649

650
651
652
653
654
655
656
620
621
622
623
624
625
626

627
628
629
630
631
632
633
634







-
+







test_suite "utf16" -description {
  Run tests using UTF-16 databases
} -presql {
  pragma encoding = 'UTF-16'
} -files {
    alter.test alter3.test
    analyze.test analyze3.test analyze4.test analyze5.test analyze6.test
    analyze7.test analyze8.test analyze9.test
    analyze7.test analyze8.test analyze9.test analyzeA.test analyzeB.test
    auth.test bind.test blob.test capi2.test capi3.test collate1.test
    collate2.test collate3.test collate4.test collate5.test collate6.test
    conflict.test date.test delete.test expr.test fkey1.test func.test
    hook.test index.test insert2.test insert.test interrupt.test in.test
    intpkey.test ioerr.test join2.test join.test lastinsert.test
    laststmtchanges.test limit.test lock2.test lock.test main.test 
    memdb.test minmax.test misc1.test misc2.test misc3.test notnull.test
984
985
986
987
988
989
990
991

992
993
994
995
996
997
998
999
962
963
964
965
966
967
968

969

970
971
972
973
974
975
976







-
+
-







} -shutdown {
  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
  delete_db.test shmlock.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
1073
1035
1036
1037
1038
1039
1040
1041

1042

1043
1044
1045
1046
1047
1048
1049







-
+
-







} -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              \
    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 {
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1070
1071
1072
1073
1074
1075
1076










1077
1078
1079
1080
1081
1082
1083







-
-
-
-
-
-
-
-
-
-







  catch {db close}
  sqlite3_shutdown
  sqlite3_config_sorterref -1
  sqlite3_initialize
  autoinstall_test_functions
}

test_suite "maindbname" -prefix "" -description {
  Run the "veryquick" test suite with SQLITE_DBCONFIG_MAINDBNAME used to
  set the name of database 0 to "icecube".
} -files [
  test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \
      *fts5corrupt* *fts5big* *fts5aj*
] -dbconfig {
  dbconfig_maindbname_icecube $::dbhandle
}

# End of tests
#############################################################################

# run_tests NAME OPTIONS
#
# where available options are:  
#
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
1100
1101
1102
1103
1104
1105
1106











1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118







-
-
-
-
-
-
-
-
-
-
-

+


+







  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)
    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)

Changes to test/pg_common.tcl.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
14
15
16
17
18
19
20


21
22
23
24
25
26
27







-
-







package require Pgtcl

set db [pg_connect -conninfo "dbname=postgres user=postgres password=postgres"]
sqlite3 sqlite ""

proc execsql {sql} {

  set sql [string map {{WITHOUT ROWID} {}} $sql]

  set lSql [list]
  set frag ""
  while {[string length $sql]>0} {
    set i [string first ";" $sql]
    if {$i>=0} {
      append frag [string range $sql 0 $i]
      set sql [string range $sql $i+1 end]
68
69
70
71
72
73
74
75
76


77
78
79
80
81
82
83
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81







-
-
+
+








  set ret
}

proc execsql_test {tn sql} {
  set res [execsql $sql]
  set sql [string map {string_agg group_concat} $sql]
  # set sql [string map [list {NULLS FIRST} {}] $sql]
  # set sql [string map [list {NULLS LAST} {}] $sql]
  set sql [string map [list {NULLS FIRST} {}] $sql]
  set sql [string map [list {NULLS LAST} {}] $sql]
  puts $::fd "do_execsql_test $tn {"
  puts $::fd "  [string trim $sql]"
  puts $::fd "} {$res}"
  puts $::fd ""
}

proc errorsql_test {tn sql} {

Changes to test/pragma.test.

383
384
385
386
387
388
389
390

391
392
393
394
395




396
397
398
399
400
401
402
403
404
405
383
384
385
386
387
388
389

390





391
392
393
394



395
396
397
398
399
400
401







-
+
-
-
-
-
-
+
+
+
+
-
-
-







      }
    } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
    do_test pragma-3.5 {
      execsql {
        PRAGMA integrity_check=4
      }
    } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2}}
    do_catchsql_test pragma-3.6 {
    do_test pragma-3.6 {
      PRAGMA integrity_check=xyz
    } {1 {no such table: xyz}}
    do_catchsql_test pragma-3.6b {
      PRAGMA integrity_check=t2
    } {0 {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}}
      execsql {
        PRAGMA integrity_check=xyz
      }
    } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
    do_catchsql_test pragma-3.6c {
      PRAGMA integrity_check=sqlite_schema
    } {0 ok}
    do_test pragma-3.7 {
      execsql {
        PRAGMA integrity_check=0
      }
    } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
  
    # Add additional corruption by appending unused pages to the end of
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
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434






435
436
437
438
439
440
441







-
+








-
-
-
-
-
-







    } {ok}
    do_test pragma-3.8.1 {
      execsql {PRAGMA quick_check}
    } {ok}
    do_test pragma-3.8.2 {
      execsql {PRAGMA QUICK_CHECK}
    } {ok}
    do_test pragma-3.9a {
    do_test pragma-3.9 {
      execsql {
        ATTACH 'testerr.db' AS t2;
        PRAGMA integrity_check
      }
    } {{*** in database t2 ***
Page 4 is never used
Page 5 is never used
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
    do_execsql_test pragma-3.9b {
      PRAGMA t2.integrity_check=t2;
    } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
    do_execsql_test pragma-3.9c {
      PRAGMA t2.integrity_check=sqlite_schema;
    } {ok}
    do_test pragma-3.10 {
      execsql {
        PRAGMA integrity_check=1
      }
    } {{*** in database t2 ***
Page 4 is never used}}
    do_test pragma-3.11 {
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876

1877
1878
1879
1880
1881
1882
1883
1855
1856
1857
1858
1859
1860
1861

1862
1863
1864

1865
1866
1867
1868
1869
1870
1871
1872







-



-
+







sqlite3 db2 test.db
do_test 23.1 {
  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d);
    CREATE INDEX i1 ON t1(b,c);
    CREATE INDEX i2 ON t1(c,d);
    CREATE INDEX i2x ON t1(d COLLATE nocase, c DESC);
    CREATE INDEX i3 ON t1(d,b+c,c);
    CREATE TABLE t2(x INTEGER REFERENCES t1);
  }
  db2 eval {SELECT name FROM sqlite_master}
} {t1 i1 i2 i2x i3 t2}
} {t1 i1 i2 i2x t2}
do_test 23.2a {
  db eval {
    DROP INDEX i2;
    CREATE INDEX i2 ON t1(c,d,b);
  }
  capture_pragma db2 out {PRAGMA index_info(i2)}
  db2 eval {SELECT cid, name, '|' FROM out ORDER BY seqno}
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
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







-
+

-
+


-
-
+
+
-



















-
-
-







} {2 c 0 BINARY 1 | 3 d 0 BINARY 1 | 1 b 0 BINARY 1 | -1 {} 0 BINARY 0 |}

# (The first column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-00197-14279 The rank of the column within the index. (0
# means left-most. Key columns come before auxiliary columns.)
#
# (The second column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-06603-49335 The rank of the column within the table
# EVIDENCE-OF: R-40889-06838 The rank of the column within the table
# being indexed, or -1 if the index-column is the rowid of the table
# being indexed and -2 if the index is on an expression.
# being indexed.
#
# (The third column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-40641-22898 The name of the column being indexed, or
# NULL if the index-column is the rowid of the table being indexed or an
# EVIDENCE-OF: R-22751-28901 The name of the column being indexed, or
# NULL if the index-column is the rowid of the table being indexed.
# expression.
#
# (The fourth column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-11847-09179 1 if the index-column is sorted in reverse
# (DESC) order by the index and 0 otherwise.
#
# (The fifth column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-15313-19540 The name for the collating sequence used to
# compare values in the index-column.
#
# (The sixth column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-14310-64553 1 if the index-column is a key column and 0
# if the index-column is an auxiliary column.
#
do_test 23.2c {
  db2 eval {PRAGMA index_xinfo(i2)}
} {0 2 c 0 BINARY 1 1 3 d 0 BINARY 1 2 1 b 0 BINARY 1 3 -1 {} 0 BINARY 0}
do_test 23.2d {
  db2 eval {PRAGMA index_xinfo(i2x)}
} {0 3 d 0 nocase 1 1 2 c 1 BINARY 1 2 -1 {} 0 BINARY 0}
do_test 23.2e {
  db2 eval {PRAGMA index_xinfo(i3)}
} {0 3 d 0 BINARY 1 1 -2 {} 0 BINARY 1 2 2 c 0 BINARY 1 3 -1 {} 0 BINARY 0}

# EVIDENCE-OF: R-64103-17776 PRAGMA schema.index_list(table-name); This
# pragma returns one row for each index associated with the given table.
#
# (The first column of output from PRAGMA index_list is...)
# EVIDENCE-OF: R-02753-24748 A sequence number assigned to each index
# for internal tracking purposes.
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1932
1933
1934
1935
1936
1937
1938

1939
1940
1941
1942
1943
1944
1945







-







# (The fourth column of output from PRAGMA index_list is...)
# EVIDENCE-OF: R-36609-39554 "c" if the index was created by a CREATE
# INDEX statement, "u" if the index was created by a UNIQUE constraint,
# or "pk" if the index was created by a PRIMARY KEY constraint.
#
do_test 23.3 {
  db eval {
    DROP INDEX IF EXISTS i3;
    CREATE INDEX i3 ON t1(d,b,c);
  }
  capture_pragma db2 out {PRAGMA index_list(t1)}
  db2 eval {SELECT seq, name, "unique", origin, '|' FROM out ORDER BY seq}
} {0 i3 0 c | 1 i2 0 c | 2 i2x 0 c | 3 i1 0 c |}
do_test 23.4 {
  db eval {

Changes to test/pragma3.test.

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
251
252
253
254
255
256
257





























258







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  do_test pragma3-430 {
    db2 eval {PRAGMA data_version; SELECT * FROM t1;}
  } {3 111 222}
  db2 close
}
}

#-------------------------------------------------------------------------
# Check that empty write transactions do not cause the return of "PRAGMA
# data_version" to be decremented with journal_mode=PERSIST and
# locking_mode=EXCLUSIVE
#
foreach {tn sql} {
  A {
  }
  B {
    PRAGMA journal_mode = PERSIST;
    PRAGMA locking_mode = EXCLUSIVE;
  }
} {
  reset_db
  execsql $sql

  do_execsql_test pragma3-510$tn {
    CREATE TABLE t1(x, y);
    INSERT INTO t1 VALUES(1, 2);
    PRAGMA data_version;
  } {1}

  do_execsql_test pragma3-520$tn {
    BEGIN EXCLUSIVE;
    COMMIT;
    PRAGMA data_version;
  } {1}
}

finish_test

Changes to test/pragma4.test.

40
41
42
43
44
45
46

47
48
49
50
51
52
53
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54







+







 10 "PRAGMA defer_foreign_keys = 1"
 11 "PRAGMA empty_result_callbacks = 1"
 12 "PRAGMA encoding = 'utf-8'"
 13 "PRAGMA foreign_keys = 1"
 14 "PRAGMA full_column_names = 1"
 15 "PRAGMA fullfsync = 1"
 16 "PRAGMA ignore_check_constraints = 1"
 17 "PRAGMA legacy_file_format = 1"
 18 "PRAGMA page_size = 511"
 19 "PRAGMA page_size = 512"
 20 "PRAGMA query_only = false"
 21 "PRAGMA read_uncommitted = true"
 22 "PRAGMA recursive_triggers = false"
 23 "PRAGMA reverse_unordered_selects = false"
 24 "PRAGMA schema_version = 211"
116
117
118
119
120
121
122
123

124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
117
118
119
120
121
122
123

124






125


126
127
128
129
130
131
132







-
+
-
-
-
-
-
-
+
-
-







  0 d {} 0 {} 0 1 e {} 0 {} 0 2 f {} 0 {} 0
}
do_test 4.1.4 { 
  sqlite3 db3 test.db
  sqlite3 db2 test.db2
  execsql { DROP TABLE t1 } db3
  execsql { DROP TABLE t2 } db2
} {}  
} {}
if {[permutation]=="prepare"} {
  do_catchsql_test 4.1.5a { 
    PRAGMA table_info(t1) 
  } {1 {database schema has changed}}
}
do_execsql_test 4.1.5 { 
do_execsql_test 4.1.5 { PRAGMA table_info(t1) }
  PRAGMA table_info(t1) 
}
do_execsql_test 4.1.6 { PRAGMA table_info(t2) }

db2 close
db3 close
reset_db
forcedelete test.db2
do_execsql_test 4.2.1 {
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
244
245
246
247
248
249
250
251










252








-
-
-
-
-
-
-
-
-
-

do_test 4.6.3 { 
  execsql { DROP TABLE c2 } db2
} {}
do_execsql_test 4.6.4 { pragma foreign_key_check('c1') } {c1 1 t1 0}
do_catchsql_test 4.6.5 { 
  pragma foreign_key_check('c2') 
} {1 {no such table: c2}}

do_execsql_test 5.0 {
  CREATE TABLE t4(a DEFAULT 'abc' /* comment */, b DEFAULT -1 -- comment
     , c DEFAULT +4.0 /* another comment */
  );
  PRAGMA table_info = t4;
} {
  0 a {} 0 'abc' 0 1 b {} 0 -1 0 2 c {} 0 +4.0 0
}


finish_test

Changes to test/pragma5.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
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













-
+

-
+


















-
-
-
-


-
-
+


-
-
+







# 2017 August 25
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the PRAGMA command. Specifically,
# those pragmas that are not disabled at build time by setting:
# those pragmas enabled at build time by setting:
#
#   -DSQLITE_OMIT_INTROSPECTION_PRAGMAS
#   -DSQLITE_INTROSPECTION_PRAGMAS
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix pragma5

if { [catch {db one "SELECT count(*) FROM pragma_function_list"}] } {
  finish_test
  return
}

db function external external

do_execsql_test 1.0 {
  PRAGMA table_info(pragma_function_list)
} {
  0 name {} 0 {} 0 
  1 builtin {} 0 {} 0
  2 type {} 0 {} 0
  3 enc {} 0 {} 0
  4 narg {} 0 {} 0
  5 flags {} 0 {} 0
}
do_execsql_test 1.1 {
  SELECT DISTINCT name, builtin
    FROM pragma_function_list WHERE name='upper' AND builtin
  SELECT * FROM pragma_function_list WHERE name='upper' AND builtin
} {upper 1}
do_execsql_test 1.2 {
  SELECT DISTINCT name, builtin
    FROM pragma_function_list WHERE name LIKE 'exter%';
  SELECT * FROM pragma_function_list WHERE name LIKE 'exter%';
} {external 0}

ifcapable fts5 {
  do_execsql_test 2.0 {
    PRAGMA table_info(pragma_module_list)
  } {
    0 name {} 0 {} 0 

Changes to test/printf.test.

534
535
536
537
538
539
540
541
542
543
544



545
546
547
548
549
550
551
552
534
535
536
537
538
539
540




541
542
543

544
545
546
547
548
549
550







-
-
-
-
+
+
+
-







} {abc: 1 1 (0.0) :xyz}
do_test printf-2.1.2.8 {
  sqlite3_mprintf_double {abc: %d %d (%1.1e) :xyz} 1 1 1.0e-20
} {abc: 1 1 (1.0e-20) :xyz}
do_test printf-2.1.2.9 {
  sqlite3_mprintf_double {abc: %d %d (%1.1g) :xyz} 1 1 1.0e-20
} {abc: 1 1 (1e-20) :xyz}
if {$SQLITE_MAX_LENGTH<=[expr 1000*1000*1000]} {
  do_test printf-2.1.2.10 {
    sqlite3_mprintf_double {abc: %*.*f}  2000000000 1000000000 1.0e-20
  } {}
do_test printf-2.1.2.10 {
  sqlite3_mprintf_double {abc: %*.*f}  2000000000 1000000000 1.0e-20
} {}
}
do_test printf-2.1.3.1 {
  sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 1.0
} {abc: (1.0) :xyz}
do_test printf-2.1.3.2 {
  sqlite3_mprintf_double {abc: (%*.*e) :xyz} 1 1 1.0
} {abc: (1.0e+00) :xyz}
do_test printf-2.1.3.3 {
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3773
3774
3775
3776
3777
3778
3779







3780







-
-
-
-
-
-
-

      expr {($nFail>0 && $z eq "") || ($nFail==$nBenign && $z eq $zSuccess)}
    } {1}
    if {$nFail == 0} break
    incr nTestNum
  }
}

# 2020-05-23
# ticket 23439ea582241138
#
do_execsql_test printf-16.1 {
  SELECT printf('%.*g',2147483647,0.01);
} {0.01}

finish_test

Changes to test/quote.test.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25







-







# focus of this file is the ability to specify table and column names
# as quoted strings.
#
# $Id: quote.test,v 1.7 2007/04/25 11:32:30 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix quote

# Create a table with a strange name and with strange column names.
#
do_test quote-1.0 {
  catchsql {CREATE TABLE '@abc' ( '#xyz' int, '!pqr' text );}
} {0 {}}

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
80
81
82
83
84
85
86

87





88

























































































89







-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

#
do_test quote-1.6 {
  set r [catch {
    execsql {DROP TABLE '@abc'}
  } msg ]
  lappend r $msg
} {0 {}}

 
#-------------------------------------------------------------------------
# Check that it is not possible to use double-quotes for a string
# constant in a CHECK constraint or CREATE INDEX statement. However, 
# SQLite can load such a schema from disk.
#

reset_db 
sqlite3_db_config db SQLITE_DBCONFIG_DQS_DDL 0
sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1
do_execsql_test 2.0 {
  CREATE TABLE t1(x, y, z);
}
foreach {tn sql errname} {
  1 { CREATE TABLE xyz(a, b, c CHECK (c!="null") ) } null
  2 { CREATE INDEX i2 ON t1(x, y, z||"abc") }        abc
  3 { CREATE INDEX i3 ON t1("w") }                   w
  4 { CREATE INDEX i4 ON t1(x) WHERE z="w" }         w
} {
  do_catchsql_test 2.1.$tn $sql [list 1 "no such column: $errname"]
}

do_execsql_test 2.2 {
  PRAGMA writable_schema = 1;
  CREATE TABLE xyz(a, b, c CHECK (c!="null") );
  CREATE INDEX i2 ON t1(x, y, z||"abc");
  CREATE INDEX i3 ON t1("w"||"");
  CREATE INDEX i4 ON t1(x) WHERE z="w";
}

db close
sqlite3 db test.db

do_execsql_test 2.3.1 {
  INSERT INTO xyz VALUES(1, 2, 3);
}
do_catchsql_test 2.3.2 {
  INSERT INTO xyz VALUES(1, 2, 'null');
} {1 {CHECK constraint failed: c!="null"}}

do_execsql_test 2.4 {
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 'w');
  SELECT * FROM t1 WHERE z='w';
} {4 5 w}
do_execsql_test 2.5 {
  SELECT sql FROM sqlite_master;
} {
  {CREATE TABLE t1(x, y, z)}
  {CREATE TABLE xyz(a, b, c CHECK (c!="null") )}
  {CREATE INDEX i2 ON t1(x, y, z||"abc")}
  {CREATE INDEX i3 ON t1("w"||"")}
  {CREATE INDEX i4 ON t1(x) WHERE z="w"}
}

# 2021-03-13
# ticket 1c24a659e6d7f3a1
reset_db
do_catchsql_test 3.0 {
  CREATE TABLE t1(a,b);
  CREATE INDEX x1 on t1("b");
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.1 {
  DROP TABLE t1;
  CREATE TABLE t1(a,"b");
  CREATE INDEX x1 on t1("b");
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.2 {
  DROP TABLE t1;
  CREATE TABLE t1(a,'b');
  CREATE INDEX x1 on t1("b");
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.3 {
  DROP TABLE t1;
  CREATE TABLE t1(a,"b");
  CREATE INDEX x1 on t1('b');
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.4 {
  DROP TABLE t1;
  CREATE TABLE t1(a, b, c);
  CREATE INDEX x1 ON t1("a"||"b");
  INSERT INTO t1 VALUES(1,2,3),(1,4,5);
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.5 {
  DROP TABLE t1;
  CREATE TABLE t1(a, b, c);
  CREATE INDEX x1 ON t1("a"||"x");
  INSERT INTO t1 VALUES(1,2,3),(1,4,5);
  ALTER TABLE t1 DROP COLUMN b;
} {0 {}}

finish_test

Deleted test/recover.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






































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 April 23
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test the shell tool ".ar" command.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix recover

ifcapable !vtab {
  finish_test; return
}
set CLI [test_find_cli]

proc compare_result {db1 db2 sql} {
  set r1 [$db1 eval $sql]
  set r2 [$db2 eval $sql]
  if {$r1 != $r2} {
  puts "r1: $r1"
  puts "r2: $r2"
    error "mismatch for $sql"
  }
  return ""
}

proc compare_dbs {db1 db2} {
  compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
  foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
    compare_result $db1 $db2 "SELECT * FROM $tbl"
  }
}

proc do_recover_test {tn {tsql {}} {res {}}} {
  set fd [open "|$::CLI test.db .recover"]
  fconfigure $fd -encoding binary
  fconfigure $fd -translation binary
  set sql [read $fd]
  close $fd

  forcedelete test.db2
  sqlite3 db2 test.db2
  execsql $sql db2
  if {$tsql==""} {
    uplevel [list do_test $tn [list compare_dbs db db2] {}]
  } else {
    uplevel [list do_execsql_test -db db2 $tn $tsql $res]
  }
  db2 close
}

set doc {
  hello
  world
}
do_execsql_test 1.1.1 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  INSERT INTO t1 VALUES(1, 4, X'1234567800');
  INSERT INTO t1 VALUES(2, 'test', 8.1);
  INSERT INTO t1 VALUES(3, $doc, 8.4);
}
do_recover_test 1.1.2

do_execsql_test 1.2.1 "
  DELETE FROM t1;
  INSERT INTO t1 VALUES(13, 'hello\r\nworld', 13);
"
do_recover_test 1.2.2

do_execsql_test 1.3.1 "
  CREATE TABLE t2(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
  INSERT INTO t2 VALUES(NULL, 1, 2);
  INSERT INTO t2 VALUES(NULL, 3, 4);
  INSERT INTO t2 VALUES(NULL, 5, 6);
  CREATE TABLE t3(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
  INSERT INTO t3 VALUES(NULL, 1, 2);
  INSERT INTO t3 VALUES(NULL, 3, 4);
  INSERT INTO t3 VALUES(NULL, 5, 6);
  DELETE FROM t2;
"
do_recover_test 1.3.2

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.1.0 {
  PRAGMA auto_vacuum = 0;
  CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
  INSERT INTO t1 VALUES(7, 8, 9);
}

do_recover_test 2.1.1

do_execsql_test 2.2.0 {
  PRAGMA writable_schema = 1;
  DELETE FROM sqlite_master WHERE name='t1';
}
do_recover_test 2.2.1 {
  SELECT name FROM sqlite_master
} {lost_and_found}

do_execsql_test 2.3.0 {
  CREATE TABLE lost_and_found(a, b, c);
}
do_recover_test 2.3.1 {
  SELECT name FROM sqlite_master
} {lost_and_found lost_and_found_0}

do_execsql_test 2.4.0 {
  CREATE TABLE lost_and_found_0(a, b, c);
}
do_recover_test 2.4.1 {
  SELECT name FROM sqlite_master;
  SELECT * FROM lost_and_found_1;
} {lost_and_found lost_and_found_0 lost_and_found_1
  2 2 3 {} 2 3 1
  2 2 3 {} 5 6 4
  2 2 3 {} 8 9 7
}

#-------------------------------------------------------------------------
reset_db
do_recover_test 3.0

finish_test

Changes to test/reindex.test.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
11
12
13
14
15
16
17

18
19
20
21
22
23
24







-







# This file implements regression tests for SQLite library.
# This file implements tests for the REINDEX command.
#
# $Id: reindex.test,v 1.4 2008/07/12 14:52:20 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix reindex

# There is nothing to test if REINDEX is disable for this build.
#
ifcapable {!reindex} {
  finish_test
  return
}
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
163
164
165
166
167
168
169
170

































171








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

    REINDEX;
  } db2
} {1 {no such collation sequence: c2}}

do_test reindex-3.99 {
  db2 close
} {}

#-------------------------------------------------------------------------
foreach {tn wo} {1 "" 2 "WITHOUT ROWID"} {
  reset_db
  eval [string map [list %without_rowid% $wo] {
    do_execsql_test 4.$tn.0 {
      CREATE TABLE t0 (
        c0 INTEGER PRIMARY KEY DESC, 
        c1 UNIQUE DEFAULT NULL
      ) %without_rowid% ;
      INSERT INTO t0(c0) VALUES (1), (2), (3), (4), (5);
      SELECT c0 FROM t0 WHERE c1 IS NULL ORDER BY 1;
    } {1 2 3 4 5}
    
    do_execsql_test 4.$tn.1 {
      REINDEX;
    }
    
    do_execsql_test 4.$tn.2 {
      SELECT c0 FROM t0 WHERE c1 IS NULL ORDER BY 1;
    } {1 2 3 4 5}

    do_execsql_test 4.$tn.3 {
      SELECT c0 FROM t0 WHERE c1 IS NULL AND c0 IN (1,2,3,4,5);
    } {1 2 3 4 5}

    do_execsql_test 4.$tn.4 {
      PRAGMA integrity_check;
    } {ok}
  }]
}



finish_test

Changes to test/releasetest.tcl.

277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291







-
+







    "Debug-One"               "mptest 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"
    "Device-Two"              test
    "No-lookaside"            test
    "Devkit"                  test
    "Apple"                   test
    "Sanitize"                {QUICKTEST_OMIT=func4.test,nan.test test}
    "Device-One"              fulltest
    "Default"                 "threadtest fulltest"
    "Valgrind"                valgrindtest
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
408
409
410
411
412
413
414


415
416
417
418
419
420
421







-
-







        set errmsg $line
      }
    }
    if {[regexp {runtime error: +(.*)} $line all msg]} {
      # skip over "value is outside range" errors
      if {[regexp {value .* is outside the range of representable} $line]} {
         # noop
      } elseif {[regexp {overflow: .* cannot be represented} $line]} {
         # noop
      } else {
        incr ::NERRCASE
        if {$rc==0} {
          set rc 1
          set errmsg $msg
        }
      }

Changes to test/releasetest_data.tcl.

1
2

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32

33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59

60
61
62
63
64
65
66
67


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
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+
-
-
-
-
-
+
-
-
-
















-
+

-
+
-







# 2019 August 01
#

# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements a program that produces scripts (either shell scripts
# or batch files) to implement a particular test that is part of the SQLite
# release testing procedure. For example, to run veryquick.test with a 
# specified set of -D compiler switches.
#
# A "configuration" is a set of options passed to [./configure] and [make]
# to build the SQLite library in a particular fashion. A "platform" is a
# list of tests; most platforms are named after the hardware/OS platform
# that the tests will be run on as part of the release procedure. Each 
# "test" is a combination of a configuration and a makefile target (e.g.
# "fulltest"). The program may be invoked as follows:
#
set USAGE {
$argv0 platforms
    List available platforms.

# This file contains Configuration data used by "wapptest.tcl" and
$argv0 tests ?-nodebug? PLATFORM
    List tests in a specified platform. If the -nodebug switch is 
    specified, synthetic debug/ndebug configurations are omitted. Each
    test is a combination of a configuration and a makefile target.

# "releasetest.tcl".
$argv0 script ?-msvc? CONFIGURATION TARGET
    Given a configuration and make target, return a bash (or, if -msvc
    is specified, batch) script to execute the test. The first argument
    passed to the script must be a directory containing SQLite source code.

#
$argv0 configurations
    List available configurations.
}

# Omit comments (text between # and \n) in a long multi-line string.
#
proc strip_comments {in} {
  regsub -all {#[^\n]*\n} $in {} out
  return $out
}

array set ::Configs [strip_comments {
  "Default" {
    -O2
    --disable-amalgamation --disable-shared
    --enable-session
    -DSQLITE_ENABLE_DESERIALIZE
  }
  "Sanitize" {
    CC=clang -fsanitize=address,undefined
    CC=clang -fsanitize=undefined
    -DSQLITE_ENABLE_STAT4
    --enable-debug
    --enable-session
    --enable-all
  }
  "Stdcall" {
    -DUSE_STDCALL=1
    -O2
  }
  "Have-Not" {
    # The "Have-Not" configuration sets all possible -UHAVE_feature options
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
95
96
97
98
99
100
101





102
103
104
105
106
107
108

109
110
111
112
113
114
115







-
-
-
-
-







-







    -DSQLITE_ENABLE_COLUMN_METADATA=1
    -DSQLITE_ENABLE_STAT4
    -DSQLITE_ENABLE_HIDDEN_COLUMNS
    -DSQLITE_MAX_ATTACHED=125
    -DSQLITE_MUTATION_TEST
    --enable-fts5 --enable-json1
  }
  "Debug-Two" {
    -DSQLITE_DEFAULT_MEMSTATUS=0
    -DSQLITE_MAX_EXPR_DEPTH=0
    --enable-debug
  }
  "Fast-One" {
    -O6
    -DSQLITE_ENABLE_FTS4=1
    -DSQLITE_ENABLE_RTREE=1
    -DSQLITE_ENABLE_STAT4
    -DSQLITE_ENABLE_RBU
    -DSQLITE_MAX_ATTACHED=125
    -DSQLITE_MAX_MMAP_SIZE=12884901888
    -DLONGDOUBLE_TYPE=double
    --enable-session
  }
  "Device-One" {
    -O2
    -DSQLITE_DEBUG=1
    -DSQLITE_DEFAULT_AUTOVACUUM=1
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
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







+
+












+







  "Apple" {
    -Os
    -DHAVE_GMTIME_R=1
    -DHAVE_ISNAN=1
    -DHAVE_LOCALTIME_R=1
    -DHAVE_PREAD=1
    -DHAVE_PWRITE=1
    -DHAVE_USLEEP=1
    -DHAVE_USLEEP=1
    -DHAVE_UTIME=1
    -DSQLITE_DEFAULT_CACHE_SIZE=1000
    -DSQLITE_DEFAULT_CKPTFULLFSYNC=1
    -DSQLITE_DEFAULT_MEMSTATUS=1
    -DSQLITE_DEFAULT_PAGE_SIZE=1024
    -DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS=1
    -DSQLITE_ENABLE_API_ARMOR=1
    -DSQLITE_ENABLE_AUTO_PROFILE=1
    -DSQLITE_ENABLE_FLOCKTIMEOUT=1
    -DSQLITE_ENABLE_FTS3=1
    -DSQLITE_ENABLE_FTS3_PARENTHESIS=1
    -DSQLITE_ENABLE_FTS3_TOKENIZER=1
    if:os=="Darwin" -DSQLITE_ENABLE_LOCKING_STYLE=1
    -DSQLITE_ENABLE_PERSIST_WAL=1
    -DSQLITE_ENABLE_PURGEABLE_PCACHE=1
    -DSQLITE_ENABLE_RTREE=1
    -DSQLITE_ENABLE_SNAPSHOT=1
    # -DSQLITE_ENABLE_SQLLOG=1
    -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1
    -DSQLITE_MAX_LENGTH=2147483645
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
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







+









-
-
-
-
-
-
-
-
-





-
-
-
-
+
+
+
+



-
-
-



-
-
+
+

-






-
+



-
+


-
+







    -DSQLITE_DISABLE_FTS4_DEFERRED
    -DSQLITE_ENABLE_RTREE
    --enable-json1 --enable-fts5
  }
  "No-lookaside" {
    -DSQLITE_TEST_REALLOC_STRESS=1
    -DSQLITE_OMIT_LOOKASIDE=1
    -DHAVE_USLEEP=1
  }
  "Valgrind" {
    -DSQLITE_ENABLE_STAT4
    -DSQLITE_ENABLE_FTS4
    -DSQLITE_ENABLE_RTREE
    -DSQLITE_ENABLE_HIDDEN_COLUMNS
    --enable-json1
  }

  "Windows-Memdebug" {
    MEMDEBUG=1
    DEBUG=3
  }
  "Windows-Win32Heap" {
    WIN32HEAP=1
    DEBUG=4
  }

  # The next group of configurations are used only by the
  # Failure-Detection platform.  They are all the same, but we need
  # different names for them all so that they results appear in separate
  # subdirectories.
  #
  Fail0     {-O0}
  Fail2     {-O0}
  Fail3     {-O0}
  Fail4     {-O0}
  Fail0 {-O0}
  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"
    "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"
    "Device-Two"              test
    "No-lookaside"            test
    "Devkit"                  test
    "Apple"                   test
    "Sanitize"                test
    "Sanitize"                {QUICKTEST_OMIT=func4.test,nan.test test}
    "Device-One"              fulltest
    "Default"                 "threadtest fulltest"
    "Valgrind*"               valgrindtest
    "Valgrind"                valgrindtest
  }
  Linux-i686 {
    "Devkit"                  test
    "Have-Not"                test
    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
    "Device-One"              test
    "Device-Two"              test
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354







355
356
357

358
359
360
361
362
363
364

































































































365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
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


































































































































































































































































-
-





-
-








-
-
-
-
-
-
-
+
+
+
+
+
+
+



+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
-
-







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    "Locking-Style"           "mptest test"
    "Have-Not"                test
    "Apple"                   "threadtest fulltest"
  }
  "Windows NT-intel" {
    "Stdcall"                 test
    "Have-Not"                test
    "Windows-Memdebug*"       test
    "Windows-Win32Heap*"      test
    "Default"                 "mptest fulltestonly"
  }
  "Windows NT-amd64" {
    "Stdcall"                 test
    "Have-Not"                test
    "Windows-Memdebug*"       test
    "Windows-Win32Heap*"      test
    "Default"                 "mptest fulltestonly"
  }

  # The Failure-Detection platform runs various tests that deliberately
  # fail.  This is used as a test of this script to verify that this script
  # correctly identifies failures.
  #
  Failure-Detection {
    Fail0*     "TEST_FAILURE=0 test"
    Sanitize*  "TEST_FAILURE=1 test"
    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"
    Fail0     "TEST_FAILURE=0 test"
    Sanitize  "TEST_FAILURE=1 test"
    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"
  }
}]

proc make_test_suite {msvc withtcl name testtarget config} {
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# End of configuration section.
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------

  # Tcl variable $opts is used to build up the value used to set the
  # OPTS Makefile variable. Variable $cflags holds the value for
  # CFLAGS. The makefile will pass OPTS to both gcc and lemon, but
  # CFLAGS is only passed to gcc.
  #
  set makeOpts ""
  set cflags [expr {$msvc ? "-Zi" : "-g"}]
  set opts ""
  set title ${name}($testtarget)
  set configOpts $withtcl
  set skip 0

  regsub -all {#[^\n]*\n} $config \n config
  foreach arg $config {
    if {$skip} {
      set skip 0
      continue
    }
    if {[regexp {^-[UD]} $arg]} {
      lappend opts $arg
    } elseif {[regexp {^[A-Z]+=} $arg]} {
      lappend testtarget $arg
    } elseif {[regexp {^if:([a-z]+)(.*)} $arg all key tail]} {
      # Arguments of the form 'if:os=="Linux"' will cause the subsequent
      # argument to be skipped if the $tcl_platform(os) is not "Linux", for
      # example...
      set skip [expr !(\$::tcl_platform($key)$tail)]
    } elseif {[regexp {^--(enable|disable)-} $arg]} {
      if {$msvc} {
        if {$arg eq "--disable-amalgamation"} {
          lappend makeOpts USE_AMALGAMATION=0
          continue
        }
        if {$arg eq "--disable-shared"} {
          lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0
          continue
        }
        if {$arg eq "--enable-fts5"} {
          lappend opts -DSQLITE_ENABLE_FTS5
          continue
        }
        if {$arg eq "--enable-json1"} {
          lappend opts -DSQLITE_ENABLE_JSON1
          continue
        }
        if {$arg eq "--enable-shared"} {
          lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1
          continue
        }
      }
      lappend configOpts $arg
    } else {
      if {$msvc} {
        if {$arg eq "-g"} {
          lappend cflags -Zi
          continue
        }
        if {[regexp -- {^-O(\d+)$} $arg all level]} then {
          lappend makeOpts OPTIMIZATIONS=$level
          continue
        }
      }
      lappend cflags $arg
    }
  }

  # Disable sync to make testing faster.
  #
  lappend opts -DSQLITE_NO_SYNC=1

  # Some configurations already set HAVE_USLEEP; in that case, skip it.
  #
  if {[lsearch -regexp $opts {^-DHAVE_USLEEP(?:=|$)}]==-1} {
    lappend opts -DHAVE_USLEEP=1
  }

  # Add the define for this platform.
  #
  if {$::tcl_platform(platform)=="windows"} {
    lappend opts -DSQLITE_OS_WIN=1
  } else {
    lappend opts -DSQLITE_OS_UNIX=1
  }

  # Set the sub-directory to use.
  #
  set dir [string tolower [string map {- _ " " _ "(" _ ")" _} $name]]

  # Join option lists into strings, using space as delimiter.
  #
  set makeOpts [join $makeOpts " "]
  set cflags   [join $cflags " "]
  set opts     [join $opts " "]

  return [list $title $dir $configOpts $testtarget $makeOpts $cflags $opts]
}

# 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]=="*"} {
      set v [string range $v 0 end-1]
    }
    if {0==[info exists ::Configs($v)]} {
      puts stderr "No such configuration: \"$v\""
      exit -1
    }
  }
}

proc usage {} {
  global argv0
  puts stderr [subst $::USAGE]
  exit 1
}

proc is_prefix {p str min} {
  set n [string length $p]
  if {$n<$min} { return 0 }
  if {[string range $str 0 [expr $n-1]]!=$p} { return 0 }
  return 1
}

proc main_configurations {} {
  foreach k [lsort [array names ::Configs]] {
    puts $k
  }
}

proc main_platforms {} {
  foreach k [lsort [array names ::Platforms]] {
    puts "\"$k\""
  }
}

proc main_script {args} {
  set bMsvc 0
  set nArg [llength $args]
  if {$nArg==3} {
    if {![is_prefix [lindex $args 0] -msvc 2]} usage
    set bMsvc 1
  } elseif {$nArg<2 || $nArg>3} {
    usage
  }
  set config [lindex $args end-1]
  set target [lindex $args end]

  set opts       [list]                         ;# OPTS value
  set cflags     [expr {$bMsvc ? "-Zi" : "-g"}] ;# CFLAGS value
  set makeOpts   [list]                         ;# Extra args for [make]
  set configOpts [list]                         ;# Extra args for [configure]

  if {$::tcl_platform(platform)=="windows" || $bMsvc} {
    lappend opts -DSQLITE_OS_WIN=1
  } else {
    lappend opts -DSQLITE_OS_UNIX=1
  }

  # Figure out if this is a synthetic ndebug or debug configuration.
  #
  set bRemoveDebug 0
  if {[string match *-ndebug $config]} {
    set bRemoveDebug 1
    set config [string range $config 0 end-7]
  }
  if {[string match *-debug $config]} {
    lappend opts -DSQLITE_DEBUG
    lappend opts -DSQLITE_EXTRA_IFNULLROW
    set config [string range $config 0 end-6]
  }

  # Ensure that the named configuration exists.
  #
  if {![info exists ::Configs($config)]} {
    puts stderr "No such config: $config"
    exit 1
  }

  # Loop through the parameters of the nominated configuration, updating
  # $opts, $cflags, $makeOpts and $configOpts along the way. Rules are as
  # follows:
  #
  #   1. If the parameter begins with a "*", discard it.
  #
  #   2. If $bRemoveDebug is set and the parameter is -DSQLITE_DEBUG or
  #      -DSQLITE_DEBUG=1, discard it
  #
  #   3. If the parameter begins with "-D", add it to $opts.
  #
  #   4. If the parameter begins with "--" add it to $configOpts. Unless
  #      this command is preparing a script for MSVC - then add an 
  #      equivalent to $makeOpts or $opts.
  #
  #   5. If the parameter begins with "-" add it to $cflags. If in MSVC
  #      mode and the parameter is an -O<integer> option, instead add
  #      an OPTIMIZATIONS=<integer> switch to $makeOpts.
  #
  #   6. If none of the above apply, add the parameter to $makeOpts
  #
  foreach param $::Configs($config) {
    if {[string range $param 0 0]=="*"} continue

    if {$bRemoveDebug} {
      if {$param=="-DSQLITE_DEBUG" || $param=="-DSQLITE_DEBUG=1"
       || $param=="-DSQLITE_MEMDEBUG" || $param=="-DSQLITE_MEMDEBUG=1"
      } {
        continue
      }
    }

    if {[string range $param 0 1]=="-D"} {
      lappend opts $param
      continue
    }

    if {[string range $param 0 1]=="--"} {
      if {$bMsvc} {
        switch -- $param {
          --disable-amalgamation {
            lappend makeOpts USE_AMALGAMATION=0
          }
          --disable-shared {
            lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0
          }
          --enable-fts5 {
            lappend opts -DSQLITE_ENABLE_FTS5
          } 
          --enable-json1 {
            lappend opts -DSQLITE_ENABLE_JSON1
          } 
          --enable-shared {
            lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1
          }
          --enable-session {
            lappend opts -DSQLITE_ENABLE_PREUPDATE_HOOK
            lappend opts -DSQLITE_ENABLE_SESSION
          }
          default {
            error "Cannot translate $param for MSVC"
          }
        }
      } else {
        lappend configOpts $param
      }

      continue
    }

    if {[string range $param 0 0]=="-"} {
      if {$bMsvc && [regexp -- {^-O(\d+)$} $param -> level]} {
        lappend makeOpts OPTIMIZATIONS=$level
      } else {
        lappend cflags $param
      }
      continue
    }

    lappend makeOpts $param
  }

  # Some configurations specify -DHAVE_USLEEP=0. For all others, add
  # -DHAVE_USLEEP=1.
  #
  if {[lsearch $opts "-DHAVE_USLEEP=0"]<0} {
    lappend opts -DHAVE_USLEEP=1
  }

  if {$bMsvc==0} {
    puts {set -e}
    puts {}
    puts {if [ "$#" -ne 1 ] ; then}
    puts {  echo "Usage: $0 <sqlite-src-dir>" }
    puts {  exit -1 }
    puts {fi }
    puts {SRCDIR=$1}
    puts {}
    puts "TCL=\"[::tcl::pkgconfig get libdir,install]\""

    puts "\$SRCDIR/configure --with-tcl=\$TCL $configOpts"
    puts {}
    puts {OPTS="      -DSQLITE_NO_SYNC=1"}
    foreach o $opts { 
      puts "OPTS=\"\$OPTS $o\"" 
    }
    puts {}
    puts "CFLAGS=\"$cflags\""
    puts {}
    puts "make $target \"CFLAGS=\$CFLAGS\" \"OPTS=\$OPTS\" $makeOpts"
  } else {

    puts {set SRCDIR=%1}
    set makecmd    "nmake /f %SRCDIR%\\Makefile.msc TOP=%SRCDIR% $target "
    append makecmd "\"CFLAGS=$cflags\" \"OPTS=$opts\" $makeOpts"

    puts "set TMP=%CD%"
    puts $makecmd
  }
}

proc main_tests {args} {
  set bNodebug 0
  set nArg [llength $args]
  if {$nArg==2} {
    if {[is_prefix [lindex $args 0] -nodebug 2]} {
      set bNodebug 1
    } elseif {[is_prefix [lindex $args 0] -debug 2]} {
      set bNodebug 0
    } else usage
  } elseif {$nArg==0 || $nArg>2} {
    usage
  }
  set p [lindex $args end]
  if {![info exists ::Platforms($p)]} {
    puts stderr "No such platform: $p"
    exit 1
  }

  foreach {config target} $::Platforms($p) {
    set bNosynthetic 0
    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\""
      }
    }
  }
}

if {[llength $argv]==0} { usage }
set cmd [lindex $argv 0]
set n [expr [llength $argv]-1]
if {[string match ${cmd}* configurations] && $n==0} {
  main_configurations 
} elseif {[string match ${cmd}* script]} {
  main_script {*}[lrange $argv 1 end]
} elseif {[string match ${cmd}* platforms] && $n==0} {
  main_platforms
} elseif {[string match ${cmd}* tests]} {
  main_tests {*}[lrange $argv 1 end]
} else {
  usage
}


Deleted 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
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-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}

# Ticket 132994c8b1063bfb
reset_db
do_catchsql_test 6.0 {
  CREATE TABLE t1(id INTEGER PRIMARY KEY);
  CREATE TABLE t2(x INT, y INT);
  INSERT INTO t1 VALUES(1),(2),(4),(9);
  INSERT INTO t2 VALUES(3,7), (4,25), (5,99);
  UPDATE t1 SET id=id+y FROM t2 WHERE t1.id=t2.x RETURNING t2.*;
} {1 {RETURNING may not use "TABLE.*" wildcards}}
do_catchsql_test 6.1 {
  UPDATE t1 SET id=id+y FROM t2 WHERE t1.id=t2.x RETURNING *, '|';
  SELECT * FROM t1 ORDER BY id;
} {0 {29 | 1 2 9 29}}

# Forum https://sqlite.org/forum/forumpost/85aef8bc01
# Do not silently ignore nonsense table names in the RETURNING clause.
# Raise an error.
#
reset_db
do_execsql_test 7.1 {
  CREATE TABLE t1(a INT, b INT);
  CREATE TABLE t2(x INT, y INT);
  INSERT INTO t1(a,b) VALUES(1,2);
  INSERT INTO t2(x,y) VALUES(1,30);
} {}
do_catchsql_test 7.2 {
  UPDATE t1 SET b=b+1 RETURNING new.b;
} {1 {no such column: new.b}}
do_catchsql_test 7.3 {
  UPDATE t1 SET b=b+1 RETURNING old.b;
} {1 {no such column: old.b}}
do_catchsql_test 7.4 {
  UPDATE t1 SET b=b+1 RETURNING another.b;
} {1 {no such column: another.b}}
do_catchsql_test 7.5 {
  UPDATE t1 SET b=b+y FROM t2 WHERE t2.x=t1.a RETURNING t2.x;
} {1 {no such column: t2.x}}
do_catchsql_test 7.6 {
  UPDATE t1 SET b=b+y FROM t2 WHERE t2.x=t1.a RETURNING t1.b;
} {0 32}

# This is goofy:  The RETURNING clause does not honor the alias
# for the table being modified.  This might change in the future.
#
do_catchsql_test 7.7 {
  UPDATE t1 AS alias SET b=123 RETURNING alias.b;
} {1 {no such column: alias.b}}
do_catchsql_test 7.8 {
  UPDATE t1 AS alias SET b=alias.b+1000 RETURNING t1.b;
} {0 1032}

# Forum: https://sqlite.org/forum/info/34c81d83c9177f46
reset_db
do_execsql_test 8.1 {
  CREATE TABLE t1(a);
  CREATE TABLE t2(b,c);
  INSERT INTO t1 VALUES(1);
  INSERT INTO t2 VALUES(3,40);
} {}
do_catchsql_test 8.2 {
  INSERT INTO t1 VALUES(3) RETURNING a, (SELECT c FROM t2 WHERE new.a=t2.b) AS x;
} {1 {no such column: new.a}}
do_catchsql_test 8.3 {
  INSERT INTO t1 VALUES(3) RETURNING a, (SELECT c FROM t2 WHERE old.a=t2.b) AS x;
} {1 {no such column: old.a}}
do_catchsql_test 8.4 {
  INSERT INTO t1 VALUES(3) RETURNING a, (SELECT c FROM t2 WHERE t1.a=t2.b) AS x;
} {0 {3 40}}

finish_test

Deleted test/round1.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









































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-05-24
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# Test cases for rounding behavior of floating point values.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix round1

expr srand(0)
unset -nocomplain iTest
for {set iTest 1} {$iTest<=50000} {incr iTest} {
   set x1 [expr int(rand()*100000)]
   set x2 [expr int(rand()*100000)+1000*int(rand()*10000)]
   set n [expr int(rand()*8)+1]
   set x3 [string range [format %09d $x2] [expr {9-$n}] end]
   set r $x1.$x3
   set ans [string trimright $r 0]
   if {[string match *. $ans]} {set ans ${ans}0}
   do_test $iTest/$n/${r}4=>$ans {
     set x [db one "SELECT round(${r}4,$n)"]
   } $ans
   set x4 [string range [format %09d [expr {$x2+1}]] [expr {9-$n}] end]
   if {[string trim $x3 9]==""} {incr x1}
   set r2 $x1.$x4
   set ans [string trimright $r2 0]
   if {[string match *. $ans]} {set ans ${ans}0}
   do_test $iTest/$n/${r}5=>$ans {
     set x [db one "SELECT round(${r}5,$n)"]
   } $ans
}

finish_test

Changes to test/rowid.test.

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
655
656
657
658
659
660
661


























662
663
664
665
666
667
668







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







do_test rowid-11.3 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid<'abc'}
} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}
do_test rowid-11.4 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc'}
} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}

do_test rowid-11.asc.1 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid>'abc' ORDER BY 1 ASC}
} {}
do_test rowid-11.asc.2 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid>='abc' ORDER BY 1 ASC}
} {}
do_test rowid-11.asc.3 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid<'abc' ORDER BY 1 ASC}
} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}
do_test rowid-11.asc.4 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc' ORDER BY 1 ASC}
} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}

do_test rowid-11.desc.1 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid>'abc' ORDER BY 1 DESC}
} {}
do_test rowid-11.desc.2 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid>='abc' ORDER BY 1 DESC}
} {}
do_test rowid-11.desc.3 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid<'abc' ORDER BY 1 DESC}
} {8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1}
do_test rowid-11.desc.4 {
  execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc' ORDER BY 1 DESC}
} {8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1}

# Test the automatic generation of rowids when the table already contains
# a rowid with the maximum value.
#
# Once the maximum rowid is taken, rowids are normally chosen at
# random.  By by reseting the random number generator, we can cause
# the rowid guessing loop to collide with prior rowids, and test the
# loop out to its limit of 100 iterations.  After 100 collisions, the
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
714
715
716
717
718
719
720
721










































722








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

db function addrow rowid_addrow_func
do_execsql_test rowid-13.1 {
  CREATE TABLE t13(x);
  INSERT INTO t13(rowid,x) VALUES(1234,5);
  SELECT rowid, x, addrow(rowid+1000), '|' FROM t13 LIMIT 3;
  SELECT last_insert_rowid();
} {1234 5 2234 | 2234 4990756 3234 | 3234 10458756 4234 | 4234}

#-------------------------------------------------------------------------
do_execsql_test rowid-14.0 {
  CREATE TABLE t14(x INTEGER PRIMARY KEY);
  INSERT INTO t14(x) VALUES (100);
}
do_execsql_test rowid-14.1 {
  SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid ASC;
} {100}
do_execsql_test rowid-14.2 {
  SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid DESC;
} {100}

do_execsql_test rowid-14.3 {
  DELETE FROM t14;
  SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid ASC;
} {}
do_execsql_test rowid-14.4 {
  SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid DESC;
} {}

reset_db
do_execsql_test rowid-15.0 {
  PRAGMA reverse_unordered_selects=true;
  CREATE TABLE t1 (c0, c1);
  CREATE TABLE t2 (c0 INT UNIQUE);
  INSERT INTO t1(c0, c1) VALUES (0, 0), (0, NULL);
  INSERT INTO t2(c0) VALUES (1);
}

do_execsql_test rowid-15.1 {
  SELECT t2.c0, t1.c1 FROM t1, t2 
  WHERE (t2.rowid <= 'a') OR (t1.c0 <= t2.c0) LIMIT 100
} {1 {} 1 0}

do_execsql_test rowid-15.2 {
  SELECT 1, NULL INTERSECT SELECT * FROM (
      SELECT t2.c0, t1.c1 FROM t1, t2
      WHERE ((t2.rowid <= 'a')) OR (t1.c0 <= t2.c0) ORDER BY 'a' DESC LIMIT 100
  );
} {1 {}}


finish_test

Changes to test/rowvalue.test.

553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
553
554
555
556
557
558
559










































































































560







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_execsql_test 21.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a,b,PRIMARY KEY(b,b));
  INSERT INTO t1 VALUES(1,2),(3,4),(5,6);
  SELECT * FROM t1 WHERE (a,b) IN (VALUES(1,2));  
} {1 2}

# 2019-08-09: Multi-column subquery on the RHS of an IN operator.
#
do_execsql_test 22.100 {
  SELECT (SELECT 3,4 UNION SELECT 5,6 ORDER BY 1) IN (SELECT 3,4);
  SELECT (SELECT 3,4 UNION SELECT 5,6 ORDER BY 1) IN (SELECT 5,6);
  SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1) IN (SELECT 3,4);
  SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1) IN (SELECT 5,6);
  SELECT (SELECT 3,4 UNION SELECT 5,6 ORDER BY 1 DESC) IN (SELECT 3,4);
  SELECT (SELECT 3,4 UNION SELECT 5,6 ORDER BY 1 DESC) IN (SELECT 5,6);
  SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1 DESC) IN (SELECT 3,4);
  SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1 DESC) IN (SELECT 5,6);
} {1 0 1 0 0 1 0 1}

# 2019-10-21 Ticket b47e3627ecaadbde
#
do_execsql_test 23.100 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(aa COLLATE NOCASE, bb);
  INSERT INTO t0 VALUES('a', 'A');
  SELECT (+bb,1) >= (aa, 1), (aa,1)<=(+bb,1) FROM t0;
  SELECT 2 FROM t0 WHERE (+bb,1) >= (aa,1);
  SELECT 3 FROM t0 WHERE (aa,1) <= (+bb,1);
} {0 1 3}
do_execsql_test 23.110 {
  SELECT (SELECT +bb,1) >= (aa, 1), (aa,1)<=(SELECT +bb,1) FROM t0;
  SELECT 2 FROM t0 WHERE (SELECT +bb,1) >= (aa,1);
  SELECT 3 FROM t0 WHERE (aa,1) <= (SELECT +bb,1);
} {0 1 3}

# 2019-10-22 Ticket 6ef984af8972c2eb
do_execsql_test 24.100 {
  DROP TABLE t0;
  CREATE TABLE t0(c0 TEXT PRIMARY KEY);
  INSERT INTO t0(c0) VALUES ('');
  SELECT (t0.c0, TRUE) > (CAST(0 AS REAL), FALSE) FROM t0;
  SELECT 2 FROM t0 WHERE (t0.c0, TRUE) > (CAST('' AS REAL), FALSE);
} {1 2}

# 2019-10-23 Ticket 135c9da7513e5a97
do_execsql_test 25.10 {
  DROP TABLE t0;
  CREATE TABLE t0(c0 UNIQUE);
  INSERT INTO t0(c0) VALUES('a');
  SELECT (t0.c0, 0) < ('B' COLLATE NOCASE, 0) FROM t0;
  SELECT 2 FROM t0 WHERE (t0.c0, 0) < ('B' COLLATE NOCASE, 0);
} {1 2}
do_execsql_test 25.20 {
  SELECT ('B' COLLATE NOCASE, 0)> (t0.c0, 0) FROM t0;
  SELECT 2 FROM t0 WHERE ('B' COLLATE NOCASE, 0)> (t0.c0, 0);
} {1 2}
do_execsql_test 25.30 {
  SELECT ('B', 0)> (t0.c0 COLLATE nocase, 0) FROM t0;
  SELECT 2 FROM t0 WHERE ('B', 0)> (t0.c0 COLLATE nocase, 0);
} {1 2}
do_execsql_test 25.40 {
  SELECT (t0.c0 COLLATE nocase, 0) < ('B', 0) FROM t0;
  SELECT 2 FROM t0 WHERE (t0.c0 COLLATE nocase, 0) < ('B', 0);
} {1 2}

# 2019-11-04 Ticket 02aa2bd02f97d0f2
# The TK_VECTOR operator messes up sqlite3ExprImpliesNonNull() which
# causes incorrect LEFT JOIN strength reduction.  TK_VECTOR should be
# treated the same as TK_OR.
#
db close
sqlite3 db :memory:
do_execsql_test 26.10 {
  CREATE TABLE t0(c0);
  CREATE TABLE t1(c1);
  INSERT INTO t1(c1) VALUES (0);
  SELECT (c0, x'') != (NULL, 0) FROM t1 LEFT JOIN t0;
} {1}
do_execsql_test 26.20 {
  SELECT 2 FROM t1 LEFT JOIN t0 ON (c0, x'') != (NULL, 0);
} {2}
do_execsql_test 26.30 {
  SELECT 3 FROM t1 LEFT JOIN t0 WHERE (c0, x'') != (NULL, 0);
} {3}

# 2019-12-30 ticket 892575cdba4e1e36
#
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}}

# 2021-03-19
# dbsqlfuzz find of a NEVER().
do_catchsql_test 29.1 {
  SELECT (SELECT 1 WHERE ((SELECT 1 WHERE (2,(2,0)) IS (2,(20))),(2,0)) IS (2,(20))) WHERE (2,(2,0)) IS (2 IN(SELECT 1 WHERE (2,(2,2,0)) IS (2,(20))),(20));
} {1 {row value misused}}

finish_test

Changes to test/rowvalue7.test.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
51
52
53
54
55
56
57










58







-
-
-
-
-
-
-
-
-
-

  UPDATE t1 SET (c,d) = (SELECT x,y,z FROM t2 WHERE w=a);
} {1 {2 columns assigned 3 values}}

do_catchsql_test 2.2 {
  UPDATE t1 SET (b,c,d) = (SELECT x,y FROM t2 WHERE w=a);
} {1 {3 columns assigned 2 values}}

# 2019-08-26
# ticket https://www.sqlite.org/src/info/78acc9d40f0786e8
#
do_catchsql_test 3.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a,b);
  INSERT INTO t1 VALUES(1,2);
  UPDATE t1 SET (a,a,a,b)=(SELECT 99,100);
} {1 {4 columns assigned 2 values}}

finish_test

Deleted test/rowvaluevtab.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































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2018 October 14
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#


set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix rowvaluevtab

ifcapable !vtab {
  finish_test
  return
}

register_echo_module db

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
  CREATE INDEX t1b ON t1(b);
  INSERT INTO t1 VALUES('one', 1, 1);
  INSERT INTO t1 VALUES('two', 1, 2);
  INSERT INTO t1 VALUES('three', 1, 3);
  INSERT INTO t1 VALUES('four', 2, 1);
  INSERT INTO t1 VALUES('five', 2, 2);
  INSERT INTO t1 VALUES('six', 2, 3);
  INSERT INTO t1 VALUES('seven', 3, 1);
  INSERT INTO t1 VALUES('eight', 3, 2);
  INSERT INTO t1 VALUES('nine', 3, 3);

  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000
  ) INSERT INTO t1 SELECT NULL, NULL, NULL FROM s;
  CREATE VIRTUAL TABLE e1 USING echo(t1);
}

proc do_vfilter4_test {tn sql expected} {
  set res [list]
  db eval "explain $sql" {
    if {$opcode=="VFilter"} {
      lappend res $p4
    }
  }
  uplevel [list do_test $tn [list set {} $res] [list {*}$expected]]
}

do_execsql_test 1.1 {
  SELECT a FROM e1 WHERE (b, c) = (2, 2)
} {five}
do_vfilter4_test 1.1f {
  SELECT a FROM e1 WHERE (b, c) = (?, ?)
} {{SELECT rowid, a, b, c FROM 't1' WHERE b = ?}}

do_execsql_test 1.2 {
  SELECT a FROM e1 WHERE (b, c) > (2, 2)
} {six seven eight nine}
do_vfilter4_test 1.2f {
  SELECT a FROM e1 WHERE (b, c) > (2, 2)
} {
  {SELECT rowid, a, b, c FROM 't1' WHERE b >= ?}
}

do_execsql_test 1.3 {
  SELECT a FROM e1 WHERE (b, c) >= (2, 2)
} {five six seven eight nine}
do_vfilter4_test 1.3f {
  SELECT a FROM e1 WHERE (b, c) >= (2, 2)
} {
  {SELECT rowid, a, b, c FROM 't1' WHERE b >= ?}
}

do_execsql_test 1.3 {
  SELECT a FROM e1 WHERE (b, c) BETWEEN (1, 2) AND (2, 3)
} {two three four five six}
do_vfilter4_test 1.3f {
  SELECT a FROM e1 WHERE (b, c) BETWEEN (1, 2) AND (2, 3)
} {
  {SELECT rowid, a, b, c FROM 't1' WHERE b >= ? AND b <= ?}
}

do_execsql_test 1.4 {
  SELECT a FROM e1 WHERE (b, c) IN ( VALUES(2, 2) )
} {five}
do_vfilter4_test 1.4f {
  SELECT a FROM e1 WHERE (b, c) IN ( VALUES(2, 2) )
} {{SELECT rowid, a, b, c FROM 't1' WHERE b = ?}}

finish_test

Changes to test/schema.test.

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
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







-
+
-
-


-

-
-
-
-
-
-
-
-



-
-
+
+

-
+
-







  do_test schema-7.4 {
    sqlite3_finalize $::STMT
  } {SQLITE_SCHEMA}
}

#---------------------------------------------------------------------
# Tests 8.1 and 8.2 check that prepared statements are invalidated when
# the authorization function is set to a non-null function.  Tests 8.11
# the authorization function is set.
# and 8.12 verify that no invalidations occur when the authorizer is
# cleared.
#
ifcapable auth {
  proc noop_auth {args} {return SQLITE_OK}
  do_test schema-8.1 {
    set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
    db auth noop_auth
    sqlite3_step $::STMT
  } {SQLITE_ERROR}
  do_test schema-8.2 {
    sqlite3_finalize $::STMT
  } {SQLITE_SCHEMA}
  do_test schema-8.11 {
    set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
    db auth {}
    sqlite3_step $::STMT
  } {SQLITE_ROW}
  do_test schema-8.12 {
  } {SQLITE_ERROR}
  do_test schema-8.3 {
    sqlite3_finalize $::STMT
  } {SQLITE_OK}
  } {SQLITE_SCHEMA}

}

#---------------------------------------------------------------------
# schema-9.1: Test that if a table is dropped by one database connection, 
#             other database connections are aware of the schema change.
# schema-9.2: Test that if a view is dropped by one database connection,
#             other database connections are aware of the schema change.

Changes to test/select1.test.

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
1096
1097
1098
1099
1100
1101
1102














































































































1103







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  SELECT * FROM t1,(SELECT * FROM t2 WHERE y=2 ORDER BY y,z LIMIT 4);
} {1 2 3}
do_execsql_test select1-17.3 {
  SELECT * FROM t1,(SELECT * FROM t2 WHERE y=2
         UNION ALL SELECT * FROM t2 WHERE y=3 ORDER BY y,z LIMIT 4);
} {1 2 3}

# 2019-07-24 Ticket https://sqlite.org/src/tktview/c52b09c7f38903b1311
#
do_execsql_test select1-18.1 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t1(c);
  CREATE TABLE t2(x PRIMARY KEY, y);
  INSERT INTO t1(c) VALUES(123);
  INSERT INTO t2(x) VALUES(123);
  SELECT x FROM t2, t1 WHERE x BETWEEN c AND null OR x AND
  x IN ((SELECT x FROM (SELECT x FROM t2, t1 
  WHERE x BETWEEN (SELECT x FROM (SELECT x COLLATE rtrim 
  FROM t2, t1 WHERE x BETWEEN c AND null
  OR x AND x IN (c)), t1 WHERE x BETWEEN c AND null
  OR x AND x IN (c)) AND null
  OR NOT EXISTS(SELECT -4.81 FROM t1, t2 WHERE x BETWEEN c AND null
  OR x AND x IN ((SELECT x FROM (SELECT x FROM t2, t1
  WHERE x BETWEEN (SELECT x FROM (SELECT x BETWEEN c AND null
  OR x AND x IN (c)), t1 WHERE x BETWEEN c AND null
  OR x AND x IN (c)) AND null
  OR x AND x IN (c)), t1 WHERE x BETWEEN c AND null
  OR x AND x IN (c)))) AND x IN (c)
  ), t1 WHERE x BETWEEN c AND null
  OR x AND x IN (c)));
} {}
do_execsql_test select1-18.2 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t1(c);
  CREATE TABLE t2(x PRIMARY KEY, y);
  INSERT INTO t1(c) VALUES(123);
  INSERT INTO t2(x) VALUES(123);
  SELECT x FROM t2, t1 WHERE x BETWEEN c AND (c+1) OR x AND
  x IN ((SELECT x FROM (SELECT x FROM t2, t1 
  WHERE x BETWEEN (SELECT x FROM (SELECT x COLLATE rtrim 
  FROM t2, t1 WHERE x BETWEEN c AND (c+1)
  OR x AND x IN (c)), t1 WHERE x BETWEEN c AND (c+1)
  OR x AND x IN (c)) AND (c+1)
  OR NOT EXISTS(SELECT -4.81 FROM t1, t2 WHERE x BETWEEN c AND (c+1)
  OR x AND x IN ((SELECT x FROM (SELECT x FROM t2, t1
  WHERE x BETWEEN (SELECT x FROM (SELECT x BETWEEN c AND (c+1)
  OR x AND x IN (c)), t1 WHERE x BETWEEN c AND (c+1)
  OR x AND x IN (c)) AND (c+1)
  OR x AND x IN (c)), t1 WHERE x BETWEEN c AND (c+1)
  OR x AND x IN (c)))) AND x IN (c)
  ), t1 WHERE x BETWEEN c AND (c+1)
  OR x AND x IN (c)));
} {123}
do_execsql_test select1-18.3 {
  SELECT 1 FROM t1 WHERE (
    SELECT 2 FROM t2 WHERE (
      SELECT 3 FROM (
        SELECT x FROM t2 WHERE x=c OR x=(SELECT x FROM (VALUES(0)))
      ) WHERE x>c OR x=c
    )
  );
} {1}
do_execsql_test select1-18.4 {
  SELECT 1 FROM t1, t2 WHERE (
    SELECT 3 FROM (
      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/select3.test.

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
257
258
259
260
261
262
263






























































264







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

} {real}
do_test select3-8.2 {
  execsql {
    SELECT typeof(sum(a3)) FROM a GROUP BY a1;
  }
} {real}

# 2019-05-09 ticket https://www.sqlite.org/src/tktview/6c1d3febc00b22d457c7
#
unset -nocomplain x
foreach {id x} {
  100 127
  101 128
  102 -127
  103 -128
  104 -129
  110 32767
  111 32768
  112 -32767
  113 -32768
  114 -32769
  120 2147483647
  121 2147483648
  122 -2147483647
  123 -2147483648
  124 -2147483649
  130 140737488355327
  131 140737488355328
  132 -140737488355327
  133 -140737488355328
  134 -140737488355329
  140 9223372036854775807
  141 -9223372036854775807
  142 -9223372036854775808
  143 9223372036854775806
  144 9223372036854775805
  145 -9223372036854775806
  146 -9223372036854775805

} {
  set x [expr {$x+0}]
  do_execsql_test select3-8.$id {
     DROP TABLE IF EXISTS t1;
     CREATE TABLE t1 (c0, c1 REAL PRIMARY KEY);
     INSERT INTO t1(c0, c1) VALUES (0, $x), (0, 0);
     UPDATE t1 SET c0 = NULL;
     UPDATE OR REPLACE t1 SET c1 = 1;
     SELECT DISTINCT * FROM t1 WHERE (t1.c0 IS NULL);
     PRAGMA integrity_check;
  } {{} 1.0 ok}
}

# 2020-03-10 ticket e0c2ad1aa8a9c691
reset_db
do_execsql_test select3-9.100 {
  CREATE TABLE t0(c0 REAL, c1 REAL GENERATED ALWAYS AS (c0));
  INSERT INTO t0(c0) VALUES (1);
  SELECT * FROM t0 GROUP BY c0;
} {1.0 1.0}

reset_db
do_execsql_test select3.10.100 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d);
  SELECT max(t1.a), 
         (SELECT 'xyz' FROM (SELECT * FROM t2 WHERE 0) WHERE t1.b=1) 
  FROM t1;
} {{} {}}

finish_test

Changes to test/select4.test.

1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1001
1002
1003
1004
1005
1006
1007




1008






























1009
1010







-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


    SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a LIMIT 3
    UNION
    SELECT 98 AS x, 99 AS y
  ) AS w WHERE y>=20
  ORDER BY +x;
} {1 {LIMIT clause should come after UNION not before}}

# 2020-04-03 ticket 51166be0159fd2ce from Yong Heng.
# Adverse interaction between the constant propagation and push-down
# optimizations.
#

reset_db
do_execsql_test select4-18.1 {
  CREATE VIEW v0(v0) AS WITH v0 AS(SELECT 0 v0) SELECT(SELECT min(v0) OVER()) FROM v0 GROUP BY v0;
  SELECT *FROM v0 v1 JOIN v0 USING(v0) WHERE datetime(v0) = (v0.v0)AND v0 = 10;
} {}
do_execsql_test select4-18.2 {
  CREATE VIEW t1(aa) AS
     WITH t2(bb) AS (SELECT 123)
     SELECT (SELECT min(bb) OVER()) FROM t2 GROUP BY bb;
  SELECT * FROM t1;
} {123}
do_execsql_test select4-18.3 {
  SELECT * FROM t1 AS z1 JOIN t1 AS z2 USING(aa)
   WHERE abs(z1.aa)=z2.aa AND z1.aa=123;
} {123}

# 2021-03-31 Fix an assert() problem in the logic at the end of sqlite3Select()
# that validates AggInfo.  The checks to ensure that AggInfo.aCol[].pCExpr
# references a valid expression was looking at an expression that had been
# deleted by the truth optimization in sqlite3ExprAnd() which was invoked by
# the push-down optimization.  This is harmless in delivery builds, as that code
# only runs with SQLITE_DEBUG.  But it should still be fixed.  The problem
# was discovered by dbsqlfuzz (crash-dece7b67a3552ed7e571a7bda903afd1f7bd9b21)
#
reset_db
do_execsql_test select4-19.1 {
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(99);
  SELECT sum((SELECT 1 FROM (SELECT 2 WHERE x IS NULL) WHERE 0)) FROM t1;
} {{}}

finish_test

Changes to test/select6.test.

8
9
10
11
12
13
14

15
16
17
18
19
20
21
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22







+







#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing SELECT statements that contain
# subqueries in their FROM clause.
#
# $Id: select6.test,v 1.29 2009/01/09 01:12:28 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Omit this whole file if the library is build without subquery support.
ifcapable !subquery {
  finish_test
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
609
610
611
612
613
614
615



616














617







-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  DROP TABLE t2;
  CREATE TABLE t1(x);
  CREATE TABLE t2(y, z);
  SELECT ( SELECT y FROM t2 WHERE z = cnt )
    FROM ( SELECT count(*) AS cnt FROM t1 );
} {{}}

# 2019-05-29 ticket https://www.sqlite.org/src/info/c41afac34f15781f
# A LIMIT clause in a subquery is incorrectly applied to a subquery.
#

do_execsql_test 12.100 {
  DROP TABLE t1;
  DROP TABLE t2;
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(1);
  INSERT INTO t1 VALUES(2);
  CREATE TABLE t2(b);
  INSERT INTO t2 VALUES(3);
  SELECT * FROM (
    SELECT * FROM (SELECT * FROM t1 LIMIT 1)
    UNION ALL
    SELECT * from t2);
} {1 3}

finish_test

Changes to test/selectA.test.

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
1442
1443
1444
1445
1446
1447
1448





















1449
1450







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  DROP TABLE IF EXISTS t2;
  CREATE TABLE t1(a INTEGER);
  CREATE TABLE t2(b TEXT);
  INSERT INTO t2(b) VALUES('12345');
  SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t2) WHERE a=a;
} {12345}

# 2020-06-15 ticket 8f157e8010b22af0
#
reset_db
do_execsql_test 7.1 {
  CREATE TABLE t1(c1);     INSERT INTO t1 VALUES(12),(123),(1234),(NULL),('abc');
  CREATE TABLE t2(c2);     INSERT INTO t2 VALUES(44),(55),(123);
  CREATE TABLE t3(c3,c4);  INSERT INTO t3 VALUES(66,1),(123,2),(77,3);
  CREATE VIEW t4 AS SELECT c3 FROM t3;
  CREATE VIEW t5 AS SELECT c3 FROM t3 ORDER BY c4;
}
do_execsql_test 7.2 {
  SELECT * FROM t1, t2 WHERE c1=(SELECT 123 INTERSECT SELECT c2 FROM t4) AND c1=123;
} {123 123}
do_execsql_test 7.3 {
  SELECT * FROM t1, t2 WHERE c1=(SELECT 123 INTERSECT SELECT c2 FROM t5) AND c1=123;
} {123 123}
do_execsql_test 7.4 {
  CREATE TABLE a(b);
  CREATE VIEW c(d) AS SELECT b FROM a ORDER BY b;
  SELECT sum(d) OVER( PARTITION BY(SELECT 0 FROM c JOIN a WHERE b =(SELECT b INTERSECT SELECT d FROM c) AND b = 123)) FROM c;
} {}

finish_test

Changes to test/selectC.test.

257
258
259
260
261
262
263
264

265
266
267


268
269
270
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;
  SELECT * FROM x1, (SELECT b FROM vvv UNION ALL SELECT c from x3);
} {
  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
  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

Changes to test/sessionfuzz.c.

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
694
695
696
697
698
699
700

701

702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717



718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742







-

-
















-
-
-


















-







  "  sessionfuzz run FILE ...   -- Run against fuzzed changeset FILE\n"
  "  sessionfuzz run SQLAR ...  -- Run against all files in the SQL Archive\n"
;

#include <stdio.h>
#include <string.h>
#include <assert.h>
#ifndef OMIT_ZLIB
#include "zlib.h"
#endif

/*
** Implementation of the "sqlar_uncompress(X,SZ)" SQL function
**
** Parameter SZ is interpreted as an integer. If it is less than or
** equal to zero, then this function returns a copy of X. Or, if
** SZ is equal to the size of X when interpreted as a blob, also
** return a copy of X. Otherwise, decompress blob X using zlib
** utility function uncompress() and return the results (another
** blob).
*/
static void sqlarUncompressFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
#ifdef OMIT_ZLIB
  sqlite3_result_value(context, argv[0]);
#else
  uLong nData;
  uLongf sz;

  assert( argc==2 );
  sz = sqlite3_value_int(argv[1]);

  if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
    sqlite3_result_value(context, argv[0]);
  }else{
    const Bytef *pData= sqlite3_value_blob(argv[0]);
    Bytef *pOut = sqlite3_malloc(sz);
    if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){
      sqlite3_result_error(context, "error in uncompress()", -1);
    }else{
      sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT);
    }
    sqlite3_free(pOut);
  }
#endif
}


/* Run a chunk of SQL.  If any errors happen, print an error message
** and exit.
*/
static void runSql(sqlite3 *db, const char *zSql){

Changes to test/shared.test.

156
157
158
159
160
161
162
163



164
165

166
167
168
169
170
171
172
156
157
158
159
160
161
162

163
164
165
166

167
168
169
170
171
172
173
174







-
+
+
+

-
+







  # Commit the connection 1 transaction.
  execsql {
    COMMIT;
  }
} {}

do_test shared-$av.2.1 {
  # Open connection db3 to the database.
  # Open connection db3 to the database. Use a different path to the same
  # file so that db3 does *not* share the same pager cache as db and db2
  # (there should be two open file handles).
  if {$::tcl_platform(platform)=="unix"} {
    sqlite3 db3 "file:test.db?cache=private" -uri 1
    sqlite3 db3 ./test.db
  } else {
    sqlite3 db3 TEST.DB
  }
  set ::sqlite_open_file_count
  expr $sqlite_open_file_count-($extrafds_prelock+$extrafds_postlock)
} {2}
do_test shared-$av.2.2 {
794
795
796
797
798
799
800
801

802
803
804
805
806
807
808
796
797
798
799
800
801
802

803
804
805
806
807
808
809
810







-
+







    INSERT INTO de VALUES('Pataya', 30000);
  } db2
} {}
do_test shared-$av.10.3 {
  # An external connection should be able to read the database, but not
  # prepare a write operation.
  if {$::tcl_platform(platform)=="unix"} {
    sqlite3 db3 "file:test.db?cache=private" -uri 1
    sqlite3 db3 ./test.db
  } else {
    sqlite3 db3 TEST.DB
  }
  execsql {
    SELECT * FROM ab;
  } db3
  catchsql {

Changes to test/shared3.test.

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
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







-
-
-
-
+
+
+
+
-
+

-
+
-



















-
+








# The cache-size should now be 10 pages. However at one point there was
# a bug that caused the cache size to return to the default value when
# a second connection was opened on the shared-cache (as happened in
# test case shared3-2.3 above). The goal of the following tests is to
# ensure that the cache-size really is 10 pages.
#
#if {$::tcl_platform(platform)=="unix"} {
#  set alternative_name ./test.db
#} else {
#  set alternative_name TEST.DB
if {$::tcl_platform(platform)=="unix"} {
  set alternative_name ./test.db
} else {
  set alternative_name TEST.DB
#}
}
do_test shared3-2.6 {
  #sqlite3 db3 $alternative_name
  sqlite3 db3 $alternative_name
  sqlite3 db3 "file:./test.db?cache=private" -uri 1
  catchsql {select count(*) from sqlite_master} db3
} {0 1}
do_test shared3-2.7 {
  execsql {
    BEGIN;
    INSERT INTO t1 VALUES(10, randomblob(5000))
  } db1
  catchsql {select count(*) from sqlite_master} db3
} {0 1}
do_test shared3-2.8 {
  db3 close
  execsql {
    INSERT INTO t1 VALUES(10, randomblob(10000))
  } db1

  # If the pager-cache is really still limited to 10 pages, then the INSERT
  # statement above should have caused the pager to grab an exclusive lock
  # on the database file so that the cache could be spilled.
  #
  catch { sqlite3 db3 "file:./test.db?cache=private" -uri 1 }
  catch { sqlite3 db3 $alternative_name }
  catchsql {select count(*) from sqlite_master} db3
} {1 {database is locked}}

db1 close
db2 close
db3 close

Changes to test/shell1.test.

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
60
61
62
63
64
65
66




67
68
69
70
71
72
73







-
-
-
-







  list $rc \
       [regexp {Usage} $res] \
       [regexp {\-init} $res] \
       [regexp {\-version} $res]
} {1 1 1 1}

# -init filename       read/process named file
forcedelete FOO
set out [open FOO w]
puts $out ""
close $out
do_test shell1-1.3.1 {
  catchcmd "-init FOO test.db" ""
} {0 {}}
do_test shell1-1.3.2 {
  catchcmd "-init FOO test.db .quit BAD" ""
} {0 {}}
do_test shell1-1.3.3 {
199
200
201
202
203
204
205
206

207
208
209

210
211
212
213
214
215
216
195
196
197
198
199
200
201

202
203
204

205
206
207
208
209
210
211
212







-
+


-
+







  catchcmd "test.db" ".explain \"OFF"
} {0 {}}
do_test shell1-2.2.4 {
  catchcmd "test.db" ".explain \'OFF"
} {0 {}}
do_test shell1-2.2.5 {
  catchcmd "test.db" ".mode \"insert FOO"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}}
do_test shell1-2.2.6 {
  catchcmd "test.db" ".mode \'insert FOO"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}}

# check multiple tokens, and quoted tokens
do_test shell1-2.3.1 {
  catchcmd "test.db" ".explain 1"
} {0 {}}
do_test shell1-2.3.2 {
  catchcmd "test.db" ".explain on"
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
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







-
+
















-







do_test shell1-2.3.7 {
  catchcmd "test.db" ".\'explain\' \'OFF\'"
} {0 {}}

# check quoted args are unquoted
do_test shell1-2.4.1 {
  catchcmd "test.db" ".mode FOO"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}}
do_test shell1-2.4.2 {
  catchcmd "test.db" ".mode csv"
} {0 {}}
do_test shell1-2.4.2 {
  catchcmd "test.db" ".mode \"csv\""
} {0 {}}


#----------------------------------------------------------------------------
# Test cases shell1-3.*: Basic test that "dot" command can be called.
#

# .backup ?DB? FILE      Backup DB (default "main") to FILE
do_test shell1-3.1.1 {
  catchcmd "test.db" ".backup"
} {1 {missing FILENAME argument on .backup}}
forcedelete FOO
do_test shell1-3.1.2 {
  catchcmd "test.db" ".backup FOO"
} {0 {}}
do_test shell1-3.1.3 {
  catchcmd "test.db" ".backup FOO BAR"
} {1 {Error: unknown database FOO}}
do_test shell1-3.1.4 {
298
299
300
301
302
303
304
305
306
307
308
309




310
311
312
313
314
315
316
293
294
295
296
297
298
299





300
301
302
303
304
305
306
307
308
309
310







-
-
-
-
-
+
+
+
+







       [regexp {COMMIT;} $res]
} {1 1}
do_test shell1-3.4.2 {
  set res [catchcmd "test.db" ".dump FOO"]
  list [regexp {BEGIN TRANSACTION;} $res] \
       [regexp {COMMIT;} $res]
} {1 1}
# The .dump command now accepts multiple arguments
#do_test shell1-3.4.3 {
#  # too many arguments
#  catchcmd "test.db" ".dump FOO BAD"
#} {1 {Usage: .dump ?--preserve-rowids? ?--newlines? ?LIKE-PATTERN?}}
do_test shell1-3.4.3 {
  # too many arguments
  catchcmd "test.db" ".dump FOO BAD"
} {1 {Usage: .dump ?--preserve-rowids? ?--newlines? ?LIKE-PATTERN?}}

# .echo ON|OFF           Turn command echo on or off
do_test shell1-3.5.1 {
  catchcmd "test.db" ".echo"
} {1 {Usage: .echo on|off}}
do_test shell1-3.5.2 {
  catchcmd "test.db" ".echo ON"
390
391
392
393
394
395
396
397

398
399
400




401
402
403
404

405
406
407
408
409
410
411
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







-
+


-
+
+
+
+



-
+







       [regexp {.quit} $res] \
       [regexp {.show} $res]
} {1 1 1}

# .import FILE TABLE     Import data from FILE into TABLE
do_test shell1-3.11.1 {
  catchcmd "test.db" ".import"
} {/1 .ERROR: missing FILE argument.*/}
} {1 {Usage: .import FILE TABLE}}
do_test shell1-3.11.2 {
  catchcmd "test.db" ".import FOO"
} {/1 .ERROR: missing TABLE argument.*/}
} {1 {Usage: .import FILE TABLE}}
#do_test shell1-3.11.2 {
#  catchcmd "test.db" ".import FOO BAR"
#} {1 {Error: no such table: BAR}}
do_test shell1-3.11.3 {
  # too many arguments
  catchcmd "test.db" ".import FOO BAR BAD"
} {/1 .ERROR: extra argument: "BAD".*./}
} {1 {Usage: .import FILE TABLE}}

# .indexes ?TABLE?       Show names of all indexes
#                          If TABLE specified, only show indexes for tables
#                          matching LIKE pattern TABLE.
do_test shell1-3.12.1 {
  catchcmd "test.db" ".indexes"
} {0 {}}
431
432
433
434
435
436
437
438

439
440
441
442
443
444
445
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442







-
+







#                          tabs     Tab-separated values
#                          tcl      TCL list elements
do_test shell1-3.13.1 {
  catchcmd "test.db" ".mode"
} {0 {current output mode: list}}
do_test shell1-3.13.2 {
  catchcmd "test.db" ".mode FOO"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}}
do_test shell1-3.13.3 {
  catchcmd "test.db" ".mode csv"
} {0 {}}
do_test shell1-3.13.4 {
  catchcmd "test.db" ".mode column"
} {0 {}}
do_test shell1-3.13.5 {
464
465
466
467
468
469
470
471

472
473
474

475
476
477
478
479
480
481
461
462
463
464
465
466
467

468
469
470

471
472
473
474
475
476
477
478







-
+


-
+







  # extra arguments ignored
  catchcmd "test.db" ".mode tcl BAD"
} {0 {}}

# don't allow partial mode type matches
do_test shell1-3.13.12 {
  catchcmd "test.db" ".mode l"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}}
do_test shell1-3.13.13 {
  catchcmd "test.db" ".mode li"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}}
do_test shell1-3.13.14 {
  catchcmd "test.db" ".mode lin"
} {0 {}}

# .nullvalue STRING      Print STRING in place of NULL values
do_test shell1-3.14.1 {
  catchcmd "test.db" ".nullvalue"
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
491
492
493
494
495
496
497

498







499
500
501
502
503
504
505
506

507







508
509
510
511
512
513
514







-
+
-
-
-
-
-
-
-








-
+
-
-
-
-
-
-
-







} {0 {}}
do_test shell1-3.15.2 {
  catchcmd "test.db" ".output FOO"
} {0 {}}
do_test shell1-3.15.3 {
  # too many arguments
  catchcmd "test.db" ".output FOO BAD"
} {1 {ERROR: extra parameter: "BAD".  Usage:
} {1 {Usage: .output [-e|-x|FILE]}}
.output ?FILE?           Send output to FILE or stdout if FILE is omitted
   If FILE begins with '|' then open it as a pipe.
   Options:
     --bom                 Prefix output with a UTF8 byte-order mark
     -e                    Send output to the system text editor
     -x                    Send output as CSV to a spreadsheet
child process exited abnormally}}

# .output stdout         Send output to the screen
do_test shell1-3.16.1 {
  catchcmd "test.db" ".output stdout"
} {0 {}}
do_test shell1-3.16.2 {
  # too many arguments
  catchcmd "test.db" ".output stdout BAD"
} {1 {ERROR: extra parameter: "BAD".  Usage:
} {1 {Usage: .output [-e|-x|FILE]}}
.output ?FILE?           Send output to FILE or stdout if FILE is omitted
   If FILE begins with '|' then open it as a pipe.
   Options:
     --bom                 Prefix output with a UTF8 byte-order mark
     -e                    Send output to the system text editor
     -x                    Send output as CSV to a spreadsheet
child process exited abnormally}}

# .prompt MAIN CONTINUE  Replace the standard prompts
do_test shell1-3.17.1 {
  catchcmd "test.db" ".prompt"
} {0 {}}
do_test shell1-3.17.2 {
  catchcmd "test.db" ".prompt FOO"
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
567
568
569
570
571
572
573

574
575
576
577
578
579
580
581







-
+







} {0 {}}
do_test shell1-3.21.2 {
  catchcmd "test.db" ".schema FOO"
} {0 {}}
do_test shell1-3.21.3 {
  # too many arguments
  catchcmd "test.db" ".schema FOO BAD"
} {1 {Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?}}
} {1 {Usage: .schema ?--indent? ?LIKE-PATTERN?}}

do_test shell1-3.21.4 {
  catchcmd "test.db" {
     CREATE TABLE t1(x);
     CREATE VIEW v2 AS SELECT x+1 AS y FROM t1;
     CREATE VIEW v1 AS SELECT y+1 FROM v2;
  }
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
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







-
+









-
+







  # 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}}
#} {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|stmt|vmstep?}}
} {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);
710
711
712
713
714
715
716
717

718
719
720
721

722
723
724
725
726
727
728
693
694
695
696
697
698
699

700
701
702
703

704
705
706
707
708
709
710
711







-
+



-
+







  # this should be treated the same as a '0' width for col 1 and 2
} {0 {}}
do_test shell1-3.26.4 {
  catchcmd "test.db" ".width 1 1"
  # this should be treated the same as a '1' width for col 1 and 2
} {0 {}}
do_test shell1-3.26.5 {
  catchcmd "test.db" ".mode column\n.header off\n.width 10 -10\nSELECT 'abcdefg', 123456;"
  catchcmd "test.db" ".mode column\n.width 10 -10\nSELECT 'abcdefg', 123456;"
  # this should be treated the same as a '1' width for col 1 and 2
} {0 {abcdefg         123456}}
do_test shell1-3.26.6 {
  catchcmd "test.db" ".mode column\n.header off\n.width -10 10\nSELECT 'abcdefg', 123456;"
  catchcmd "test.db" ".mode column\n.width -10 10\nSELECT 'abcdefg', 123456;"
  # this should be treated the same as a '1' width for col 1 and 2
} {0 {   abcdefg  123456    }}


# .timer ON|OFF          Turn the CPU timer measurement on or off
do_test shell1-3.27.1 {
  catchcmd "test.db" ".timer"
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
1150
1151
1152
1153
1154
1155
1156





















































1157







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

CREATE TABLE ___ (x TEXT PRIMARY KEY);}}
do_test shell1-7.1.7 {
  catchcmd "test.db" ".schema \\\\_\\\\_\\\\_"
} {0 {CREATE TABLE ___ (x TEXT PRIMARY KEY);}}

}

# Test case for the ieee754 and decimal extensions in the shell.
# See the "floatingpoint.html" file in the documentation for more
# information.
#
do_test shell1-8.1 {
  catchcmd ":memory:" {
    -- The pow2 table will hold all the necessary powers of two.
    CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
    WITH RECURSIVE c(x,v) AS (
      VALUES(0,'1')
      UNION ALL
      SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971
    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
    WITH RECURSIVE c(x,v) AS (
      VALUES(-1,'0.5')
      UNION ALL
      SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075
    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
    
    -- This query finds the decimal representation of each value in the "c" table.
    WITH c(n) AS (VALUES(47.49))
                     ----XXXXX----------- Replace with whatever you want
    SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
  }
} {0 47.49000000000000198951966012828052043914794921875}
do_test shell1-8.2 {
  catchcmd :memory: {
.mode box
SELECT ieee754(47.49) AS x;
  }
} {0 {┌───────────────────────────────┐
│               x               │
├───────────────────────────────┤
│ ieee754(6683623321994527,-47) │
└───────────────────────────────┘}}
do_test shell1-8.3 {
  catchcmd ":memory: --box" {
    select ieee754(6683623321994527,-47) as x;
  }
} {0 {┌───────┐
│   x   │
├───────┤
│ 47.49 │
└───────┘}}
do_test shell1-8.4 {
  catchcmd ":memory: --table" {SELECT ieee754_mantissa(47.49) AS M, ieee754_exponent(47.49) AS E;}
} {0 {+------------------+-----+
|        M         |  E  |
+------------------+-----+
| 6683623321994527 | -47 |
+------------------+-----+}}

finish_test

Changes to test/shell4.test.

62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
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?}}
} {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}

Changes to test/shell5.test.

28
29
30
31
32
33
34
35

36
37
38




39
40
41
42

43
44
45
46
47
48
49
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







-
+


-
+
+
+
+



-
+







#----------------------------------------------------------------------------
# Test cases shell5-1.*: Basic handling of the .import and .separator commands.
#

# .import FILE TABLE     Import data from FILE into TABLE
do_test shell5-1.1.1 {
  catchcmd "test.db" ".import"
} {/1 .ERROR: missing FILE argument.*/}
} {1 {Usage: .import FILE TABLE}}
do_test shell5-1.1.2 {
  catchcmd "test.db" ".import FOO"
} {/1 .ERROR: missing TABLE argument.*/}
} {1 {Usage: .import FILE TABLE}}
#do_test shell5-1.1.2 {
#  catchcmd "test.db" ".import FOO BAR"
#} {1 {Error: no such table: BAR}}
do_test shell5-1.1.3 {
  # too many arguments
  catchcmd "test.db" ".import FOO BAR BAD"
} {/1 .ERROR: extra argument.*/}
} {1 {Usage: .import FILE TABLE}}

# .separator STRING      Change separator used by output mode and .import
do_test shell5-1.2.1 {
  catchcmd "test.db" ".separator"
} {1 {Usage: .separator COL ?ROW?}}
do_test shell5-1.2.2 {
  catchcmd "test.db" ".separator ONE"

Changes to test/skipscan1.test.

230
231
232
233
234
235
236

237
238
239
240
241
242
243
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244







+







  EXPLAIN QUERY PLAN
    SELECT xh, loc FROM t5 WHERE loc >= 'M' AND loc < 'N';
} {/.*COVERING INDEX t5i1 .*/}
do_execsql_test skipscan1-5.2 {
  ANALYZE;
  DELETE FROM sqlite_stat1;
  DROP TABLE IF EXISTS sqlite_stat4;
  DROP TABLE IF EXISTS sqlite_stat3;
  INSERT INTO sqlite_stat1 VALUES('t5','t5i1','2702931 3 2 2 2 2');
  INSERT INTO sqlite_stat1 VALUES('t5','t5i2','2702931 686 2 2 2');
  ANALYZE sqlite_master;
} {}
db cache flush
do_execsql_test skipscan1-5.3 {
  EXPLAIN QUERY PLAN
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
369
370
371
372
373
374
375















































376







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  EXPLAIN QUERY PLAN
  SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a DESC;
} {/* USING INDEX t6abc (ANY(a) AND b=?)*/}
do_execsql_test skipscan1-2.3 {
  SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a DESC;
} {}

# 2019-07-29 Ticket ced41c7c7d6b4d36
# A skipscan query is not order-distinct
#
db close
sqlite3 db :memory:
do_execsql_test skipscan1-3.1 {
  CREATE TABLE t1 (c1, c2, c3, c4, PRIMARY KEY(c4, c3));
  INSERT INTO t1 VALUES(3,0,1,NULL);
  INSERT INTO t1 VALUES(0,4,1,NULL);
  INSERT INTO t1 VALUES(5,6,1,NULL);
  INSERT INTO t1 VALUES(0,4,1,NULL);
  ANALYZE sqlite_master;
  INSERT INTO sqlite_stat1 VALUES('t1','sqlite_autoindex_t1_1','18 18 6');
  ANALYZE sqlite_master;
  SELECT DISTINCT quote(c1), quote(c2), quote(c3), quote(c4), '|'
    FROM t1 WHERE t1.c3 = 1;
} {3 0 1 NULL | 0 4 1 NULL | 5 6 1 NULL |}
do_eqp_test skipscan1-3.2 {
  SELECT DISTINCT quote(c1), quote(c2), quote(c3), quote(c4), '|'
    FROM t1 WHERE t1.c3 = 1;
} {
  QUERY PLAN
  |--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (ANY(c4) AND c3=?)
  `--USE TEMP B-TREE FOR DISTINCT
}

# 2020-01-06 ticket 304017f5f04a0035
#
reset_db
do_execsql_test skipscan1-4.10 {
  CREATE TABLE t1(a,b INT);
  INSERT INTO t1(a,b) VALUES(1,2),(3,3),(4,5);
  CREATE UNIQUE INDEX i1 ON t1(b,b,a,a,a,a,a,b,a);
  ANALYZE;
  DROP TABLE IF EXISTS sqlite_stat4;
  INSERT INTO sqlite_stat1 VALUES('t1','i1','30 30 30 2 2 2 2 2 2 2');
  ANALYZE sqlite_master;

  SELECT DISTINCT a
    FROM t1
   WHERE a = b
     AND a = 3
     AND b IN (1,3,2,4)
     AND b >= 0
     AND a <= 10;
} {3}

finish_test

Changes to test/skipscan5.test.

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
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







-
+












-
+








-
+







do_execsql_test 1.1 {
  CREATE TABLE t1(a INT, b INT, c INT);
  CREATE INDEX i1 ON t1(a, b);
} {}

expr srand(4)
do_test 1.2 {
  for {set i 0} {$i < 1000} {incr i} {
  for {set i 0} {$i < 100} {incr i} {
    set a [expr int(rand()*4.0) + 1]
    set b [expr int(rand()*20.0) + 1]
    execsql { INSERT INTO t1 VALUES($a, $b, NULL) }
  }
  execsql ANALYZE
} {}

foreach {tn q res} {
  1  "b = 5"                   {/*ANY(a) AND b=?*/}
  2  "b > 12 AND b < 16"       {/*ANY(a) AND b>? AND b<?*/}
  3  "b > 2 AND b < 16"        {/*SCAN TABLE t1*/}
  4  "b > 18 AND b < 25"       {/*ANY(a) AND b>? AND b<?*/}
  5  "b > 16"                  {/*ANY(a) AND b>?*/}
  5  "b > 15"                  {/*ANY(a) AND b>?*/}
  6  "b > 5"                   {/*SCAN TABLE t1*/}
  7  "b < 15"                  {/*SCAN TABLE t1*/}
  8  "b < 5"                   {/*ANY(a) AND b<?*/}
  9  "5 > b"                   {/*ANY(a) AND b<?*/}
  10 "b = '5'"                 {/*ANY(a) AND b=?*/}
  11 "b > '12' AND b < '16'"   {/*ANY(a) AND b>? AND b<?*/}
  12 "b > '2' AND b < '16'"    {/*SCAN TABLE t1*/}
  13 "b > '18' AND b < '25'"   {/*ANY(a) AND b>? AND b<?*/}
  14 "b > '16'"                {/*ANY(a) AND b>?*/}
  14 "b > '15'"                {/*ANY(a) AND b>?*/}
  15 "b > '5'"                 {/*SCAN TABLE t1*/}
  16 "b < '15'"                {/*SCAN TABLE t1*/}
  17 "b < '5'"                 {/*ANY(a) AND b<?*/}
  18 "'5' > b"                 {/*ANY(a) AND b<?*/}
} {
  set sql "EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE $q"
  do_execsql_test 1.3.$tn $sql $res
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118







-
+








  foreach {tn2 q res} {
    1 { c BETWEEN 'd' AND 'e' }       {/*ANY(a) AND ANY(b) AND c>? AND c<?*/}
    2 { c BETWEEN 'b' AND 'r' }       {/*SCAN TABLE t2*/}
    3 { c > 'q' }                     {/*ANY(a) AND ANY(b) AND c>?*/}
    4 { c > 'e' }                     {/*SCAN TABLE t2*/}
    5 { c < 'q' }                     {/*SCAN TABLE t2*/}
    6 { c < 'b' }                     {/*ANY(a) AND ANY(b) AND c<?*/}
    6 { c < 'c' }                     {/*ANY(a) AND ANY(b) AND c<?*/}
  } {
    set sql "EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE $q" 
    do_execsql_test 2.$tn.$tn2 $sql $res
  }

}

Changes to test/speedtest1.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
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









-
+
-







-





-





-















+



















-
-
-
-
-
-
-
-
-
-
-
-
-
-
















-
-




-


-
-
-
-







+










-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







/*
** A program for performance testing.
**
** The available command-line options are described below:
*/
static const char zHelp[] =
  "Usage: %s [--options] DATABASE\n"
  "Options:\n"
  "  --autovacuum        Enable AUTOVACUUM mode\n"
  "  --cachesize N       Set the cache size to N\n"
  "  --cachesize N       Set the cache size to N\n" 
  "  --checkpoint        Run PRAGMA wal_checkpoint after each test case\n"
  "  --exclusive         Enable locking_mode=EXCLUSIVE\n"
  "  --explain           Like --sqlonly but with added EXPLAIN keywords\n"
  "  --heap SZ MIN       Memory allocator uses SZ bytes & min allocation MIN\n"
  "  --incrvacuum        Enable incremenatal vacuum mode\n"
  "  --journal M         Set the journal_mode to M\n"
  "  --key KEY           Set the encryption key to KEY\n"
  "  --lookaside N SZ    Configure lookaside for N slots of SZ bytes each\n"
  "  --memdb             Use an in-memory database\n"
  "  --mmap SZ           MMAP the first SZ bytes of the database file\n"
  "  --multithread       Set multithreaded mode\n"
  "  --nomemstat         Disable memory statistics\n"
  "  --nosync            Set PRAGMA synchronous=OFF\n"
  "  --notnull           Add NOT NULL constraints to table columns\n"
  "  --output FILE       Store SQL output in FILE\n"
  "  --pagesize N        Set the page size to N\n"
  "  --pcache N SZ       Configure N pages of pagecache each of size SZ bytes\n"
  "  --primarykey        Use PRIMARY KEY instead of UNIQUE where appropriate\n"
  "  --repeat N          Repeat each SELECT N times (default: 1)\n"
  "  --reprepare         Reprepare each statement upon every invocation\n"
  "  --reserve N         Reserve N bytes on each database page\n"
  "  --serialized        Set serialized threading mode\n"
  "  --singlethread      Set single-threaded mode - disables all mutexing\n"
  "  --sqlonly           No-op.  Only show the SQL that would have been run.\n"
  "  --shrink-memory     Invoke sqlite3_db_release_memory() frequently.\n"
  "  --size N            Relative test size.  Default=100\n"
  "  --stats             Show statistics at the end\n"
  "  --temp N            N from 0 to 9.  0: no temp table. 9: all temp tables\n"
  "  --testset T         Run test-set T (main, cte, rtree, orm, fp, debug)\n"
  "  --trace             Turn on SQL tracing\n"
  "  --threads N         Use up to N threads for sorting\n"
  "  --utf16be           Set text encoding to UTF-16BE\n"
  "  --utf16le           Set text encoding to UTF-16LE\n"
  "  --verify            Run additional verification steps.\n"
  "  --without-rowid     Use WITHOUT ROWID where appropriate\n"
;


#include "sqlite3.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#ifndef _WIN32
# include <unistd.h>
#else
# include <io.h>
#endif
#define ISSPACE(X) isspace((unsigned char)(X))
#define ISDIGIT(X) isdigit((unsigned char)(X))

#if SQLITE_VERSION_NUMBER<3005000
# define sqlite3_int64 sqlite_int64
#endif

typedef sqlite3_uint64 u64;

/*
** State structure for a Hash hash in progress
*/
typedef struct HashContext HashContext;
struct HashContext {
  unsigned char isInit;          /* True if initialized */
  unsigned char i, j;            /* State variables */
  unsigned char s[256];          /* State variables */
  unsigned char r[32];           /* Result */
};


/* All global state is held in this structure */
static struct Global {
  sqlite3 *db;               /* The open database connection */
  sqlite3_stmt *pStmt;       /* Current SQL statement */
  sqlite3_int64 iStart;      /* Start-time for the current test */
  sqlite3_int64 iTotal;      /* Total time */
  int bWithoutRowid;         /* True for --without-rowid */
  int bReprepare;            /* True to reprepare the SQL on each rerun */
  int bSqlOnly;              /* True to print the SQL once only */
  int bExplain;              /* Print SQL with EXPLAIN prefix */
  int bVerify;               /* Try to verify that results are correct */
  int bMemShrink;            /* Call sqlite3_db_release_memory() often */
  int eTemp;                 /* 0: no TEMP.  9: always TEMP. */
  int szTest;                /* Scale factor for test iterations */
  int nRepeat;               /* Repeat selects this many times */
  int doCheckpoint;          /* Run PRAGMA wal_checkpoint after each trans */
  int nReserve;              /* Reserve bytes */
  const char *zWR;           /* Might be WITHOUT ROWID */
  const char *zNN;           /* Might be NOT NULL */
  const char *zPK;           /* Might be UNIQUE or PRIMARY KEY */
  unsigned int x, y;         /* Pseudo-random number generator state */
  u64 nResByte;              /* Total number of result bytes */
  int nResult;               /* Size of the current result */
  char zResult[3000];        /* Text of the current result */
#ifndef SPEEDTEST_OMIT_HASH
  FILE *hashFile;            /* Store all hash results in this file */
  HashContext hash;          /* Hash of all output */
#endif
} g;

/* Return " TEMP" or "", as appropriate for creating a table.
*/
static const char *isTemp(int N){
  return g.eTemp>=N ? " TEMP" : "";
}


/* Print an error message and exit */
static void fatal_error(const char *zMsg, ...){
  va_list ap;
  va_start(ap, zMsg);
  vfprintf(stderr, zMsg, ap);
  va_end(ap);
  exit(1);
}

#ifndef SPEEDTEST_OMIT_HASH
/****************************************************************************
** Hash algorithm used to verify that compilation is not miscompiled
** in such a was as to generate an incorrect result.
*/

/*
** Initialize a new hash.  iSize determines the size of the hash
** in bits and should be one of 224, 256, 384, or 512.  Or iSize
** can be zero to use the default hash size of 256 bits.
*/
static void HashInit(void){
  unsigned int k;
  g.hash.i = 0;
  g.hash.j = 0;
  for(k=0; k<256; k++) g.hash.s[k] = k;
}

/*
** Make consecutive calls to the HashUpdate function to add new content
** to the hash
*/
static void HashUpdate(
  const unsigned char *aData,
  unsigned int nData
){
  unsigned char t;
  unsigned char i = g.hash.i;
  unsigned char j = g.hash.j;
  unsigned int k;
  if( g.hashFile ) fwrite(aData, 1, nData, g.hashFile);
  for(k=0; k<nData; k++){
    j += g.hash.s[i] + aData[k];
    t = g.hash.s[j];
    g.hash.s[j] = g.hash.s[i];
    g.hash.s[i] = t;
    i++;
  }
  g.hash.i = i;
  g.hash.j = j;
}

/*
** After all content has been added, invoke HashFinal() to compute
** the final hash.  The hash result is stored in g.hash.r[].
*/
static void HashFinal(void){
  unsigned int k;
  unsigned char t, i, j;
  i = g.hash.i;
  j = g.hash.j;
  for(k=0; k<32; k++){
    i++;
    t = g.hash.s[i];
    j += t;
    g.hash.s[i] = g.hash.s[j];
    g.hash.s[j] = t;
    t += g.hash.s[i];
    g.hash.r[k] = g.hash.s[t];
  }
}

/* End of the Hash hashing logic
*****************************************************************************/
#endif /* SPEEDTEST_OMIT_HASH */

/*
** 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;
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
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







-
-
-



-
















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  sqlite3_free(zName);
  g.nResult = 0;
  g.iStart = speedtest1_timestamp();
  g.x = 0xad131d0b;
  g.y = 0x44f9eac8;
}

/* Forward reference */
void speedtest1_exec(const char*,...);

/* Complete a test case */
void speedtest1_end_test(void){
  sqlite3_int64 iElapseTime = speedtest1_timestamp() - g.iStart;
  if( g.doCheckpoint ) speedtest1_exec("PRAGMA wal_checkpoint;");
  if( !g.bSqlOnly ){
    g.iTotal += iElapseTime;
    printf("%4d.%03ds\n", (int)(iElapseTime/1000), (int)(iElapseTime%1000));
  }
  if( g.pStmt ){
    sqlite3_finalize(g.pStmt);
    g.pStmt = 0;
  }
}

/* Report end of testing */
void speedtest1_final(void){
  if( !g.bSqlOnly ){
    printf("       TOTAL%.*s %4d.%03ds\n", NAMEWIDTH-5, zDots,
           (int)(g.iTotal/1000), (int)(g.iTotal%1000));
  }
  if( g.bVerify ){
#ifndef SPEEDTEST_OMIT_HASH
    int i;
#endif
    printf("Verification Hash: %llu ", g.nResByte);
#ifndef SPEEDTEST_OMIT_HASH
    HashUpdate((const unsigned char*)"\n", 1);
    HashFinal();
    for(i=0; i<24; i++){
      printf("%02x", g.hash.r[i]);
    }
    if( g.hashFile && g.hashFile!=stdout ) fclose(g.hashFile);
#endif
    printf("\n");
  }
}

/* Print an SQL statement to standard output */
static void printSql(const char *zSql){
  int n = (int)strlen(zSql);
  while( n>0 && (zSql[n-1]==';' || ISSPACE(zSql[n-1])) ){ n--; }
  if( g.bExplain ) printf("EXPLAIN ");
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
368
369
370
371
372
373
374






























375
376
377
378
379
380
381







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    if( zErrMsg ) fatal_error("SQL error: %s\n%s\n", zErrMsg, zSql);
    if( rc!=SQLITE_OK ) fatal_error("exec error: %s\n", sqlite3_errmsg(g.db));
  }
  sqlite3_free(zSql);
  speedtest1_shrink_memory();
}

/* Run SQL and return the first column of the first row as a string.  The
** returned string is obtained from sqlite_malloc() and must be freed by
** the caller.
*/
char *speedtest1_once(const char *zFormat, ...){
  va_list ap;
  char *zSql;
  sqlite3_stmt *pStmt;
  char *zResult = 0;
  va_start(ap, zFormat);
  zSql = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
  if( g.bSqlOnly ){
    printSql(zSql);
  }else{
    int rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
    if( rc ){
      fatal_error("SQL error: %s\n", sqlite3_errmsg(g.db));
    }
    if( sqlite3_step(pStmt)==SQLITE_ROW ){
      const char *z = (const char*)sqlite3_column_text(pStmt, 0);
      if( z ) zResult = sqlite3_mprintf("%s", z);
    }
    sqlite3_finalize(pStmt);
  }
  sqlite3_free(zSql);
  speedtest1_shrink_memory();
  return zResult;
}

/* Prepare an SQL statement */
void speedtest1_prepare(const char *zFormat, ...){
  va_list ap;
  char *zSql;
  va_start(ap, zFormat);
  zSql = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
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
400
401
402
403
404
405
406

































407
408
409
410
411
412
413







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  g.nResult = 0;
  while( sqlite3_step(g.pStmt)==SQLITE_ROW ){
    n = sqlite3_column_count(g.pStmt);
    for(i=0; i<n; i++){
      const char *z = (const char*)sqlite3_column_text(g.pStmt, i);
      if( z==0 ) z = "nil";
      len = (int)strlen(z);
#ifndef SPEEDTEST_OMIT_HASH
      if( g.bVerify ){
        int eType = sqlite3_column_type(g.pStmt, i);
        unsigned char zPrefix[2];
        zPrefix[0] = '\n';
        zPrefix[1] = "-IFTBN"[eType];
        if( g.nResByte ){
          HashUpdate(zPrefix, 2);
        }else{
          HashUpdate(zPrefix+1, 1);
        }
        if( eType==SQLITE_FLOAT ){
          /* Omit the value of floating-point results from the verification
          ** hash.  The only thing we record is the fact that the result was
          ** a floating-point value. */
          g.nResByte += 2;
        }else if( eType==SQLITE_BLOB ){
          int nBlob = sqlite3_column_bytes(g.pStmt, i);
          int iBlob;
          unsigned char zChar[2];
          const unsigned char *aBlob = sqlite3_column_blob(g.pStmt, i);
          for(iBlob=0; iBlob<nBlob; iBlob++){
            zChar[0] = "0123456789abcdef"[aBlob[iBlob]>>4];
            zChar[1] = "0123456789abcdef"[aBlob[iBlob]&15];
            HashUpdate(zChar,2);
          }
          g.nResByte += nBlob*2 + 2;
        }else{
          HashUpdate((unsigned char*)z, len);
          g.nResByte += len + 2;
        }
      }
#endif
      if( g.nResult+len<sizeof(g.zResult)-2 ){
        if( g.nResult>0 ) g.zResult[g.nResult++] = ' ';
        memcpy(g.zResult + g.nResult, z, len+1);
        g.nResult += len;
      }
    }
  }
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
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







-
+

-
+
















-
+

-
+







  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);",
  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 z1 VALUES(?1,?2,?3); --  %d times", n);
  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 z2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
     "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 z2 VALUES(?1,?2,?3); -- %d times", n);
  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();
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
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







-
+



















-
+







                          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"
    "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 z1\n"
    "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);
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
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682




683
684
685
686
687
688
689
690
691
692
693
694
695

696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715

716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743







-
+




















-
+



















-
-
-
-
+
+
+
+









-
+



















-
+



















-
+







  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"
    "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 z1 WHERE c LIKE ?1\n"
    "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 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 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 z1\n"
    "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 z2\n"
    "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 z1\n"
    "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);
    }
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
755
756
757
758
759
760
761

762
763
764
765
766
767


768
769
770
771
772
773
774
775
776
777
778


779
780
781
782
783
784
785
786
787

788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

805
806
807
808
809
810
811
812
813
814
815

816
817
818
819
820

821
822
823
824
825
826
827
828
829

830
831
832
833
834
835
836
837







-
+





-
-
+
+









-
-
+
+







-
+
















-
+










-
+




-
+








-
+







    "  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("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 z2;");
  speedtest1_exec("INSERT INTO z2 SELECT * FROM z1;");
  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 z2 ADD COLUMN d DEFAULT 123");
  speedtest1_exec("SELECT sum(d) FROM z2");
  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 z2 SET d=b*2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
    "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 z2 SET d=b*3 WHERE a=?1; -- %d times", n
    "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 z2 SET d=b*4");
  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 z2");
  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 z2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
    "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();
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
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







-
-
+
+



-
-
-
-
-
+
+
+
+
+







-
+


-
-
+
+














-
-
+
+







    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_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 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_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 z1.c FROM z1, z2, t3, t4\n"
    "SELECT t1.c FROM t1, t2, 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"
    "   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 z2 WHERE 5+z2.b=z1.b) AND rowid<?1), max(c)\n"
    " FROM z1 WHERE rowid<?1;"
    "       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;
1278
1279
1280
1281
1282
1283
1284
1285
1286


1287
1288

1289
1290
1291
1292
1293
1294
1295
1107
1108
1109
1110
1111
1112
1113


1114
1115
1116

1117
1118
1119
1120
1121
1122
1123
1124







-
-
+
+

-
+







  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"
    "  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 z1 EXCEPT SELECT y FROM z2 ORDER BY 1\n"
    "  SELECT x FROM t1 EXCEPT SELECT y FROM t2 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
1383
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







-
+

-
+












-
+











-
-
-
+
+
+





-
+







-
-
-
-
-
-
-
-
-
-
-
-
-







  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);",
  speedtest1_exec("CREATE%s TABLE t1(a REAL %s, b REAL %s);",
                  isTemp(1), g.zNN, g.zNN);
  speedtest1_prepare("INSERT INTO z1 VALUES(?1,?2); -- %d times", n);
  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 z1 WHERE a BETWEEN ?1 AND ?2");
  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 z1(a);");
  speedtest1_exec("CREATE INDEX t1b ON z1(b);");
  speedtest1_exec("CREATE INDEX t1ab ON z1(a,b);");
  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 z1 WHERE a BETWEEN ?1 AND ?2");
  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 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
** be far apart.
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
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







-
-
+
+

















-
+







    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_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 z1 WHERE x0>=?1 AND x1<=?2");
    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",
1502
1503
1504
1505
1506
1507
1508
1509

1510
1511
1512
1513
1514
1515
1516
1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1332







-
+







    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");
    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",
1598
1599
1600
1601
1602
1603
1604
1605

1606
1607
1608
1609
1610
1611
1612
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
1428







-
+







    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_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.
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
1699
1700
1701
1702
1703
1704
1705


1706
1707
1708


1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723


1724
1725
1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737
1738

1739
1740
1741
1742
1743
1744
1745
1746







-
-
+
+

-
-
+
+













-
-
+
+






-
+






-
+







  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 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 z1;"
      "CREATE VIEW v2 AS SELECT rowid, i, t FROM z2;"
      "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 z1(t);"
      "CREATE INDEX i2 ON z2(t);"
      "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 z1, z2, t3 WHERE z1.oid = z2.oid AND z2.oid = t3.oid"
      "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 z1, z2, t3 WHERE z1.t = z2.t AND z2.t = t3.t"
      "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);
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
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







-
-
+
+










-
+









-
+







      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 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 z1 SET i=i+1 WHERE rowid=?1");
  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 z1");
  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);"
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
1949
1950
1951
1952
1953
1954
1955




1956
1957
1958
1959
1960
1961
1962







-
-
-
-







}   
#endif

#if SQLITE_VERSION_NUMBER<3006018
#  define sqlite3_sourceid(X) "(before 3.6.18)"
#endif

#if SQLITE_CKSUMVFS_STATIC
int sqlite3_register_cksumvfs(const char*);
#endif

static int xCompileOptions(void *pCtx, int nVal, char **azVal, char **azCol){
  printf("-- Compile option: %s\n", azVal[0]);
  return SQLITE_OK;
}

int main(int argc, char **argv){
  int doAutovac = 0;            /* True for --autovacuum */
2158
2159
2160
2161
2162
2163
2164
2165
2166

2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183

2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
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







-
-
+











-
-
-
-

-
+




















-
-







  int noSync = 0;               /* True for --nosync */
  int pageSize = 0;             /* Desired page size.  0 means default */
  int nPCache = 0, szPCache = 0;/* --pcache configuration */
  int doPCache = 0;             /* True if --pcache is seen */
  int showStats = 0;            /* True for --stats */
  int nThread = 0;              /* --threads value */
  int mmapSize = 0;             /* How big of a memory map to use */
  int memDb = 0;                /* --memdb.  Use an in-memory database */
  char *zTSet = "main";         /* Which --testset torun */
  const char *zTSet = "main";   /* Which --testset torun */
  int doTrace = 0;              /* True for --trace */
  const char *zEncoding = 0;    /* --utf16be or --utf16le */
  const char *zDbName = 0;      /* Name of the test database */

  void *pHeap = 0;              /* Allocated heap space */
  void *pLook = 0;              /* Allocated lookaside space */
  void *pPCache = 0;            /* Allocated storage for pcache */
  int iCur, iHi;                /* Stats values, current and "highwater" */
  int i;                        /* Loop counter */
  int rc;                       /* API return code */

#ifdef SQLITE_CKSUMVFS_STATIC
  sqlite3_register_cksumvfs(0);
#endif

  /* Display the version of SQLite being tested */
  printf("-- Speedtest1 for SQLite %s %.48s\n",
  printf("-- Speedtest1 for SQLite %s %.50s\n",
         sqlite3_libversion(), sqlite3_sourceid());

  /* Process command-line arguments */
  g.zWR = "";
  g.zNN = "";
  g.zPK = "UNIQUE";
  g.szTest = 100;
  g.nRepeat = 1;
  for(i=1; i<argc; i++){
    const char *z = argv[i];
    if( z[0]=='-' ){
      do{ z++; }while( z[0]=='-' );
      if( strcmp(z,"autovacuum")==0 ){
        doAutovac = 1;
      }else if( strcmp(z,"cachesize")==0 ){
        if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
        i++;
        cacheSize = integerValue(argv[i]);
      }else if( strcmp(z,"exclusive")==0 ){
        doExclusive = 1;
      }else if( strcmp(z,"checkpoint")==0 ){
        g.doCheckpoint = 1;
      }else if( strcmp(z,"explain")==0 ){
        g.bSqlOnly = 1;
        g.bExplain = 1;
      }else if( strcmp(z,"heap")==0 ){
        if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
        nHeap = integerValue(argv[i+1]);
        mnHeap = integerValue(argv[i+2]);
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
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







-
-















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







        if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
        zKey = argv[++i];
      }else if( strcmp(z,"lookaside")==0 ){
        if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
        nLook = integerValue(argv[i+1]);
        szLook = integerValue(argv[i+2]);
        i += 2;
      }else if( strcmp(z,"memdb")==0 ){
        memDb = 1;
#if SQLITE_VERSION_NUMBER>=3006000
      }else if( strcmp(z,"multithread")==0 ){
        sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
      }else if( strcmp(z,"nomemstat")==0 ){
        sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0);
#endif
#if SQLITE_VERSION_NUMBER>=3007017
      }else if( strcmp(z, "mmap")==0 ){
        if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
        mmapSize = integerValue(argv[++i]);
 #endif
      }else if( strcmp(z,"nosync")==0 ){
        noSync = 1;
      }else if( strcmp(z,"notnull")==0 ){
        g.zNN = "NOT NULL";
      }else if( strcmp(z,"output")==0 ){
#ifdef SPEEDTEST_OMIT_HASH
        fatal_error("The --output option is not supported with"
                    " -DSPEEDTEST_OMIT_HASH\n");
#else
        if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
        i++;
        if( strcmp(argv[i],"-")==0 ){
          g.hashFile = stdout;
        }else{
          g.hashFile = fopen(argv[i], "wb");
          if( g.hashFile==0 ){
            fatal_error("cannot open \"%s\" for writing\n", argv[i]);
          }
        }
#endif
      }else if( strcmp(z,"pagesize")==0 ){
        if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
        pageSize = integerValue(argv[++i]);
      }else if( strcmp(z,"pcache")==0 ){
        if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
        nPCache = integerValue(argv[i+1]);
        szPCache = integerValue(argv[i+2]);
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2093
2094
2095
2096
2097
2098
2099






2100
2101
2102
2103
2104
2105
2106







-
-
-
-
-
-







        nThread = integerValue(argv[++i]);
      }else if( strcmp(z,"utf16le")==0 ){
        zEncoding = "utf16le";
      }else if( strcmp(z,"utf16be")==0 ){
        zEncoding = "utf16be";
      }else if( strcmp(z,"verify")==0 ){
        g.bVerify = 1;
#ifndef SPEEDTEST_OMIT_HASH
        HashInit();
#endif
      }else if( strcmp(z,"reserve")==0 ){
        if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
        g.nReserve = atoi(argv[++i]);
      }else if( strcmp(z,"without-rowid")==0 ){
        g.zWR = "WITHOUT ROWID";
        g.zPK = "PRIMARY KEY";
      }else if( strcmp(z, "help")==0 || strcmp(z,"?")==0 ){
        printf(zHelp, argv[0]);
        exit(0);
      }else{
2350
2351
2352
2353
2354
2355
2356
2357
2358

2359
2360

2361
2362
2363
2364
2365
2366

2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2131
2132
2133
2134
2135
2136
2137


2138
2139

2140
2141
2142
2143
2144
2145

2146
2147
2148
2149



2150
2151
2152
2153
2154
2155



2156
2157
2158
2159
2160
2161
2162







-
-
+

-
+





-
+



-
-
-






-
-
-







    rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
    if( rc ) fatal_error("pcache configuration failed: %d\n", rc);
  }
  if( nLook>=0 ){
    sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
  }
#endif
  sqlite3_initialize();

 
  /* Open the database and the input file */
  if( sqlite3_open(memDb ? ":memory:" : zDbName, &g.db) ){
  if( sqlite3_open(zDbName, &g.db) ){
    fatal_error("Cannot open database file: %s\n", zDbName);
  }
#if SQLITE_VERSION_NUMBER>=3006001
  if( nLook>0 && szLook>0 ){
    pLook = malloc( nLook*szLook );
    rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE,pLook,szLook,nLook);
    rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook);
    if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
  }
#endif
  if( g.nReserve>0 ){
    sqlite3_file_control(g.db, 0, SQLITE_FCNTL_RESERVE_BYTES, &g.nReserve);
  }

  /* Set database connection options */
  sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0);
#ifndef SQLITE_OMIT_DEPRECATED
  if( doTrace ) sqlite3_trace(g.db, traceCallback, 0);
#endif
  if( memDb>0 ){
    speedtest1_exec("PRAGMA temp_store=memory");
  }
  if( mmapSize>0 ){
    speedtest1_exec("PRAGMA mmap_size=%d", mmapSize);
  }
  speedtest1_exec("PRAGMA threads=%d", nThread);
  if( zKey ){
    speedtest1_exec("PRAGMA key('%s')", zKey);
  }
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436













2437
2438

2439
2440
2441


2442
2443
2444
2445



2446
2447
2448

2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460

2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2179
2180
2181
2182
2183
2184
2185

























2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199

2200
2201


2202
2203
2204



2205
2206
2207



2208












2209













2210
2211
2212
2213
2214
2215
2216







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+

-
-
+
+

-
-
-
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-







    speedtest1_exec("PRAGMA locking_mode=EXCLUSIVE");
  }
  if( zJMode ){
    speedtest1_exec("PRAGMA journal_mode=%s", zJMode);
  }

  if( g.bExplain ) printf(".explain\n.echo on\n");
  do{
    char *zThisTest = zTSet;
    char *zComma = strchr(zThisTest,',');
    if( zComma ){
      *zComma = 0;
      zTSet = zComma+1;
    }else{
      zTSet = "";
    }
    if( g.iTotal>0 || zComma!=0 ){
      printf("       Begin testset \"%s\"\n", zThisTest);
    }
    if( strcmp(zThisTest,"main")==0 ){
      testset_main();
    }else if( strcmp(zThisTest,"debug1")==0 ){
      testset_debug1();
    }else if( strcmp(zThisTest,"orm")==0 ){
      testset_orm();
    }else if( strcmp(zThisTest,"cte")==0 ){
      testset_cte();
    }else if( strcmp(zThisTest,"fp")==0 ){
      testset_fp();
    }else if( strcmp(zThisTest,"trigger")==0 ){
      testset_trigger();
    }else if( strcmp(zThisTest,"rtree")==0 ){
  if( strcmp(zTSet,"main")==0 ){
    testset_main();
  }else if( strcmp(zTSet,"debug1")==0 ){
    testset_debug1();
  }else if( strcmp(zTSet,"orm")==0 ){
    testset_orm();
  }else if( strcmp(zTSet,"cte")==0 ){
    testset_cte();
  }else if( strcmp(zTSet,"fp")==0 ){
    testset_fp();
  }else if( strcmp(zTSet,"trigger")==0 ){
    testset_trigger();
  }else if( strcmp(zTSet,"rtree")==0 ){
#ifdef SQLITE_ENABLE_RTREE
      testset_rtree(6, 147);
    testset_rtree(6, 147);
#else
      fatal_error("compile with -DSQLITE_ENABLE_RTREE to enable "
                  "the R-Tree tests\n");
    fatal_error("compile with -DSQLITE_ENABLE_RTREE to enable "
                "the R-Tree tests\n");
#endif
    }else{
      fatal_error("unknown testset: \"%s\"\n"
                  "Choices: cte debug1 fp main orm rtree trigger\n",
  }else{
    fatal_error("unknown testset: \"%s\"\n"
                "Choices: cte debug1 fp main orm rtree trigger\n",
                   zThisTest);
    }
    if( zTSet[0] ){
                 zTSet);
      char *zSql, *zObj;
      speedtest1_begin_test(999, "Reset the database");
      while( 1 ){
        zObj = speedtest1_once(
             "SELECT name FROM main.sqlite_master"
             " WHERE sql LIKE 'CREATE %%TABLE%%'");
        if( zObj==0 ) break;
        zSql = sqlite3_mprintf("DROP TABLE main.\"%w\"", zObj);
        speedtest1_exec(zSql);
        sqlite3_free(zSql);
        sqlite3_free(zObj);
      }
  }
      while( 1 ){
        zObj = speedtest1_once(
             "SELECT name FROM temp.sqlite_master"
             " WHERE sql LIKE 'CREATE %%TABLE%%'");
        if( zObj==0 ) break;
        zSql = sqlite3_mprintf("DROP TABLE main.\"%w\"", zObj);
        speedtest1_exec(zSql);
        sqlite3_free(zSql);
        sqlite3_free(zObj);
      }
      speedtest1_end_test();
    }
  }while( zTSet[0] );
  speedtest1_final();

  if( showStats ){
    sqlite3_exec(g.db, "PRAGMA compile_options", xCompileOptions, 0, 0);
  }

  /* Database connection statistics printed after both prepared statements

Deleted 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/stat.test.

55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69







-
+








if {[wal_is_capable]} {
  do_execsql_test stat-0.1 {
    PRAGMA journal_mode = WAL;
    PRAGMA journal_mode = delete;
    SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
      FROM stat;
  } {wal delete sqlite_schema / 1 leaf 0 0 916 0}
  } {wal delete sqlite_master / 1 leaf 0 0 916 0}
}

do_test stat-1.0 {
  execsql {
    CREATE TABLE t1(a, b);
    CREATE INDEX i1 ON t1(b);
    INSERT INTO t1(rowid, a, b) VALUES(2, 2, 3);
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
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







-
+

-
+




















-
+







    SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
      FROM stat WHERE name = 'i1';
  }
} {i1 / 3 leaf 2 10 1000 5}
do_test stat-1.3 {
  execsql {
    SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
      FROM stat WHERE name = 'sqlite_schema';
      FROM stat WHERE name = 'sqlite_master';
  }
} {sqlite_schema / 1 leaf 2 77 831 40}
} {sqlite_master / 1 leaf 2 77 831 40}
do_test stat-1.4 {
  execsql {
    DROP TABLE t1;
  }
} {}

do_execsql_test stat-2.1 {
  CREATE TABLE t3(a PRIMARY KEY, b);
  INSERT INTO t3(rowid, a, b) VALUES(2, a_string(111), a_string(222));
  INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
   ORDER BY rowid;
  INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
   ORDER BY rowid;
  INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
   ORDER BY rowid;
  INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
   ORDER BY rowid;
  INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
   ORDER BY rowid;
  SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
    FROM stat WHERE name != 'sqlite_schema' ORDER BY name;
    FROM stat WHERE name != 'sqlite_master';
} [list \
  sqlite_autoindex_t3_1 / 3 internal 3 368 623 125       \
  sqlite_autoindex_t3_1 /000/ 8 leaf 8 946 46 123        \
  sqlite_autoindex_t3_1 /001/ 9 leaf 8 988 2 131         \
  sqlite_autoindex_t3_1 /002/ 15 leaf 7 857 137 132      \
  sqlite_autoindex_t3_1 /003/ 20 leaf 6 739 257 129      \
  t3 / 2 internal 15 0 907 0                             \
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
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







-
-
-
-
-
-
-
-
















-
+



















-
-
-
-
-
-
-
-
-







  t3 /00b/ 18 leaf 2 706 300 354                         \
  t3 /00c/ 19 leaf 2 714 292 358                         \
  t3 /00d/ 21 leaf 2 722 284 362                         \
  t3 /00e/ 22 leaf 2 730 276 366                         \
  t3 /00f/ 23 leaf 2 738 268 370                         \
]

do_execsql_test stat-2.1agg {
  SELECT * FROM dbstat WHERE aggregate=TRUE ORDER BY name;
} [list \
  sqlite_autoindex_t3_1 {}  5 {} 32  3898 1065 132 {}  5120 \
  sqlite_schema         {}  1 {}  2    84  824  49 {}  1024 \
  t3                    {} 17 {} 47 11188 5815 370 {} 17408 \
]

# With every index entry overflowing, make sure no pages are missed 
# (other than the locking page which is 64 in this test build.)
#
do_execsql_test stat-2.2 {
  UPDATE t3 SET a=a||hex(randomblob(700));
  VACUUM;
  SELECT pageno FROM stat EXCEPT SELECT pageno-1 FROM stat;
} {64 136}

do_execsql_test stat-2.3 { DROP TABLE t3; VACUUM; } {}

do_execsql_test stat-3.1 {
  CREATE TABLE t4(x);
  CREATE INDEX i4 ON t4(x);
  INSERT INTO t4(rowid, x) VALUES(2, a_string(7777));
  SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
    FROM stat WHERE name != 'sqlite_schema' ORDER BY name;
    FROM stat WHERE name != 'sqlite_master';
} [list \
  i4 / 3 leaf 1 103 905 7782                 \
  i4 /000+000000 4 overflow 0 1020 0 0       \
  i4 /000+000001 5 overflow 0 1020 0 0      \
  i4 /000+000002 6 overflow 0 1020 0 0      \
  i4 /000+000003 7 overflow 0 1020 0 0      \
  i4 /000+000004 8 overflow 0 1020 0 0      \
  i4 /000+000005 9 overflow 0 1020 0 0      \
  i4 /000+000006 10 overflow 0 1020 0 0      \
  i4 /000+000007 11 overflow 0 539 481 0     \
  t4 / 2 leaf 1 640 367 7780                 \
  t4 /000+000000 12 overflow 0 1020 0 0      \
  t4 /000+000001 13 overflow 0 1020 0 0      \
  t4 /000+000002 14 overflow 0 1020 0 0      \
  t4 /000+000003 15 overflow 0 1020 0 0      \
  t4 /000+000004 16 overflow 0 1020 0 0      \
  t4 /000+000005 17 overflow 0 1020 0 0      \
  t4 /000+000006 18 overflow 0 1020 0 0      \
]

do_execsql_test stat-3.2 {
  SELECT *, '|' FROM dbstat WHERE aggregate=TRUE ORDER BY name;
} [list \
  i4            {} 9 {} 1 7782 1386 7782 {} 9216 | \
  sqlite_schema {} 1 {} 2   74  834   40 {} 1024 | \
  t4            {} 8 {} 1 7780  367 7780 {} 8192 | \
]


do_execsql_test stat-4.1 {
  CREATE TABLE t5(x);
  CREATE INDEX i5 ON t5(x);
  SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
    FROM stat WHERE name = 't5' OR name = 'i5';
} [list  \
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
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







-
-
-
-
-
-
-
-
-
-




















-
+





-
+






-
+






-
+












-
+









-
+







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
    FROM stat WHERE name = 't1';
} [list \
  t1 / 2 leaf 2 993 5 1517                \
  t1 /000+000000 3 overflow 0 1020 0 0    \
  t1 /001+000000 4 overflow 0 1020 0 0    \
]

do_execsql_test stat-5.20 {
  SELECT name, quote(path), pageno, quote(pagetype), ncell, payload,
         unused, mx_payload, '|' FROM dbstat('main',1);
} {sqlite_schema NULL 1 NULL 1 34 878 34 | tx NULL 1 NULL 0 0 1016 0 |}
do_execsql_test stat-5.21 {
  SELECT name, quote(path), pageno, quote(pagetype), ncell, payload,
         unused, mx_payload, '|' FROM dbstat('aux1',1);
} {sqlite_schema NULL 1 NULL 1 34 878 34 | t1 NULL 3 NULL 2 3033 5 1517 |}


do_catchsql_test stat-6.1 {
  CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx);
} {1 {no such database: mainx}}

#-------------------------------------------------------------------------
# Test that the argument passed to the dbstat constructor is dequoted
# before it is matched against the names of attached databases.
#
forcedelete test.db2
do_execsql_test 7.1 {
  ATTACH 'test.db2' AS '123';
  PRAGMA "123".auto_vacuum = OFF;
  CREATE TABLE "123".x1(a, b);
  INSERT INTO x1 VALUES(1, 2);
}

do_execsql_test 7.1.1 {
  SELECT * FROM dbstat('123');
} {
  sqlite_schema / 1 leaf 1 37 875 37 0 1024 
  sqlite_master / 1 leaf 1 37 875 37 0 1024 
  x1 / 2 leaf 1 4 1008 4 1024 1024
}
do_execsql_test 7.1.2 {
  SELECT * FROM dbstat(123);
} {
  sqlite_schema / 1 leaf 1 37 875 37 0 1024 
  sqlite_master / 1 leaf 1 37 875 37 0 1024 
  x1 / 2 leaf 1 4 1008 4 1024 1024
}
do_execsql_test 7.1.3 {
  CREATE VIRTUAL TABLE x2 USING dbstat('123');
  SELECT * FROM x2;
} {
  sqlite_schema / 1 leaf 1 37 875 37 0 1024 
  sqlite_master / 1 leaf 1 37 875 37 0 1024 
  x1 / 2 leaf 1 4 1008 4 1024 1024
}
do_execsql_test 7.1.4 {
  CREATE VIRTUAL TABLE x3 USING dbstat(123);
  SELECT * FROM x3;
} {
  sqlite_schema / 1 leaf 1 37 875 37 0 1024 
  sqlite_master / 1 leaf 1 37 875 37 0 1024 
  x1 / 2 leaf 1 4 1008 4 1024 1024
}

do_execsql_test 7.2 {
  DETACH 123;
  DROP TABLE x2;
  DROP TABLE x3;
  ATTACH 'test.db2' AS '123corp';
}
do_execsql_test 7.2.1 {
  SELECT * FROM dbstat('123corp');
} {
  sqlite_schema / 1 leaf 1 37 875 37 0 1024 
  sqlite_master / 1 leaf 1 37 875 37 0 1024 
  x1 / 2 leaf 1 4 1008 4 1024 1024
}
do_catchsql_test 7.2.2 {
  SELECT * FROM dbstat(123corp);
} {1 {unrecognized token: "123corp"}}
do_execsql_test 7.2.3 {
  CREATE VIRTUAL TABLE x2 USING dbstat('123corp');
  SELECT * FROM x2;
} {
  sqlite_schema / 1 leaf 1 37 875 37 0 1024 
  sqlite_master / 1 leaf 1 37 875 37 0 1024 
  x1 / 2 leaf 1 4 1008 4 1024 1024
}
do_catchsql_test 7.2.4 {
  CREATE VIRTUAL TABLE x3 USING dbstat(123corp);
  SELECT * FROM x3;
} {1 {unrecognized token: "123corp"}}


do_execsql_test 8.1 {
  CREATE VIRTUAL TABLE st4 USING dbstat;
}
do_execsql_test 8.2 {
  SELECT * FROM st4 WHERE st4.aggregate = NULL;
}
do_execsql_test 8.3 {
  SELECT aggregate=1 FROM st4 WHERE aggregate = 5
}
do_execsql_test 8.4 {
  SELECT * FROM st4 WHERE name = NULL;
} {}
do_execsql_test 8.5 {
  SELECT * FROM st4 WHERE schema = NULL;
} {}

finish_test

Changes to test/subquery2.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
193
194
195
196
197
198
199

















200
201







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  }
} {
  do_catchsql_test 4.$tn $sql [list {*}{
    1 {ORDER BY clause should come after UNION ALL not before}
  }]
}

#-------------------------------------------------------------------------
# Test that ticket [9cdc5c46] is fixed.
#
reset_db
do_execsql_test 5.0 {
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES('ALFKI');
  INSERT INTO t1 VALUES('ANATR');

  CREATE TABLE t2(y, z);
  CREATE INDEX t2y ON t2 (y);
  INSERT INTO t2 VALUES('ANATR', '1997-08-08 00:00:00');
  INSERT INTO t2 VALUES('ALFKI', '1997-08-25 00:00:00');
}
do_execsql_test 5.1 {
  SELECT ( SELECT y FROM t2 WHERE x = y ORDER BY y, z) FROM t1;
} {ALFKI ANATR}

finish_test

Changes to test/substr.test.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21













+







# 2007 May 14
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the built-in SUBSTR() functions.
#
# $Id: substr.test,v 1.7 2009/02/03 13:10:54 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !tclvar {
  finish_test
  return
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
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







-
+















-
+







    execsql {
      SELECT substr(t, $i1, $i2) FROM t1
    }
  }] [list $result]
  set qstr '[string map {' ''} $string]'
  do_test substr-$id.2 [subst {
    execsql {
      SELECT substring($qstr, $i1, $i2)
      SELECT substr($qstr, $i1, $i2)
    }
  }] [list $result]
}
proc subblob-test {id hex i1 i2 hexresult} {
  db eval "
    DELETE FROM t1;
    INSERT INTO t1(b) VALUES(x'$hex')
  "
  do_test substr-$id.1 [subst {
    execsql {
      SELECT hex(substr(b, $i1, $i2)) FROM t1
    }
  }] [list $hexresult]
  do_test substr-$id.2 [subst {
    execsql {
      SELECT hex(substring(x'$hex', $i1, $i2))
      SELECT hex(substr(x'$hex', $i1, $i2))
    }
  }] [list $hexresult]
}

# Basic SUBSTR functionality
#
substr-test 1.1 abcdefg 1 1 a
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103







-
+







do_test substr-1.91 {
  db eval {SELECT ifnull(substr(NULL,1),'nil')}
} nil
do_test substr-1.92 {
  db eval {SELECT ifnull(substr('abcdefg',NULL,1),'nil')}
} nil
do_test substr-1.93 {
  db eval {SELECT ifnull(substring('abcdefg',NULL),'nil')}
  db eval {SELECT ifnull(substr('abcdefg',NULL),'nil')}
} nil
do_test substr-1.94 {
  db eval {SELECT ifnull(substr('abcdefg',1,NULL),'nil')}
} nil

# Make sure everything works with long unicode characters
#
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159







-
+







    execsql {
      SELECT substr(t, $idx) FROM t1
    }
  }] [list $result]
  set qstr '[string map {' ''} $string]'
  do_test substr-$id.2 [subst {
    execsql {
      SELECT substring($qstr, $idx)
      SELECT substr($qstr, $idx)
    }
  }] [list $result]
}
substr-2-test 5.1 abcdefghijklmnop 5 efghijklmnop
substr-2-test 5.2 abcdef -5 bcdef

finish_test

Changes to test/symlink.test.

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
33
34
35
36
37
38
39



















40
41
42
43

44
45
46
47
48
49
50
51







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-
+







forcedelete test.db2
do_test 1.1 {
  file link test.db2 test.db
  sqlite3 db2 test.db2
  sqlite3_db_filename db2 main
} [file join [pwd] test.db]

# But not with the -nofollow flag
#
do_test 1.1.2 {
  db2 close
  set rc [catch {sqlite3 db2 test.db2 -nofollow 1} msg]
  lappend rc $msg
} {1 {unable to open database file}}

# If the main database is successfully opened with -nofollow, then -nofollow
# is also used for ATTACH.
#
do_test 1.1.3 {
  catch {db2 close}
  sqlite3 db2 test.db -nofollow 1
} {}
do_test 1.1.4 {
  catchsql {ATTACH 'test.db2' AS aux1;} db2
} {1 {unable to open database: test.db2}}

# Test that if the symlink points to a file that does not exists, it is
# created when it is opened.
#
do_test 1.2.1 {
  catch {db2 close}
  db2 close
  db close
  forcedelete test.db
  file exists test.db
} 0
do_test 1.2.2 {
  sqlite3 db2 test.db2
  file exists test.db

Deleted test/symlink2.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




















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 November 18
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing that SQLite can follow symbolic links.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix symlink2

# This only runs on Windows.
if {$::tcl_platform(platform)!="windows"} {
  finish_test
  return
}

proc createWin32Symlink { link target } {
  exec -- $::env(ComSpec) /c mklink \
      [file nativename $link] [file nativename $target]
  return ""
}

proc deleteWin32Symlink { link } {
  exec -- $::env(ComSpec) /c del [file nativename $link]
  return ""
}

proc canCreateWin32Symlink {} {
  set link [file join $::testdir lnk[pid].sym]
  if {[file exists $link]} { return 0 }
  set target [info nameofexecutable]
  if {[catch {createWin32Symlink $link $target}] == 0} {
    deleteWin32Symlink $link
    return 1
  }
  return 0
}

# Creating symlinks may require administrator privileges on Windows.
if {![canCreateWin32Symlink]} {
  finish_test
  return
}

# Ensure that test.db has been created.
#
do_execsql_test 1.0 {
  CREATE TABLE t1(x, y);
  INSERT INTO t1 VALUES(1,9999);
}

do_test 2.0 {
  createWin32Symlink link.db test.db
} {}

do_test 2.1 {
  file exists test.db
} {1}

do_test 2.2 {
  file exists link.db
} {1}

do_test 3.1 {
  execsql { SELECT x, y FROM t1; } db
} {1 9999}

do_test 3.2 {
  sqlite3 db2 link.db
  execsql { SELECT x, y FROM t1; } db2
} {1 9999}

do_test 3.3 {
  sqlite3 db3 test.db -nofollow true
  execsql { SELECT x, y FROM t1; } db3
} {1 9999}

do_test 3.4 {
  db3 close
} {}

do_test 3.5 {
  list [catch {
    sqlite3 db4 link.db -nofollow true
    execsql { SELECT x, y FROM t1; } db4
  } res] $res
} {1 {unable to open database file}}

catch {db4 close}

do_test 4.0 {
  db2 close
  deleteWin32Symlink link.db
} {}

do_test 4.1 {
  file exists test.db
} {1}

do_test 4.2 {
  file exists link.db
} {0}

do_test 5.1 {
  execsql { SELECT x, y FROM t1; } db
} {1 9999}

finish_test

Changes to test/tabfunc01.test.

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
212
213
214
215
216
217
218









219
220
221
222
223
224
225







-
-
-
-
-
-
-
-
-








do_test tabfunc01-750 {
  db eval {
    SELECT aa.value, bb.value, '|'
      FROM carray(inttoptr($PTR4),5,'double') AS aa
      JOIN carray(inttoptr($PTR5),5,'char*') AS bb ON aa.rowid=bb.rowid;
  }
} {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |}

# ticket https://www.sqlite.org/src/info/2ae0c599b735d59e
do_test tabfunc01-751 {
  db eval {
    SELECT aa.value, bb.value, '|'
      FROM carray(inttoptr($PTR4),5,'double') AS aa
      LEFT JOIN carray(inttoptr($PTR5),5,'char*') AS bb ON aa.rowid=bb.rowid;
  }
} {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |}

# Free up memory allocations
intarray_addr
int64array_addr
doublearray_addr
textarray_addr

Changes to test/tclsqlite.test.

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
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







-
+
















-
+








set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tcl

# Check the error messages generated by tclsqlite
#
set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nofollow BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
if {[sqlite3 -has-codec]} {
  append r " ?-key CODECKEY?"
}
do_test tcl-1.1 {
  set v [catch {sqlite3 -bogus} msg]
  regsub {really_sqlite3} $msg {sqlite3} msg
  lappend v $msg
} [list 1 "wrong # args: should be \"$r\""]
do_test tcl-1.1.1 {
  set v [catch {sqlite3} msg]
  regsub {really_sqlite3} $msg {sqlite3} msg
  lappend v $msg
} [list 1 "wrong # args: should be \"$r\""]
do_test tcl-1.2 {
  set v [catch {db bogus} msg]
  lappend v $msg
} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
do_test tcl-1.2.1 {
  set v [catch {db cache bogus} msg]
  lappend v $msg
} {1 {bad option "bogus": must be flush or size}}
do_test tcl-1.2.2 {
  set v [catch {db cache} msg]
  lappend v $msg
367
368
369
370
371
372
373
374
375
376
377



378
379
380
381
382
383
384
367
368
369
370
371
372
373




374
375
376
377
378
379
380
381
382
383







-
-
-
-
+
+
+







      if {$n<=0} {return 0}
      set nm1 [expr {$n-1}]
      return [expr {[db eval {SELECT r1($nm1)}]+$n}]
    }
    db function r1 userfunc_r1
    execsql {SELECT r1(10)}
  } {55}
  # Fails under -fsanitize=address,undefined due to stack overflow
  # do_test tcl-9.11 {
  #   execsql {SELECT r1(100)}
  # } {5050}
  do_test tcl-9.11 {
    execsql {SELECT r1(100)}
  } {5050}
}

# Tests for the new transaction method
#
do_test tcl-10.1 {
  db transaction {}
} {}
786
787
788
789
790
791
792
793

794
795
796
797
798
799
800
785
786
787
788
789
790
791

792
793
794
795
796
797
798
799







-
+








do_test 17.6.2 {
  list [catch { db function xyz -return ret } msg] $msg
} {1 {option requires an argument: -return}}

do_test 17.6.3 {
  list [catch { db function xyz -n object ret } msg] $msg
} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, -innocuous, or -returntype}}
} {1 {bad option "-n": must be -argcount, -deterministic or -returntype}}

# 2019-02-28: The "bind_fallback" command.
#
do_test 18.100 {
  unset -nocomplain bindings abc def ghi jkl mno e01 e02
  set bindings(abc) [expr {1+2}]
  set bindings(def) {hello}

Changes to test/tempdb2.test.

93
94
95
96
97
98
99

93
94
95
96
97
98
99
100







+
}

do_execsql_test 2.2 {
  SELECT b FROM t1 WHERE a = 10001;
} "[int2str 1001][int2str 1001][int2str 1001]"

finish_test

Changes to test/tester.tcl.

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
125
126
127
128
129
130
131

132
133
134
135
136
137
138







-







      if {[info exists ::G(perm:presql)]} {
        [lindex $args 0] eval $::G(perm:presql)
      }
      if {[info exists ::G(perm:dbconfig)]} {
        set ::dbhandle [lindex $args 0]
        uplevel #0 $::G(perm:dbconfig)
      }
      [lindex $args 0] cache size 3
      set res
    } else {
      # This command is not opening a new database connection. Pass the
      # arguments through to the C implementation as the are.
      #
      uplevel 1 sqlite_orig $args
    }
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
169
170
171
172
173
174
175






176

177
178
179
180
181
182
183
184







-
-
-
-
-
-

-
+







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%]]]
        [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
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
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







-




















-
















-








# Print a HELP message and exit
#
proc print_help_and_quit {} {
  puts {Options:
  --pause                  Wait for user input before continuing
  --soft-heap-limit=N      Set the soft-heap-limit to N
  --hard-heap-limit=N      Set the hard-heap-limit to N
  --maxerror=N             Quit after N errors
  --verbose=(0|1)          Control the amount of output.  Default '1'
  --output=FILE            set --verbose=2 and output to FILE.  Implies -q
  -q                       Shorthand for --verbose=0
  --help                   This message
}
  exit 1
}

# The following block only runs the first time this file is sourced. It
# does not run in slave interpreters (since the ::cmdlinearg array is
# populated before the test script is run in slave interpreters).
#
if {[info exists cmdlinearg]==0} {

  # Parse any options specified in the $argv array. This script accepts the
  # following options:
  #
  #   --pause
  #   --soft-heap-limit=NN
  #   --hard-heap-limit=NN
  #   --maxerror=NN
  #   --malloctrace=N
  #   --backtrace=N
  #   --binarylog=N
  #   --soak=N
  #   --file-retries=N
  #   --file-retry-delay=N
  #   --start=[$permutation:]$testfile
  #   --match=$pattern
  #   --verbose=$val
  #   --output=$filename
  #   -q                                      Reduce output
  #   --testdir=$dir                          Run tests in subdirectory $dir
  #   --help
  #
  set cmdlinearg(soft-heap-limit)    0
  set cmdlinearg(hard-heap-limit)    0
  set cmdlinearg(maxerror)        1000
  set cmdlinearg(malloctrace)        0
  set cmdlinearg(backtrace)         10
  set cmdlinearg(binarylog)          0
  set cmdlinearg(soak)               0
  set cmdlinearg(file-retries)       0
  set cmdlinearg(file-retry-delay)   0
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
446
447
448
449
450
451
452



453
454
455
456
457
458
459







-
-
-







        puts -nonewline "Press RETURN to begin..."
        flush stdout
        gets stdin
      }
      {^-+soft-heap-limit=.+$} {
        foreach {dummy cmdlinearg(soft-heap-limit)} [split $a =] break
      }
      {^-+hard-heap-limit=.+$} {
        foreach {dummy cmdlinearg(hard-heap-limit)} [split $a =] break
      }
      {^-+maxerror=.+$} {
        foreach {dummy cmdlinearg(maxerror)} [split $a =] break
      }
      {^-+malloctrace=.+$} {
        foreach {dummy cmdlinearg(malloctrace)} [split $a =] break
        if {$cmdlinearg(malloctrace)} {
          if {0==$::sqlite_options(memdebug)} {
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
610
582
583
584
585
586
587
588

589

590
591
592
593
594
595
596







-
+
-







  }
}

# Update the soft-heap-limit each time this script is run. In that
# way if an individual test file changes the soft-heap-limit, it
# will be reset at the start of the next test file.
#
sqlite3_soft_heap_limit64 $cmdlinearg(soft-heap-limit)
sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
sqlite3_hard_heap_limit64 $cmdlinearg(hard-heap-limit)

# Create a test database
#
proc reset_db {} {
  catch {db close}
  forcedelete test.db
  forcedelete test.db-journal
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
771
772
773
774
775
776
777



778
779
780
781
782
783
784







-
-
-








  if {![info exists ::G(match)] || [string match $::G(match) $name]} {
    if {[catch {uplevel #0 "$cmd;\n"} result]} {
      output2_if_no_verbose -nonewline $name...
      output2 "\nError: $result"
      fail_test $name
    } else {
      if {[permutation]=="maindbname"} {
        set result [string map [list [string tolower ICECUBE] main] $result]
      }
      if {[regexp {^[~#]?/.*/$} $expected]} {
        # "expected" is of the form "/PATTERN/" then the result if correct if
        # regular expression PATTERN matches the result.  "~/PATTERN/" means
        # the regular expression must not match.
        if {[string index $expected 0]=="~"} {
          set re [string range $expected 2 end-1]
          if {[string index $re 0]=="*"} {
904
905
906
907
908
909
910
911
912


913
914
915
916
917
918
919
887
888
889
890
891
892
893


894
895
896
897
898
899
900
901
902







-
-
+
+







  # 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 {/}]
    # 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 ] }
1220
1221
1222
1223
1224
1225
1226
1227

1228
1229
1230
1231
1232
1233
1234
1235
1203
1204
1205
1206
1207
1208
1209

1210

1211
1212
1213
1214
1215
1216
1217







-
+
-








  vfs_unlink_test
  sqlite3 db {}
  # sqlite3_clear_tsd_memdebug
  db close
  sqlite3_reset_auto_extension

  sqlite3_soft_heap_limit64 0
  sqlite3_soft_heap_limit 0
  sqlite3_hard_heap_limit64 0
  set nTest [incr_ntest]
  set nErr [set_test_counter errors]

  set nKnown 0
  if {[file readable known-problems.txt]} {
    set fd [open known-problems.txt]
    set content [read $fd]
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1673
1674
1675
1676
1677
1678
1679


1680
1681
1682

1683
1684
1685
1686
1687
1688
1689







-
-



-








  # $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;}}
1724
1725
1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
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







-
+











-
-
-







  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
    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"} {
    if {$msg=="child killed: unknown signal"} {
      set msg "child process exited abnormally"
    }
  }
  if {$r && [string match {*ERROR: LeakSanitizer*} $msg]} {
    set msg "child process exited abnormally"
  }

  lappend r $msg
}

#   crash_on_write ?-devchar DEVCHAR? CRASHDELAY SQL
#
proc crash_on_write {args} {
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2463
2464
2465
2466
2467
2468
2469

2470
2471
2472







-



set sqlite_fts3_enable_parentheses 0

# During testing, assume that all database files are well-formed.  The
# few test cases that deliberately corrupt database files should rescind 
# this setting by invoking "database_can_be_corrupt"
#
database_never_corrupt
extra_schema_checks 1

source $testdir/thread_common.tcl
source $testdir/malloc_common.tcl

Changes to test/threadtest3.c.

1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1429
1430
1431
1432
1433
1434
1435

1436
1437
1438
1439
1440
1441
1442







-









#include "tt3_checkpoint.c"
#include "tt3_index.c"
#include "tt3_lookaside1.c"
#include "tt3_vacuum.c"
#include "tt3_stress.c"
#include "tt3_shared.c"

int main(int argc, char **argv){
  struct ThreadTest {
    void (*xTest)(int);   /* Routine for running this test */
    const char *zTest;    /* Name of this test */
    int nMs;              /* How long to run this test, in milliseconds */
  } aTest[] = {
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1453
1454
1455
1456
1457
1458
1459

1460
1461
1462
1463
1464
1465
1466







-







    { checkpoint_starvation_2, "checkpoint_starvation_2", 10000 },

    { create_drop_index_1, "create_drop_index_1", 10000 },
    { lookaside1,          "lookaside1", 10000 },
    { vacuum1,             "vacuum1", 10000 },
    { stress1,             "stress1", 10000 },
    { stress2,             "stress2", 60000 },
    { shared1,             "shared1", 10000 },
  };
  static char *substArgv[] = { 0, "*", 0 };
  int i, iArg;
  int nTestfound = 0;

  sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
  if( argc<2 ){

Deleted test/tkt-18458b1a.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




















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 September 10
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. In particular,
# that problems related to ticket [18458b1a] have been fixed.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-18458b1a

foreach tn {1 2} {
  reset_db
  if {$tn==1} {
    # Disable the flattener and push-down optimizations
    optimization_control db query-flattener 0
    optimization_control db push-down 0
  } else {
    # Enable them
    optimization_control db query-flattener 1
    optimization_control db push-down 1
  }

  db cache size 0

  do_execsql_test $tn.1.1 {
    CREATE TABLE t0(c0 COLLATE NOCASE);
    INSERT INTO t0(c0) VALUES ('B');
    CREATE VIEW v0(c0, c1) AS SELECT DISTINCT t0.c0, 'a' FROM t0;
  } 

  do_execsql_test $tn.1.2 {
    SELECT count(*) FROM v0 WHERE c1 >= c0;
  } 1

  do_execsql_test $tn.1.3 {
    SELECT count(*) FROM v0 WHERE NOT NOT (c1 >= c0);
  } 1

  do_execsql_test $tn.1.4 {
    SELECT count(*) FROM v0 WHERE ((c1 >= c0) OR 0+0);
  } 1
}

finish_test

Changes to test/tkt-3a77c9714e.test.

1

2
3
4
5
6
7
8

1
2
3
4
5
6
7
8
-
+







# 2011-12-06
# 2011 December 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.
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
64
65
66
67
68
69
70


71













72







-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-

        SELECT SrcWord, B.Id as BeginningId, B.Title || E.Title As Connected
        FROM Beginnings B LEFT JOIN Endings E ON B.EndingId=E.EndingId
        WHERE Connected=SrcWord LIMIT 1
      )
    )
} {FACTORING FACTOR SWIMMING SWIMM} 

# Similar problem discovered by dbsqlfuzz on 2019-09-18
#

do_execsql_test 3.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(i INT PRIMARY KEY, a, b);
  INSERT INTO t1 VALUES(NULL,'one','i');
  CREATE INDEX i1a ON t1(a);
  CREATE INDEX i1b ON t1(b);
  SELECT (SELECT 1
            FROM (SELECT 1 FROM t1 WHERE a=1 OR b='i')
           WHERE a='o'
              OR b IN (SELECT a=('b' IN (SELECT 'a'))))
    FROM t1;
} {{}}

finish_test

Changes to test/tkt-78e04e52ea.test.

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+







} {0 {} {} 0 {} 0 1 x CHAR(100) 0 {} 0}
do_test tkt-78e04-1.3 {
  execsql {
    CREATE INDEX i1 ON ""("" COLLATE nocase);
  }
} {}
do_test tkt-78e04-1.4 {
 db eval {EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1e5%';}
 db eval {EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';}
} {/*SCAN TABLE  USING COVERING INDEX i1*/}
do_test tkt-78e04-1.5 {
  execsql {
    DROP TABLE "";
    SELECT name FROM sqlite_master;
  }
} {t2}

Deleted test/tkt-a7debbe0.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






































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 September 10
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. In particular,
# that problems related to ticket a7debbe0ad1 have been fixed.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-a7debbe0

foreach tn {1 2} {
  reset_db
  if {$tn==1} {
    # Disable the flattener
    optimization_control db query-flattener 0
  } else {
    # Enable the flattener
    optimization_control db query-flattener 1
  }

  do_execsql_test $tn.1.0 {
    CREATE TABLE t0(xyz INTEGER);
    INSERT INTO t0(xyz) VALUES(456);
    CREATE VIEW v2(a, B) AS 
        SELECT 'a', 'B' COLLATE NOCASE FROM t0;
    CREATE TABLE t2(a, B COLLATE NOCASE);
    INSERT INTO t2 VALUES('a', 'B');
    CREATE VIEW v3(a, B) AS
        SELECT 'a' COLLATE BINARY, 'B' COLLATE NOCASE FROM t0;

    CREATE VIEW v4(a, B) AS
        SELECT 'a', +CAST('B' COLLATE NOCASE AS TEXT) FROM t0;

    CREATE VIEW v5(a, B) AS
        SELECT 'a', ('B' COLLATE NOCASE) || '' FROM t0;
  }

  # Table t2 and views v2 through v5 should all be equivalent.
  do_execsql_test $tn.1.1.1 { SELECT a   >= B FROM t2;         } 1
  do_execsql_test $tn.1.1.2 { SELECT 'a' >= 'B' COLLATE NOCASE } 0
  do_execsql_test $tn.1.1.3 { SELECT a   >= B FROM v2          } 1
  do_execsql_test $tn.1.1.4 { SELECT a   >= B FROM v3          } 1
  do_execsql_test $tn.1.1.5 { SELECT a   >= B FROM v4          } 1
  do_execsql_test $tn.1.1.6 { SELECT a   >= B FROM v5          } 1

  do_execsql_test $tn.1.2.1 { SELECT B   < a FROM t2           } 0
  do_execsql_test $tn.1.2.2 { SELECT 'B' COLLATE NOCASE < 'a'  } 0
  do_execsql_test $tn.1.2.3 { SELECT B   < a FROM v2           } 0
  do_execsql_test $tn.1.2.4 { SELECT B   < a FROM v3           } 0
  do_execsql_test $tn.1.2.5 { SELECT a  < B FROM v4           } 0
  do_execsql_test $tn.1.2.6 { SELECT a  < B FROM v5           } 0

  #-------------------------------------------------------------------------
  do_execsql_test $tn.2.0 {
    CREATE TABLE t5(a, b COLLATE NOCASE);
    INSERT INTO t5 VALUES(1, 'XYZ');
  }

  # Result should be 0, as column "xyz" from the sub-query has implicit
  # collation sequence BINARY.
  do_execsql_test $tn.2.1 {
    SELECT xyz==b FROM ( SELECT a, 'xyz' AS xyz FROM t5 ), t5;
  } {0}

  # Result should be 1, as literal 'xyz' has no collation sequence, so
  # the comparison uses the implicit collation sequence of the RHS - NOCASE.
  do_execsql_test $tn.2.2 {
    SELECT 'xyz'==b FROM ( SELECT a, 'xyz' AS xyz FROM t5 ), t5;
  } {1}

  #-----------------------------------------------------------------------
  # The test case submitted with the ticket.
  #
  do_execsql_test $tn.3.0 {
    DROP TABLE t0;
    DROP VIEW v2;

    CREATE TABLE t0(c0);
    INSERT INTO t0(c0) VALUES('');
    CREATE VIEW v2(c0, c1) AS 
        SELECT 'B' COLLATE NOCASE, 'a' FROM t0 ORDER BY t0.c0;
    SELECT SUM(count) FROM (
      SELECT v2.c1 BETWEEN v2.c0 AND v2.c1 as count FROM v2
    );
  } 1

  # The result is 1, as the collation used is the implicit collation sequence
  # of v2.c1 - BINARY.
  do_execsql_test $tn.3.1 {
    SELECT v2.c1 BETWEEN v2.c0 AND v2.c1 as count FROM v2;
  } 1
}

finish_test

Changes to test/tkt-a8a0d2996a.test.

80
81
82
83
84
85
86
87

88
89
90

91
92
93


94
95
80
81
82
83
84
85
86

87
88
89

90
91


92
93
94
95







-
+


-
+

-
-
+
+


  SELECT '100x'+'-2y';
} {98}
do_execsql_test 4.3 {
  SELECT '100x'+'4.5y';
} {104.5}
do_execsql_test 4.4 {
  SELECT '-9223372036854775807x'-'1x';
} {-9223372036854775808}
} {-9.22337203685478e+18}
do_execsql_test 4.5 {
  SELECT '9223372036854775806x'+'1x';
} {9223372036854775807}
} {9.22337203685478e+18}
do_execsql_test 4.6 {
  SELECT '1234x'/'10y', '1234x'/'10.y', '1234x'/'1e1y';
} {123 123.4 123.4}
  SELECT '1234x'/'10y';
} {123.4}

finish_test

Changes to test/tkt-b75a9ca6b0.test.

56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







-
+







  6 "SELECT * FROM t1 GROUP BY y ORDER BY x"
  {1 3  2 2  3 1} {$tblscan*$grpsort*$sort}

  7 "SELECT * FROM t1 GROUP BY x, y ORDER BY x, y DESC"
  {1 3  2 2  3 1} {$idxscan*$sort}

  8 "SELECT * FROM t1 GROUP BY x, y ORDER BY x DESC, y DESC"
  {3 1  2 2  1 3} {$idxscan}
  {3 1  2 2  1 3} {$idxscan*$sort}

  9 "SELECT * FROM t1 GROUP BY x, y ORDER BY x ASC, y ASC"
  {1 3  2 2  3 1} {$idxscan}

  10 "SELECT * FROM t1 GROUP BY x, y ORDER BY x COLLATE nocase, y"
  {1 3  2 2  3 1} {$idxscan*$sort}

Changes to test/tkt-cbd054fa6b.test.

12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26







-
+







# This file implements tests to verify that ticket [cbd054fa6b] has been
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !stat4 {
ifcapable !stat4&&!stat3 {
  finish_test
  return
}

proc s {blob} {
  set ret ""
  binary scan $blob c* bytes
51
52
53
54
55
56
57

58
59
60
61
62
63












64
65
66
67
68
69
70
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







+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+







    INSERT INTO t1 VALUES (NULL, 'H');
    INSERT INTO t1 VALUES (NULL, 'I');
    SELECT count(*) FROM t1;
  }
} {10}
do_test tkt-cbd05-1.2 {
  db eval { ANALYZE; }
  ifcapable stat4 {
  db eval {
    PRAGMA writable_schema = 1;
    CREATE VIEW vvv AS 
    SELECT tbl,idx,neq,nlt,ndlt,test_extract(sample,0) AS sample
    FROM sqlite_stat4;
    PRAGMA writable_schema = 0;
    db eval {
      PRAGMA writable_schema = 1;
      CREATE VIEW vvv AS 
      SELECT tbl,idx,neq,nlt,ndlt,test_extract(sample,0) AS sample
      FROM sqlite_stat4;
      PRAGMA writable_schema = 0;
    }
  } else {
    db eval {
      CREATE VIEW vvv AS 
      SELECT tbl,idx,neq,nlt,ndlt,sample FROM sqlite_stat3;
    }
  }
} {}
do_test tkt-cbd05-1.3 {
  execsql { 
    SELECT tbl,idx,group_concat(s(sample),' ') 
    FROM vvv 
    WHERE idx = 't1_x' 

Changes to test/tkt2854.test.

24
25
26
27
28
29
30









31


32
33
34
35
36
37
38
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







+
+
+
+
+
+
+
+
+
-
+
+








# Open 3 database connections. Connection "db" and "db2" share a cache.
# Connection "db3" has its own cache.
#
do_test tkt2854-1.1 {
  sqlite3 db test.db
  sqlite3 db2 test.db

  # This is taken from shared.test.  The Windows VFS expands 
  # ./test.db (and test.db) to be the same thing so the path
  # matches and they share a cache.  By changing the case 
  # for Windows platform, we get around this and get a separate
  # connection.
  if {$::tcl_platform(platform)=="unix"} {
    sqlite3 db3 ./test.db
  } else {
  sqlite3 db3 "file:test.db?cache=private" -uri 1
    sqlite3 db3 TEST.DB
  }

  db eval {
    CREATE TABLE abc(a, b, c);
  }
} {}

# Check that an exclusive lock cannot be obtained if some other 

Changes to test/tkt3292.test.

16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31







-

+







#
# $Id: tkt3292.test,v 1.1 2008/08/13 14:07:41 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt3292-1.1 {
  sqlite3_db_config db LEGACY_FILE_FORMAT 0
  execsql {
    PRAGMA legacy_file_format=OFF;
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
    INSERT INTO t1 VALUES(0, 1);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t1 VALUES(2, 1);
    CREATE INDEX i1 ON t1(b);
    SELECT * FROM t1 WHERE b>=1;
  }

Changes to test/tkt3793.test.

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
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







+












+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+







#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket #3793 has been
# fixed.  
#
# $Id: tkt3793.test,v 1.2 2009/06/01 16:42:18 shane Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !shared_cache||!attach {
  finish_test
  return
}
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]

do_test tkt3793-1.1 {
  # This is taken from shared.test.  The Windows VFS expands 
  # ./test.db (and test.db) to be the same thing so the path
  # matches and they share a cache.  By changing the case 
  # for Windows platform, we get around this and get a separate
  db close
  sqlite3 db "file:test.db" -uri 1
  sqlite3 db1 "file:test.db?cache=private" -uri 1
  sqlite3 db2 "file:test.db?cache=shared" -uri 1
  # connection.
  if {$::tcl_platform(platform)=="unix"} {
    sqlite3 db1 test.db
    sqlite3 db2 test.db
  } else {
    sqlite3 db1 TEST.DB
    sqlite3 db2 TEST.DB
  }
  execsql {
    BEGIN;
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(a PRIMARY KEY, b);
    INSERT INTO t1 VALUES(randstr(50,50), randstr(50,50));
    INSERT INTO t1 SELECT randstr(50,50), randstr(50,50) FROM t1;
    INSERT INTO t1 SELECT randstr(50,50), randstr(50,50) FROM t1;

Changes to test/tkt3810.test.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
80
81
82
83
84
85
86
















87







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  execsql {
    SELECT name FROM sqlite_temp_master;
  }
} {}

db2 close

# 2020-11-06 forum post https://sqlite.org/forum/forumpost/157dc791df
#
reset_db
do_test tkt3810-100 {
  db eval {
    ATTACH ':memory:' AS aux1;
    CREATE TABLE aux1.t1(x);
    CREATE TEMP TRIGGER r1 DELETE ON t1 BEGIN SELECT *; END;
    CREATE VIEW t1 AS SELECT *;
  }
  catch {db eval {
    CREATE VIRTUAL TABLE t2 USING nosuchmodule;
  }}
  db eval {CREATE TABLE t3(z);}
} {}

finish_test

Changes to test/trace3.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
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+$/}

#-------------------------------------------------------------------------
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/trans.test.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21













+







# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: trans.test,v 1.41 2009/04/28 16:37:59 danielk1977 Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create several tables to work with.
#
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
















-
-
-







    CREATE TABLE two(a int PRIMARY KEY, b text);
    INSERT INTO two VALUES(1,'I');
    INSERT INTO two VALUES(5,'V');
    INSERT INTO two VALUES(10,'X');
    SELECT b FROM two ORDER BY a;
  }
} {I V X}
do_test trans-1.2.1 {
  sqlite3_txn_state db
} {0}
do_test trans-1.2.2 {
  sqlite3_txn_state db main
} {0}
do_test trans-1.2.3 {
  sqlite3_txn_state db temp
} {0}
do_test trans-1.2.4 {
  sqlite3_txn_state db no-such-schema
} {-1}

do_test trans-1.9 {
  sqlite3 altdb test.db
  execsql {SELECT b FROM one ORDER BY a} altdb
} {one two three}
do_test trans-1.10 {
  execsql {SELECT b FROM two ORDER BY a} altdb
} {I V X}
integrity_check trans-1.11
wal_check_journal_mode trans-1.12

# Basic transactions
#
do_test trans-2.1 {
  set v [catch {execsql {BEGIN}} msg]
  lappend v $msg
} {0 {}}
do_test trans-2.1b {
  sqlite3_txn_state db
} {0}
do_test trans-2.2 {
  set v [catch {execsql {END}} msg]
  lappend v $msg
} {0 {}}
do_test trans-2.3 {
  set v [catch {execsql {BEGIN TRANSACTION}} msg]
  lappend v $msg
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
91
92
93
94
95
96
97










98
99
100
101
102
103
104







-
-
-
-
-
-
-
-
-
-







do_test trans-3.1 {
  execsql {
    BEGIN;
    UPDATE one SET a = 0 WHERE 0;
    SELECT a FROM one ORDER BY a;
  }
} {1 2 3}
do_test trans-3.1b {
  sqlite3_txn_state db
} {2}
do_test trans-3.1c {
  sqlite3_txn_state db main
} {2}
do_test trans-3.1d {
  sqlite3_txn_state db temp
} {0}

do_test trans-3.2 {
  catchsql {
    SELECT a FROM two ORDER BY a;
  } altdb
} {0 {1 5 10}}

do_test trans-3.3 {
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
135
136
137
138
139
140
141




142
143
144
145
146
147
148







-
-
-
-







  catchsql {
    SELECT a FROM one ORDER BY a;
  } altdb
} {0 {1 2 3}}
do_test trans-3.10 {
  execsql {END TRANSACTION}
} {}
do_test trans-3.10b {
  sqlite3_txn_state db
} {0}


do_test trans-3.11 {
  set v [catch {execsql {
    SELECT a FROM two ORDER BY a;
  } altdb} msg]
  lappend v $msg
} {0 {1 4 5 10}}
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
248
249
250
251
252
253
254









255
256
257
258
259
260
261







-
-
-
-
-
-
-
-
-







do_test trans-5.1 {
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
} {}
do_test trans-5.2 {
  execsql {BEGIN TRANSACTION}
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
} {}
do_test trans-5.2b {
  sqlite3_txn_state db
} {1}
do_test trans-5.2c {
  sqlite3_txn_state db main
} {1}
do_test trans-5.2d {
  sqlite3_txn_state db temp
} {0}
do_test trans-5.3 {
  execsql {CREATE TABLE one(a text, b int)}
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
} {one}
do_test trans-5.4 {
  execsql {SELECT a,b FROM one ORDER BY b}
} {}

Changes to test/trigger1.test.

764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
764
765
766
767
768
769
770



























































771







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_execsql_test trigger1-19.1 {
  DELETE FROM t19;
  INSERT INTO t19(a,b,c) VALUES(1,2,3);
  UPDATE t19 SET c=CASE WHEN b=2 THEN b ELSE b+99 END WHERE a=1;
  SELECT * FROM t19;
} {1 2 2}

# 2019-08-26 Chromium sqlite3_fts3_lpm_fuzzer find.
#
db close
sqlite3 db :memory:
do_execsql_test trigger1-20.1 {
  CREATE TABLE t20_1(x);
  ATTACH ':memory:' AS aux;
  CREATE TABLE aux.t20_2(y);
  CREATE TABLE aux.t20_3(z);
  CREATE TEMP TRIGGER r20_3 AFTER INSERT ON t20_2 BEGIN UPDATE t20_3 SET z=z+1; END;
  DETACH aux;
  DROP TRIGGER r20_3;
} {}

# 2019-10-24 ticket 50c09fc2cf0d91ce
#
db close
sqlite3 db :memory:
do_execsql_test trigger1-21.1 {
  PRAGMA recursive_triggers = true;
  CREATE TABLE t0(a, b, c UNIQUE);
  CREATE UNIQUE INDEX i0 ON t0(b) WHERE a;
  CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN
    DELETE FROM t0;
  END;
  INSERT INTO t0(a,b,c) VALUES(0,0,9),(1,1,1);
  REPLACE INTO t0(a,b,c) VALUES(2,0,9);
  SELECT * FROM t0;
} {2 0 9}

# 2020-01-04 From Yongheng
# The test case below caused problems for the register validity
# tracking logic.  There was no bug in the release build.  The
# only problem was a false-positive in the register validity
# tracking.
#
reset_db
do_execsql_test trigger1-22.10 {
  CREATE TABLE t1(
    a INTEGER PRIMARY KEY,
    b DOUBLE
  );
  CREATE TRIGGER x AFTER UPDATE ON t1 BEGIN
   SELECT sum(b)OVER(ORDER BY (SELECT b FROM t1 AS x 
                               WHERE b IN (t1.a,127,t1.b)
                               GROUP BY b))
     FROM t1
     GROUP BY a;
  END;
  CREATE TEMP TRIGGER x BEFORE INSERT ON t1 BEGIN
    UPDATE t1
       SET b=randomblob(10)
     WHERE b >= 'E'
       AND a < (SELECT a FROM t1 WHERE a<22 GROUP BY b);
  END;
  INSERT INTO t1(b) VALUES('Y'),('X'),('Z');
  SELECT a, CASE WHEN typeof(b)='text' THEN quote(b) ELSE '<blob>' END, '|' FROM t1;
} {1 <blob> | 2 'X' | 3 'Z' |}

finish_test

Changes to test/trigger2.test.

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
748
749
750
751
752
753
754















755
756

757
758
759







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+


    CREATE TRIGGER trig1 INSTEAD OF DELETE ON v3 BEGIN
      SELECT 1;
    END;
    DELETE FROM v3 WHERE a = 1;
  }
} {}

integrity_check trigger2-9.99

# 2019-11-02 Problem found by TH3, related to generated column support.
db close
sqlite3 db :memory:
do_execsql_test trigger2-10.1 {
  CREATE TABLE t1(a,b,c,d);
  CREATE VIEW v2(a,b,c,d) AS SELECT * FROM t1;
  CREATE TRIGGER v2ins INSTEAD OF INSERT ON v2 BEGIN
    INSERT INTO t1(a,b,c,d) VALUES(new.a, new.b, new.c, new.d);
  END;
  INSERT INTO v2(a,d) VALUES(11,14);
  SELECT * FROM t1;
} {11 {} {} 14}
 
} ;# ifcapable view

integrity_check trigger2-999
integrity_check trigger2-9.9

finish_test

Changes to test/triggerC.test.

1068
1069
1070
1071
1072
1073
1074

1068
1069
1070
1071
1072
1073
1074
1075







+
}
do_catchsql_test 17.1 {
  INSERT INTO xyz VALUES('hello', 2, 3);
} {1 {datatype mismatch}}


finish_test

Changes to test/triggerE.test.

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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; }
 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]
}

#-------------------------------------------------------------------------

Changes to test/triggerG.test.

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
70
71
72
73
74
75
76
















77
78







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


    SELECT 0x2147483648e0e0099 AS y WHERE y;
  END;
}

do_catchsql_test 310 {
  INSERT INTO t4 VALUES(1);
} {1 {hex literal too big: 0x2147483648e0e0099}}

#-------------------------------------------------------------------------
# 
do_execsql_test 400 {
  CREATE VIEW v0(a) AS SELECT 1234;
  CREATE TRIGGER t0001 INSTEAD OF DELETE ON v0 BEGIN
    SELECT old.a;
  END;
}
do_execsql_test 405 {
  SELECT a FROM v0;
} {1234}
do_execsql_test 410 {
  DELETE FROM v0;
}


finish_test

Deleted test/triggerupfrom.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














































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 July 14
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix triggerupfrom

do_execsql_test 1.0 {
  CREATE TABLE map(k, v);
  INSERT INTO map VALUES(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four');

  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);

  CREATE TRIGGER tr AFTER INSERT ON t1 BEGIN
    UPDATE t1 SET c = v FROM map WHERE k=new.a AND a=new.a;
  END;
}

do_execsql_test 1.1 {
  INSERT INTO t1(a) VALUES(1);
}

do_execsql_test 1.2 {
  SELECT a, c FROM t1 ORDER BY a;
} {1 one}

do_execsql_test 1.3 {
  INSERT INTO t1(a) VALUES(2), (3), (4), (5);
  SELECT a, c FROM t1 ORDER BY a;
} {1 one 2 two 3 three 4 four 5 {}}

forcedelete test.db2
do_execsql_test 2.0 {
  ATTACH 'test.db2' AS aux;
  CREATE TABLE aux.t3(x, y);
  INSERT INTO aux.t3 VALUES('x', 'y');
}

do_catchsql_test 2.1 {
  CREATE TRIGGER tr2 AFTER INSERT ON t1 BEGIN
    UPDATE t1 SET b = y FROM aux.t3 WHERE k=new.a;
  END;
} {1 {trigger tr2 cannot reference objects in database aux}}

do_execsql_test 2.2 {
  CREATE TEMP TRIGGER tr2 AFTER INSERT ON t1 BEGIN
    UPDATE t1 SET b = y FROM aux.t3 WHERE a=new.a;
  END;
  INSERT INTO t1(a) VALUES(10), (20);
  SELECT * FROM t1;
} {
  1 {} one 
  2 {} two 
  3 {} three 
  4 {} four 
  5 {} {} 
  10 y {} 
  20 y {}
}

do_execsql_test 2.3 {
  CREATE TABLE link(f, t);
  INSERT INTO link VALUES(5, 2), (20, 10), (2, 1);
  CREATE TRIGGER tr3 BEFORE DELETE ON t1 BEGIN
    UPDATE t1 SET b=coalesce(old.b,old.c) FROM main.link WHERE a=t AND old.a=f;
  END;
  DELETE FROM t1 WHERE a=2;
  SELECT * FROM t1;
} {
  1 two one 
  3 {} three 
  4 {} four 
  5 {} {} 
  10 y {} 
  20 y {}
}

db close
sqlite3 db ""
do_catchsql_test 2.4 {
  ATTACH 'test.db' AS yyy;
  SELECT * FROM t1;
} {1 {malformed database schema (tr3) - trigger tr3 cannot reference objects in database main}}

#-------------------------------------------------------------------------
reset_db
forcedelete test.db2
do_execsql_test 3.0 {
  CREATE TABLE mmm(x, y);
  INSERT INTO mmm VALUES(1, 'one');
  INSERT INTO mmm VALUES(2, 'two');
  INSERT INTO mmm VALUES(3, 'three');

  ATTACH 'test.db2' AS aux;
  CREATE TABLE aux.t1(a, b);
  CREATE TABLE aux.mmm(x, y);
  INSERT INTO aux.mmm VALUES(1, 'ONE');
  INSERT INTO aux.mmm VALUES(2, 'TWO');
  INSERT INTO aux.mmm VALUES(3, 'THREE');

  CREATE TRIGGER aux.ttt AFTER INSERT ON t1 BEGIN
    UPDATE t1 SET b=y FROM mmm WHERE x=new.a AND a=new.a;
  END;
  
  INSERT INTO t1(a) VALUES (2);
  SELECT * FROM t1;
} {2 TWO}

#-------------------------------------------------------------------------
# Test that INSTEAD OF UPDATE triggers on views work with UPDATE...FROM
# statements. Including, if the library is built with ENABLE_HIDDEN_COLUMNS, 
# that they work correctly on views with hidden columns.
#
reset_db
do_execsql_test 4.0 {
  CREATE TABLE t1(k, a, b);
  INSERT INTO t1 VALUES('a', 1, 'one');
  INSERT INTO t1 VALUES('b', 2, 'two');
  INSERT INTO t1 VALUES('c', 3, 'three');
  INSERT INTO t1 VALUES('d', 4, 'four');

  CREATE TABLE log(x);
  CREATE VIEW v1 AS SELECT k, a, b AS __hidden__b FROM t1;
  CREATE TRIGGER tr1 INSTEAD OF UPDATE ON v1 BEGIN
    INSERT INTO log VALUES(
      '('||old.a||','||old.__hidden__b||')->('||new.a||','||new.__hidden__b||')'
    );
  END;
}

ifcapable hiddencolumns {
  do_execsql_test 4.1-hc-enabled {
    SELECT * FROM v1
  } {a 1 b 2 c 3 d 4}
} else {
  do_execsql_test 4.1-hc-disabled {
    SELECT * FROM v1
  } {a 1 one b 2 two c 3 three d 4 four}
}

do_execsql_test 4.2 {
  UPDATE v1 SET a='xyz' WHERE k IN ('a', 'c');
  SELECT * FROM log;
  DELETE FROM log;
} {
  (1,one)->(xyz,one)
  (3,three)->(xyz,three)
}

do_execsql_test 4.3 {
  CREATE TABLE map(k, v);
  INSERT INTO map VALUES('b', 'twelve');
  INSERT INTO map VALUES('d', 'fourteen');
  UPDATE v1 SET a=map.v FROM map WHERE v1.k=map.k;
  SELECT * FROM log;
  DELETE FROM log;
} {
  (2,two)->(twelve,two)
  (4,four)->(fourteen,four)
}



finish_test

Deleted test/trustschema1.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



























































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020-01-08
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# 
# Test cases for managing execution of code snippets found in untrusted
# schemas.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix trustschema1

# edgy functions used in generated columns
#
proc f1 {x} {return $x}
do_test 1.100 {
  db function f1 -innocuous -deterministic f1
  db function f2 -deterministic f1
  db function f3 -directonly -deterministic f1
  db eval {
    CREATE TABLE t1(a, b AS (f1(a+1)), c AS (f2(a+2)));
    INSERT INTO t1 VALUES(100),(200);
  }
} {}
do_catchsql_test 1.110 {
  SELECT a, b, c FROM t1;
} {0 {100 101 102 200 201 202}}
do_execsql_test 1.120 {
  PRAGMA trusted_schema=OFF;
} {}
do_catchsql_test 1.130 {
  SELECT a, b FROM t1;
} {0 {100 101 200 201}}
do_catchsql_test 1.140 {
  SELECT a, b, c FROM t1;
} {1 {unsafe use of f2()}}
do_catchsql_test 1.150 {
  PRAGMA trusted_schema=ON;
  DROP TABLE t1;
  CREATE TABLE t1(a, b AS (f3(a+1)));
} {1 {unsafe use of f3()}}
do_execsql_test 1.160 {
  PRAGMA trusted_schema=OFF;
  CREATE TEMP TABLE temp1(a,b AS (f3(a+1)));
  INSERT INTO temp1(a) VALUES(100),(900);
  SELECT * FROM temp1;
} {100 101 900 901}

# edgy functions used in CHECK constraints
#
do_catchsql_test 1.200 {
  PRAGMA trusted_schema=ON;
  CREATE TABLE t2(a,b,c,CHECK(f3(c)==c));
} {1 {unsafe use of f3()}}
do_catchsql_test 1.210 {
  PRAGMA trusted_schema=Off;
  CREATE TABLE t2(a,b,c,CHECK(f2(c)==c));
} {1 {unsafe use of f2()}}
do_catchsql_test 1.211 {
  PRAGMA trusted_schema=On;
  CREATE TABLE t2(a,b,c,CHECK(f2(c)==c));
} {0 {}}
do_catchsql_test 1.220 {
  INSERT INTO t2 VALUES(1,2,3);
  SELECT * FROM t2;
} {0 {1 2 3}}
do_catchsql_test 1.230 {
  PRAGMA trusted_schema=off;
  INSERT INTO t2 VALUES(4,5,6);
} {1 {unsafe use of f2()}}
do_execsql_test 1.231 {
  SELECT * FROM t2;
} {1 2 3}
# Ok to put as many edgy functions as you want in a
# TEMP table.
do_execsql_test 1.240 {
  PRAGMA trusted_schema=OFF;
  CREATE TEMP TABLE temp2(a, b, CHECK(f3(b)==b));
  INSERT INTO temp2(a,b) VALUES(1,2),('x','y');
  SELECT * FROM temp2;
} {1 2 x y}

# edgy functions used in DEFAULT constraints
#
do_catchsql_test 1.300 {
  CREATE TABLE t3(a,b DEFAULT(f2(25)));
} {0 {}}
do_catchsql_test 1.310 {
  PRAGMA trusted_schema=Off;
  INSERT INTO t3(a) VALUES(1);
} {1 {unsafe use of f2()}}
do_catchsql_test 1.311 {
  INSERT INTO t3(a,b) VALUES(1,2);
} {0 {}}
do_execsql_test 1.320 {
  CREATE TEMP TABLE temp3(a, b DEFAULT(f3(31)));
  INSERT INTO temp3(a) VALUES(22);
  SELECT * FROM temp3;
} {22 31}

# edgy functions used in partial indexes.
#
do_execsql_test 1.400 {
  CREATE TABLE t4(a,b,c);
  INSERT INTO t4 VALUES(1,2,3),('a','b','c'),(4,'d',0);
  SELECT * FROM t4;
  CREATE TEMP TABLE temp4(a,b,c);
  INSERT INTO temp4 SELECT * FROM t4;
} {1 2 3 a b c 4 d 0}
do_catchsql_test 1.410 {
  CREATE INDEX t4a ON t4(a) WHERE f3(c);
} {1 {unsafe use of f3()}}
do_catchsql_test 1.420 {
  PRAGMA trusted_schema=OFF;
  CREATE INDEX t4a ON t4(a) WHERE f2(c);
} {1 {unsafe use of f2()}}
do_execsql_test 1.421 {
  CREATE INDEX t4a ON t4(a) WHERE f1(c);
  SELECT a FROM t4 WHERE f1(c) ORDER BY a;
} {1}
do_execsql_test 1.430 {
  PRAGMA trusted_schema=ON;
  CREATE INDEX t4b ON t4(b) WHERE f2(c);
  SELECT b FROM t4 WHERE f2(c) ORDER BY b;
} {2}
do_execsql_test 1.440 {
  PRAGMA trusted_schema=OFF;
  CREATE INDEX temp4a ON temp4(a) WHERE f3(c);
  SELECT a FROM temp4 WHERE f2(c) ORDER BY a;
} {1}

# edgy functions used in index expressions
#
do_execsql_test 1.500 {
  CREATE TABLE t5(a,b,c);
  INSERT INTO t5 VALUES(1,2,3),(4,5,6),(7,0,-3);
  SELECT * FROM t5;
  CREATE TEMP TABLE temp5(a,b,c);
  INSERT INTO temp5 SELECT * FROM t5;
} {1 2 3 4 5 6 7 0 -3}
do_catchsql_test 1.510 {
  CREATE INDEX t5x1 ON t5(a+f3(b));
} {1 {unsafe use of f3()}}
do_catchsql_test 1.520 {
  PRAGMA trusted_schema=OFF;
  CREATE INDEX t5x1 ON t5(a+f2(b));
} {1 {unsafe use of f2()}}
do_execsql_test 1.521 {
  CREATE INDEX t5x1 ON t5(a+f1(b));
  SELECT * FROM t5 INDEXED BY t5x1 WHERE a+f1(b)=3;
} {1 2 3}
do_execsql_test 1.530 {
  PRAGMA trusted_schema=ON;
  CREATE INDEX t5x2 ON t5(b+f2(c));
  SELECT * FROM t5 INDEXED BY t5x2 WHERE b+f2(c)=11;
} {4 5 6}
do_execsql_test 1.540 {
  PRAGMA trusted_schema=OFF;
  CREATE INDEX temp5x1 ON temp5(a+f3(b));
  SELECT * FROM temp5 INDEXED BY temp5x1 WHERE a+f3(b)=7;
} {7 0 -3}

# edgy functions in VIEWs
#
reset_db
db function f1 -innocuous -deterministic f1
db function f2 -deterministic f1
db function f3 -directonly -deterministic f1
do_execsql_test 2.100 {
  CREATE TABLE t1(a,b,c);
  INSERT INTO t1 VALUES(1,2,3),(100,50,75),(-11,22,-33);
  CREATE VIEW v1a AS SELECT f3(a+b) FROM t1;
  SELECT f3(a+b) FROM t1;
} {3 150 11}
do_catchsql_test 2.110 {
  PRAGMA trusted_schema=ON;
  SELECT * FROM v1a;
} {1 {unsafe use of f3()}}
do_catchsql_test 2.111 {
  PRAGMA trusted_schema=OFF;
  SELECT * FROM v1a;
} {1 {unsafe use of f3()}}
do_execsql_test 2.120 {
  DROP VIEW v1a;
  CREATE TEMP VIEW v1a AS SELECT f3(a+b) FROM t1;
  SELECT * FROM v1a;
} {3 150 11}
do_execsql_test 2.130 {
  CREATE VIEW v1b AS SELECT f2(b+c) FROM t1;
  SELECT f2(b+c) FROM t1;
} {5 125 -11}
do_catchsql_test 2.140 {
  PRAGMA trusted_schema=ON;
  SELECT * FROM v1b;
} {0 {5 125 -11}}
do_catchsql_test 2.141 {
  PRAGMA trusted_schema=OFF;
  SELECT * FROM v1b;
} {1 {unsafe use of f2()}}
do_execsql_test 2.150 {
  DROP VIEW v1b;
  CREATE TEMP VIEW v1b AS SELECT f2(b+c) FROM t1;
  SELECT * FROM v1b;
} {5 125 -11}

# edgy functions inside of triggers
#
do_execsql_test 3.100 {
  DELETE FROM t1;
  CREATE TABLE t2(x);
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
    INSERT INTO t2(x) SELECT f3(new.a);
  END;
} {}
do_catchsql_test 3.110 {
  INSERT INTO t1 VALUES(7,6,5);
} {1 {unsafe use of f3()}}
do_execsql_test 3.111 {
  SELECT * FROM t1;
  SELECT * FROM t2;
} {}

do_execsql_test 3.120 {
  DROP TRIGGER r1;
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
    INSERT INTO t2(x) SELECT f2(new.a)+100;
  END;
  PRAGMA trusted_schema=ON;
  INSERT INTO t1 VALUES(7,6,5);
  SELECT * FROM t1, t2;
} {7 6 5 107}
do_catchsql_test 3.130 {
  DELETE FROM t1;
  DELETE FROM t2;
  PRAGMA trusted_schema=OFF;
  INSERT INTO t1 VALUES(7,6,5);
} {1 {unsafe use of f2()}}
do_execsql_test 3.131 {
  SELECT * FROM t1;
  SELECT * FROM t2;
} {}


finish_test

Deleted test/tt3_shared.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























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** 2020 September 5
**
** 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.
**
*************************************************************************
**
**
*/


/*
*/
static char *shared_thread1(int iTid, void *pArg){
  Error err = {0};                /* Error code and message */

  while( !timetostop(&err) ){
    Sqlite db = {0};              /* SQLite database connection */
    opendb(&err, &db, "test.db", 0);
    sql_script(&err, &db, "SELECT * FROM t1");
    closedb(&err, &db);
  }
  print_and_free_err(&err);
  return sqlite3_mprintf("done!");
}


static void shared1(int nMs){
  Error err = {0};
  Sqlite db = {0};              /* SQLite database connection */
  Threadset threads = {0};
  int ii;

  opendb(&err, &db, "test.db", 1);
  sql_script(&err, &db, "CREATE TABLE t1(x)");
  closedb(&err, &db);

  setstoptime(&err, nMs);
  sqlite3_enable_shared_cache(1);

  for(ii=0; ii<5; ii++){
    launch_thread(&err, &threads, shared_thread1, 0);
  }

  join_all_threads(&err, &threads);
  sqlite3_enable_shared_cache(0);

  print_and_free_err(&err);
}

Changes to test/tt3_stress.c.

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+







** Thread 2. Open and close database connections.
*/
static char *stress_thread_2(int iTid, void *pArg){
  Error err = {0};                /* Error code and message */
  Sqlite db = {0};                /* SQLite database connection */
  while( !timetostop(&err) ){
    opendb(&err, &db, "test.db", 0);
    sql_script(&err, &db, "SELECT * FROM sqlite_schema;");
    sql_script(&err, &db, "SELECT * FROM sqlite_master;");
    clear_error(&err, SQLITE_LOCKED);
    closedb(&err, &db);
  }
  print_and_free_err(&err);
  return sqlite3_mprintf("ok");
}

262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276







-
+








static char *stress2_workload19(int iTid, void *pArg){
  Error err = {0};                /* Error code and message */
  Sqlite db = {0};                /* SQLite database connection */
  const char *zDb = (const char*)pArg;
  while( !timetostop(&err) ){
    opendb(&err, &db, zDb, 0);
    sql_script(&err, &db, "SELECT * FROM sqlite_schema;");
    sql_script(&err, &db, "SELECT * FROM sqlite_master;");
    clear_error(&err, SQLITE_LOCKED);
    closedb(&err, &db);
  }
  print_and_free_err(&err);
  return sqlite3_mprintf("ok");
}

358
359
360
361
362
363
364




358
359
360
361
362
363
364
365
366
367
368







+
+
+
+
  launch_thread(&err, &threads, stress2_workload19, (void*)zDb);
  launch_thread(&err, &threads, stress2_workload19, (void*)zDb);

  join_all_threads(&err, &threads);
  sqlite3_enable_shared_cache(0);
  print_and_free_err(&err);
}




Deleted 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

Deleted 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

Deleted 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

Changes to test/update.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
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
637
638
639
640
641
642
643

























































































644







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_execsql_test update-16.1 {
  CREATE TABLE t16(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b UNIQUE);
  INSERT INTO t16(a,b) VALUES(1,2),(3,4),(5,6);
  UPDATE t16 SET a=a;
  SELECT * FROM t16 ORDER BY +a;
} {1 2 3 4 5 6}

# 2019-12-09 gramfuzz find
# If a partial index that does not reference any column of its table (which is you
# must admit is a very strange index, but one that is allowed) is used by an UPDATE
# statement, void the use of OP_DeferredSeek on the main loop, as the seek will not
# be resolved prior to the OP_Delete.
#
do_execsql_test update-17.10 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x,y);
  INSERT INTO t1(x) VALUES(1);
  CREATE INDEX t1x1 ON t1(1) WHERE 3;
  UPDATE t1 SET x=2, y=3 WHERE 3;
  SELECT * FROM t1;
} {2 3}

# 2019-12-22 ticket 5ad2aa6921faa1ee
# Make a hard-copy of values that need to be run through OP_RealAffinity
# rather than a soft-copy.  This is not strictly necessary, but it avoids
# a memory-accounting assert().
#
reset_db
do_execsql_test update-18.10 {
  PRAGMA encoding = 'UTF16';
  CREATE TABLE t0(c0 REAL, c1);
  INSERT INTO t0(c0,c1) VALUES('xyz',11),('uvw',22);
  CREATE INDEX i0 ON t0(c1) WHERE c0 GLOB 3;
  CREATE INDEX i1 ON t0(c0,c1) WHERE typeof(c0)='text' AND typeof(c1)='integer';
  UPDATE t0 SET c1=345;
  SELECT * FROM t0;
} {xyz 345 uvw 345}

# 2019-12-22 ticket c62c5e58524b204d
# This is really the same underlying problem as 5ad2aa6921faa1ee
#
reset_db
do_execsql_test update-18.20 {
  PRAGMA encoding = 'utf16';
  CREATE TABLE t0(c0 TEXT);
  CREATE INDEX i0 ON t0(0 LIKE COALESCE(c0, 0));
  INSERT INTO t0(c0) VALUES (0), (0);
  SELECT * FROM t0;
} {0 0}

# 2019-12-28 assertion fault reported by Yongheng
# Similar to ticket ec8abb025e78f40c
# An UPDATE was reaching the OP_Delete after running OP_DeferredSeek
# without ever hitting an OP_Column. The enhanced solution is to
# fix OP_Delete so that it can do the seek itself.
#
reset_db
do_execsql_test update-19.10 {
  CREATE TABLE t1(
   a TEXT,
   b INTEGER PRIMARY KEY UNIQUE
  ); 
  INSERT INTO t1 VALUES(1,2);
  UPDATE t1 SET a = quote(b) WHERE b>=2;
  SELECT * FROM t1;
} {2 2}

# 2019-12-29 ticket https://www.sqlite.org/src/info/314cc133e5ada126
# REPLACE conflict resolution during an UPDATE causes a DELETE trigger 
# to fire.  If that DELETE trigger subsequently modifies the row
# being updated, bad things can happen.  Prevent this by prohibiting
# triggers from making changes to the table being updated while doing
# REPLACE conflict resolution on the UPDATE.
#
# See also tickets:
#   https://www.sqlite.org/src/info/c1e19e12046d23fe 2019-10-25
#   https://www.sqlite.org/src/info/a8a4847a2d96f5de 2019-10-16 
#
reset_db
do_execsql_test update-20.10 {
  PRAGMA recursive_triggers = true;
  CREATE TABLE t1(a UNIQUE ON CONFLICT REPLACE, b);
  INSERT INTO t1(a,b) VALUES(4,12),(9,13);
  CREATE INDEX i0 ON t1(b);
  CREATE TRIGGER tr0 DELETE ON t1 BEGIN
    UPDATE t1 SET b = a;
  END;
  PRAGMA integrity_check;
} {ok}
do_catchsql_test update-20.20 {
  UPDATE t1 SET a=0;
} {1 {constraint failed}}
do_execsql_test update-20.30 {
  PRAGMA integrity_check;
} {ok}

finish_test

Deleted test/upfrom1.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115



















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 April 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.
#
#***********************************************************************
#

source [file join [file dirname $argv0] pg_common.tcl]

#=========================================================================

start_test upfrom1 "2020 April 22"

foreach {tn wo} {
  1 "WITHOUT ROWID"
  2 ""
} {
eval [string map [list %TN% $tn %WITHOUT_ROWID% $wo] {
execsql_test 1.%TN%.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER, c INTEGER) %WITHOUT_ROWID%;
  INSERT INTO t2 VALUES(1, 2, 3);
  INSERT INTO t2 VALUES(4, 5, 6);
  INSERT INTO t2 VALUES(7, 8, 9);

  DROP TABLE IF EXISTS chng;
  CREATE TABLE chng(a INTEGER, b INTEGER, c INTEGER);
  INSERT INTO chng VALUES(1, 100, 1000);
  INSERT INTO chng VALUES(7, 700, 7000);
}

execsql_test 1.%TN%.1 {
  SELECT * FROM t2;
}

execsql_test 1.%TN%.2 {
  UPDATE t2 SET b = chng.b, c = chng.c FROM chng WHERE chng.a = t2.a;
  SELECT * FROM t2 ORDER BY a;
}

execsql_test 1.%TN%.3 {
  DELETE FROM t2;
  INSERT INTO t2 VALUES(1, 2, 3);
  INSERT INTO t2 VALUES(4, 5, 6);
  INSERT INTO t2 VALUES(7, 8, 9);
}

execsql_test 1.%TN%.4 {
  UPDATE t2 SET (b, c) = (SELECT b, c FROM chng WHERE a=t2.a) 
    WHERE a IN (SELECT a FROM chng);
  SELECT * FROM t2 ORDER BY a;
}

execsql_test 1.%TN%.5 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a INTEGER PRIMARY KEY, b INTEGER, c TEXT) %WITHOUT_ROWID%;
  INSERT INTO t3 VALUES(1, 1, 'one');
  INSERT INTO t3 VALUES(2, 2, 'two');
  INSERT INTO t3 VALUES(3, 3, 'three');

  DROP TABLE IF EXISTS t4;
  CREATE TABLE t4(x TEXT);
  INSERT INTO t4 VALUES('five');

  SELECT * FROM t3 ORDER BY a;
}

execsql_test 1.%TN%.6 {
  UPDATE t3 SET c=x FROM t4;
  SELECT * FROM t3 ORDER BY a;
}
}]}

execsql_test 2.1 {
  DROP TABLE IF EXISTS t5;
  DROP TABLE IF EXISTS m1;
  DROP TABLE IF EXISTS m2;
  CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT);
  CREATE TABLE m1(x INTEGER PRIMARY KEY, y TEXT);
  CREATE TABLE m2(u INTEGER PRIMARY KEY, v TEXT);

  INSERT INTO t5 VALUES(1, 'one', 'ONE');
  INSERT INTO t5 VALUES(2, 'two', 'TWO');
  INSERT INTO t5 VALUES(3, 'three', 'THREE');
  INSERT INTO t5 VALUES(4, 'four', 'FOUR');

  INSERT INTO m1 VALUES(1, 'i');
  INSERT INTO m1 VALUES(2, 'ii');
  INSERT INTO m1 VALUES(3, 'iii');

  INSERT INTO m2 VALUES(1, 'I');
  INSERT INTO m2 VALUES(3, 'II');
  INSERT INTO m2 VALUES(4, 'III');
}

execsql_test 2.2 {
  UPDATE t5 SET b=y, c=v FROM m1 LEFT JOIN m2 ON (x=u) WHERE x=a;
  SELECT * FROM t5 ORDER BY a;
}

errorsql_test 2.3.1 {
  UPDATE t5 SET b=1 FROM t5;
}
errorsql_test 2.3.2 {
  UPDATE t5 AS apples SET b=1 FROM t5 AS apples;
}


finish_test

Deleted test/upfrom1.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


















































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 April 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.
#

####################################################
# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
####################################################

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix upfrom1

do_execsql_test 1.1.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER, c INTEGER) WITHOUT ROWID;
  INSERT INTO t2 VALUES(1, 2, 3);
  INSERT INTO t2 VALUES(4, 5, 6);
  INSERT INTO t2 VALUES(7, 8, 9);

  DROP TABLE IF EXISTS chng;
  CREATE TABLE chng(a INTEGER, b INTEGER, c INTEGER);
  INSERT INTO chng VALUES(1, 100, 1000);
  INSERT INTO chng VALUES(7, 700, 7000);
} {}

do_execsql_test 1.1.1 {
  SELECT * FROM t2;
} {1 2 3   4 5 6   7 8 9}

do_execsql_test 1.1.2 {
  UPDATE t2 SET b = chng.b, c = chng.c FROM chng WHERE chng.a = t2.a;
  SELECT * FROM t2 ORDER BY a;
} {1 100 1000   4 5 6   7 700 7000}

do_execsql_test 1.1.3 {
  DELETE FROM t2;
  INSERT INTO t2 VALUES(1, 2, 3);
  INSERT INTO t2 VALUES(4, 5, 6);
  INSERT INTO t2 VALUES(7, 8, 9);
} {}

do_execsql_test 1.1.4 {
  UPDATE t2 SET (b, c) = (SELECT b, c FROM chng WHERE a=t2.a) 
    WHERE a IN (SELECT a FROM chng);
  SELECT * FROM t2 ORDER BY a;
} {1 100 1000   4 5 6   7 700 7000}

do_execsql_test 1.1.5 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a INTEGER PRIMARY KEY, b INTEGER, c TEXT) WITHOUT ROWID;
  INSERT INTO t3 VALUES(1, 1, 'one');
  INSERT INTO t3 VALUES(2, 2, 'two');
  INSERT INTO t3 VALUES(3, 3, 'three');

  DROP TABLE IF EXISTS t4;
  CREATE TABLE t4(x TEXT);
  INSERT INTO t4 VALUES('five');

  SELECT * FROM t3 ORDER BY a;
} {1 1 one   2 2 two   3 3 three}

do_execsql_test 1.1.6 {
  UPDATE t3 SET c=x FROM t4;
  SELECT * FROM t3 ORDER BY a;
} {1 1 five   2 2 five   3 3 five}

do_execsql_test 1.2.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER, c INTEGER) ;
  INSERT INTO t2 VALUES(1, 2, 3);
  INSERT INTO t2 VALUES(4, 5, 6);
  INSERT INTO t2 VALUES(7, 8, 9);

  DROP TABLE IF EXISTS chng;
  CREATE TABLE chng(a INTEGER, b INTEGER, c INTEGER);
  INSERT INTO chng VALUES(1, 100, 1000);
  INSERT INTO chng VALUES(7, 700, 7000);
} {}

do_execsql_test 1.2.1 {
  SELECT * FROM t2;
} {1 2 3   4 5 6   7 8 9}

do_execsql_test 1.2.2 {
  UPDATE t2 SET b = chng.b, c = chng.c FROM chng WHERE chng.a = t2.a;
  SELECT * FROM t2 ORDER BY a;
} {1 100 1000   4 5 6   7 700 7000}

do_execsql_test 1.2.3 {
  DELETE FROM t2;
  INSERT INTO t2 VALUES(1, 2, 3);
  INSERT INTO t2 VALUES(4, 5, 6);
  INSERT INTO t2 VALUES(7, 8, 9);
} {}

do_execsql_test 1.2.4 {
  UPDATE t2 SET (b, c) = (SELECT b, c FROM chng WHERE a=t2.a) 
    WHERE a IN (SELECT a FROM chng);
  SELECT * FROM t2 ORDER BY a;
} {1 100 1000   4 5 6   7 700 7000}

do_execsql_test 1.2.5 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a INTEGER PRIMARY KEY, b INTEGER, c TEXT) ;
  INSERT INTO t3 VALUES(1, 1, 'one');
  INSERT INTO t3 VALUES(2, 2, 'two');
  INSERT INTO t3 VALUES(3, 3, 'three');

  DROP TABLE IF EXISTS t4;
  CREATE TABLE t4(x TEXT);
  INSERT INTO t4 VALUES('five');

  SELECT * FROM t3 ORDER BY a;
} {1 1 one   2 2 two   3 3 three}

do_execsql_test 1.2.6 {
  UPDATE t3 SET c=x FROM t4;
  SELECT * FROM t3 ORDER BY a;
} {1 1 five   2 2 five   3 3 five}

do_execsql_test 2.1 {
  DROP TABLE IF EXISTS t5;
  DROP TABLE IF EXISTS m1;
  DROP TABLE IF EXISTS m2;
  CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT);
  CREATE TABLE m1(x INTEGER PRIMARY KEY, y TEXT);
  CREATE TABLE m2(u INTEGER PRIMARY KEY, v TEXT);

  INSERT INTO t5 VALUES(1, 'one', 'ONE');
  INSERT INTO t5 VALUES(2, 'two', 'TWO');
  INSERT INTO t5 VALUES(3, 'three', 'THREE');
  INSERT INTO t5 VALUES(4, 'four', 'FOUR');

  INSERT INTO m1 VALUES(1, 'i');
  INSERT INTO m1 VALUES(2, 'ii');
  INSERT INTO m1 VALUES(3, 'iii');

  INSERT INTO m2 VALUES(1, 'I');
  INSERT INTO m2 VALUES(3, 'II');
  INSERT INTO m2 VALUES(4, 'III');
} {}

do_execsql_test 2.2 {
  UPDATE t5 SET b=y, c=v FROM m1 LEFT JOIN m2 ON (x=u) WHERE x=a;
  SELECT * FROM t5 ORDER BY a;
} {1 i I   2 ii {}   3 iii II   4 four FOUR}

# PG says ERROR:  table name "t5" specified more than once
do_test 2.3.1 { catch { execsql {
  UPDATE t5 SET b=1 FROM t5;
} } } 1

# PG says ERROR:  table name "apples" specified more than once
do_test 2.3.2 { catch { execsql {
  UPDATE t5 AS apples SET b=1 FROM t5 AS apples;
} } } 1

# Problem found by OSSFuzz on 2020-07-20
# https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24282
#
reset_db
do_execsql_test 3.1 {
  CREATE TABLE t0(a);
  CREATE TABLE t1(b);
  UPDATE t1 SET b=sum(a) FROM t0;
  SELECT * FROM t0, t1;
} {}

finish_test

Deleted test/upfrom2.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



















































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 April 29
#
# 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 upfrom2

# Test cases:
#
#   1.*: Test that triggers are fired correctly for UPDATE FROM statements,
#        and only once for each row. Except for INSTEAD OF triggers on 
#        views - these are fired once for each row returned by the join, 
#        including duplicates.
#
#   2.*: Test adding ORDER BY and LIMIT clauses with UPDATE FROM statements.
#
#   5.*: Test that specifying the target table name or alias in the FROM
#        clause of an UPDATE statement is an error.
#

foreach {tn wo} {
  1 ""
  2 "WITHOUT ROWID"
} {
  reset_db

  eval [string map [list %WO% $wo %TN% $tn] {
  do_execsql_test 1.%TN%.0 {
    CREATE TABLE log(t TEXT);
    CREATE TABLE t1(x PRIMARY KEY, y, z UNIQUE) %WO%;
    CREATE INDEX t1y ON t1(y);

    INSERT INTO t1 VALUES(1, 'i',   'one');
    INSERT INTO t1 VALUES(2, 'ii',  'two');
    INSERT INTO t1 VALUES(3, 'iii', 'three');
    INSERT INTO t1 VALUES(4, 'iv',  'four');

    CREATE TRIGGER tr1 BEFORE UPDATE ON t1 BEGIN
      INSERT INTO log VALUES(old.z || '->' || new.z);
    END;
    CREATE TRIGGER tr2 AFTER UPDATE ON t1 BEGIN
      INSERT INTO log VALUES(old.y || '->' || new.y);
    END;
  }

  do_execsql_test 1.%TN%.1 {
    WITH data(k, v) AS (
      VALUES(3, 'thirty'), (1, 'ten')
    )
    UPDATE t1 SET z=v FROM data WHERE x=k;

    SELECT * FROM t1;
    SELECT * FROM log;
  } {
    1 i ten   2 ii two   3 iii thirty   4 iv four
    one->ten        i->i
    three->thirty   iii->iii
  }

  do_execsql_test 1.%TN%.2 {
    CREATE TABLE t2(a, b);
    CREATE TABLE t3(k, v);
  
    INSERT INTO t3 VALUES(5,   'v');
    INSERT INTO t3 VALUES(12, 'xii');
  
    INSERT INTO t2 VALUES(2, 12);
    INSERT INTO t2 VALUES(3, 5);
  
    DELETE FROM log;
    UPDATE t1 SET y=v FROM t2, t3 WHERE t1.x=t2.a AND t3.k=t2.b;
  
    SELECT * FROM t1;
    SELECT * FROM log;
  } {
    1 i ten   2 xii two   3 v thirty   4 iv four
    two->two         ii->xii
    thirty->thirty   iii->v
  }

  do_execsql_test 1.%TN%.3 {
    DELETE FROM log;
    WITH data(k, v) AS (
      VALUES(1, 'seven'), (1, 'eight'), (2, 'eleven'), (2, 'twelve')
    )
    UPDATE t1 SET z=v FROM data WHERE x=k;
  
    SELECT * FROM t1;
    SELECT * FROM log;
  } {
    1 i eight   2 xii twelve   3 v thirty   4 iv four
    ten->eight        i->i
    two->twelve       xii->xii
  }

  do_test 1.%TN%.4 { db changes } {2}

  do_execsql_test 1.%TN%.5 { 
    CREATE VIEW v1 AS SELECT * FROM t1;
    CREATE TRIGGER v1tr INSTEAD OF UPDATE ON v1 BEGIN
      UPDATE t1 SET y=new.y, z=new.z WHERE x=new.x;
    END;

    DELETE FROM log;
    WITH data(k, v) AS (
      VALUES(3, 'thirteen'), (3, 'fourteen'), (4, 'fifteen'), (4, 'sixteen')
    )
    UPDATE v1 SET z=v FROM data WHERE x=k;
  }

  do_execsql_test 1.%TN%.6 {
    SELECT * FROM v1;
    SELECT * FROM log;
  } {
    1 i eight   2 xii twelve   3 v fourteen   4 iv sixteen
    thirty->thirteen  v->v
    thirteen->fourteen  v->v
    four->fifteen  iv->iv
    fifteen->sixteen  iv->iv
  }

  #--------------------------------------------------------------

  do_execsql_test 1.%TN%.7 {
    CREATE TABLE o1(w, x, y, z UNIQUE, PRIMARY KEY(w, x)) %WO%;
    CREATE INDEX o1y ON t1(y);

    INSERT INTO o1 VALUES(0, 0, 'i', 'one');
    INSERT INTO o1 VALUES(0, 1, 'ii', 'two');
    INSERT INTO o1 VALUES(1, 0, 'iii', 'three');
    INSERT INTO o1 VALUES(1, 1, 'iv', 'four');

    CREATE TRIGGER tro1 BEFORE UPDATE ON o1 BEGIN
      INSERT INTO log VALUES(old.z || '->' || new.z);
    END;
    CREATE TRIGGER tro2 AFTER UPDATE ON o1 BEGIN
      INSERT INTO log VALUES(old.y || '->' || new.y);
    END;
  }

  do_execsql_test 1.%TN%.8 {
    DELETE FROM log;
    WITH data(k, v) AS (
      VALUES(3, 'thirty'), (1, 'ten')
    )
    UPDATE o1 SET z=v FROM data WHERE (1+x+w*2)=k;

    SELECT * FROM o1;
    SELECT * FROM log;
  } {
    0 0 i ten   0 1 ii two   1 0 iii thirty   1 1 iv four
    one->ten        i->i
    three->thirty   iii->iii
  }

  do_execsql_test 1.%TN%.9 {
    DELETE FROM log;
    UPDATE o1 SET y=v FROM t2, t3 WHERE (1+o1.w*2+o1.x)=t2.a AND t3.k=t2.b;
  
    SELECT * FROM o1;
    SELECT * FROM log;
  } {
    0 0 i ten   0 1 xii two   1 0 v thirty   1 1 iv four
    two->two         ii->xii
    thirty->thirty   iii->v
  }

  do_execsql_test 1.%TN%.10 {
    DELETE FROM log;
    WITH data(k, v) AS (
      VALUES(1, 'seven'), (1, 'eight'), (2, 'eleven'), (2, 'twelve')
    )
    UPDATE o1 SET z=v FROM data WHERE (1+w*2+x)=k;
  
    SELECT * FROM o1;
    SELECT * FROM log;
  } {
    0 0 i eight   0 1 xii twelve   1 0 v thirty   1 1 iv four
    ten->eight        i->i
    two->twelve       xii->xii
  }

  do_test 1.%TN%.11 { db changes } {2}

  do_execsql_test 1.%TN%.12 { 
    CREATE VIEW w1 AS SELECT * FROM o1;
    CREATE TRIGGER w1tr INSTEAD OF UPDATE ON w1 BEGIN
      UPDATE o1 SET y=new.y, z=new.z WHERE w=new.w AND x=new.x;
    END;

    DELETE FROM log;
    WITH data(k, v) AS (
      VALUES(3, 'thirteen'), (3, 'fourteen'), (4, 'fifteen'), (4, 'sixteen')
    )
    UPDATE w1 SET z=v FROM data WHERE (1+w*2+x)=k;
  }

  do_execsql_test 1.%TN%.13 {
    SELECT * FROM w1;
    SELECT * FROM log;
  } {
    0 0 i eight   0 1 xii twelve   1 0 v fourteen   1 1 iv sixteen
    thirty->thirteen  v->v
    thirteen->fourteen  v->v
    four->fifteen  iv->iv
    fifteen->sixteen  iv->iv
  }

}]
}

ifcapable update_delete_limit {
foreach {tn wo} {
  1 ""
  2 "WITHOUT ROWID"
} {
  reset_db

eval [string map [list %WO% $wo %TN% $tn] {
  do_execsql_test 2.%TN%.1 {
    CREATE TABLE x1(a INTEGER PRIMARY KEY, b) %WO%;
    INSERT INTO x1 VALUES
        (1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'),
        (5, 'five'), (6, 'six'), (7, 'seven'), (8, 'eight');
  }

  do_execsql_test 2.%TN%.2 {
    CREATE TABLE data1(x, y);
    INSERT INTO data1 VALUES
    (1, 'eleven'), (1, 'twenty-one'), (2, 'twelve'), (2, 'twenty-two'),
    (3, 'thirteen'), (3, 'twenty-three'), (4, 'fourteen'), (4, 'twenty-four');
  }

  do_execsql_test 2.%TN%.3 {
    UPDATE x1 SET b=y FROM data1 WHERE a=x ORDER BY a LIMIT 3;
    SELECT * FROM x1;
  } {
    1 eleven 2 twelve 3 thirteen 4 four 5 five 6 six 7 seven 8 eight
  }

  do_execsql_test 2.%TN%.4 {
    UPDATE x1 SET b=b||y FROM data1 WHERE a=x ORDER BY b LIMIT 3;
    SELECT * FROM x1;
  } {
    1 eleveneleven 2 twelve 3 thirteenthirteen 4 fourfourteen 
    5 five 6 six 7 seven 8 eight
  }

  do_catchsql_test 2.%TN%.5 {
    UPDATE x1 SET b=b||b ORDER BY b;
  } {1 {ORDER BY without LIMIT on UPDATE}}
  do_catchsql_test 2.%TN%.6 {
    UPDATE x1 SET b=b||y FROM data1 WHERE a=x ORDER BY b;
  } {1 {ORDER BY without LIMIT on UPDATE}}

  #-----------------------------------------------------------------------

  do_execsql_test 2.%TN%.6 {
    DROP TABLE x1;
    CREATE TABLE x1(u, v, b, PRIMARY KEY(u, v)) %WO%;
    INSERT INTO x1 VALUES
        (0, 1, 'one'), (1, 0, 'two'), (1, 1, 'three'), (2, 0, 'four'),
        (2, 1, 'five'), (3, 0, 'six'), (3, 1, 'seven'), (4, 0, 'eight');
  }

  do_execsql_test 2.%TN%.7 {
    UPDATE x1 SET b=y FROM data1 WHERE (u*2+v)=x ORDER BY u, v LIMIT 3;
    SELECT * FROM x1;
  } {
    0 1 eleven 1 0 twelve 1 1 thirteen 2 0 four 
    2 1 five 3 0 six 3 1 seven 4 0 eight
  }

  do_execsql_test 2.%TN%.8 {
    UPDATE x1 SET b=b||y FROM data1 WHERE (u*2+v)=x ORDER BY b LIMIT 3;
    SELECT * FROM x1;
  } {
    0 1 eleveneleven 1 0 twelve 1 1 thirteenthirteen 2 0 fourfourteen 
    2 1 five  3 0 six 3 1 seven 4 0 eight
  }


}]
}}

reset_db
do_execsql_test 3.0 {
  CREATE TABLE data(x, y, z);
  CREATE VIEW t1 AS SELECT * FROM data;
  CREATE TRIGGER t1_insert INSTEAD OF INSERT ON t1 BEGIN
    INSERT INTO data VALUES(new.x, new.y, new.z);
  END;
  CREATE TRIGGER t1_update INSTEAD OF UPDATE ON t1 BEGIN
    INSERT INTO log VALUES(old.z || '->' || new.z);
  END;

  CREATE TABLE log(t TEXT);

  INSERT INTO t1 VALUES(1, 'i',   'one');
  INSERT INTO t1 VALUES(2, 'ii',  'two');
  INSERT INTO t1 VALUES(3, 'iii', 'three');
  INSERT INTO t1 VALUES(4, 'iv',  'four');
}

do_execsql_test 3.1 {
  WITH input(k, v) AS (
      VALUES(3, 'thirty'), (1, 'ten')
  )
  UPDATE t1 SET z=v FROM input WHERE x=k;
}

foreach {tn sql} {
  2 { 
    CREATE TABLE x1(a INT PRIMARY KEY, b, c) WITHOUT ROWID;
  }
  1 { 
    CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c);
  }
  3 { 
    CREATE TABLE x1(a INT PRIMARY KEY, b, c);
  }
} {

  reset_db
  execsql $sql

  do_execsql_test 4.$tn.0 {
    INSERT INTO x1 VALUES(1, 1, 1);
    INSERT INTO x1 VALUES(2, 2, 2);
    INSERT INTO x1 VALUES(3, 3, 3);
    INSERT INTO x1 VALUES(4, 4, 4);
    INSERT INTO x1 VALUES(5, 5, 5);
    CREATE TABLE map(o, t);
    INSERT INTO map VALUES(3, 30), (4, 40), (1, 10);
  }

  do_execsql_test 4.$tn.1 {
    UPDATE x1 SET a=t FROM map WHERE a=o;
    SELECT * FROM x1 ORDER BY a;
  } {2 2 2   5 5 5   10 1 1  30 3 3  40 4 4}
}

reset_db
do_execsql_test 5.0 {
  CREATE TABLE x1(a, b, c);
  CREATE TABLE x2(a, b, c);
}

foreach {tn update nm} {
  1 "UPDATE x1 SET a=5 FROM x1" x1
  2 "UPDATE x1 AS grapes SET a=5 FROM x1 AS grapes" grapes
  3 "UPDATE x1 SET a=5 FROM x2, x1" x1
  4 "UPDATE x1 AS grapes SET a=5 FROM x2, x1 AS grapes" grapes
} {
  do_catchsql_test 5.$tn $update \
    "1 {target object/alias may not appear in FROM clause: $nm}"
}


finish_test


Deleted test/upfrom3.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






































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 July 14
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix upfrom3

# Test plan:
#
#   1.*: Test UPDATE ... FROM statements that modify IPK fields. And that
#        modify "INTEGER PRIMARY KEY" fields on WITHOUT ROWID tables.
#
#   2.*: Test UPDATE ... FROM statements that modify PK fields of WITHOUT
#        ROWID tables.
#
#   3.*: Test that UPDATE ... FROM statements are not confused if there
#        are multiple tables of the same name in attached databases.
#
#   4.*: Tests for UPDATE ... FROM statements and foreign keys.
#

foreach {tn wo} {
  1 ""
  2 "WITHOUT ROWID"
} {
  reset_db
  eval [string map [list %WO% $wo %TN% $tn] {

  do_execsql_test 1.%TN%.0 {
    CREATE TABLE log(t TEXT);
    CREATE TABLE t1(x INTEGER PRIMARY KEY, y, z UNIQUE) %WO%;
    CREATE INDEX t1y ON t1(y);

    INSERT INTO t1 VALUES(1, 'i',   'one');
    INSERT INTO t1 VALUES(2, 'ii',  'two');
    INSERT INTO t1 VALUES(3, 'iii', 'three');
    INSERT INTO t1 VALUES(4, 'iv',  'four');
  }

  do_execsql_test 1.%TN%.1 {
    CREATE TABLE x1(o, n);
    INSERT INTO x1 VALUES(1, 11);
    INSERT INTO x1 VALUES(2, 12);
    INSERT INTO x1 VALUES(3, 13);
    INSERT INTO x1 VALUES(4, 14);
    UPDATE t1 SET x=n FROM x1 WHERE x=o;
    SELECT x, y, z FROM t1 ORDER BY 1;
  } {
    11 i one
    12 ii two
    13 iii three
    14 iv four
  }

  do_test 1.%TN%.2 { db changes } 4

  do_execsql_test 1.%TN%.3 {
    INSERT INTO x1 VALUES(11, 21);
    INSERT INTO x1 VALUES(12, 22);
    INSERT INTO x1 VALUES(13, 23);
    INSERT INTO x1 VALUES(14, 24);

    INSERT INTO x1 VALUES(21, 31);
    INSERT INTO x1 VALUES(22, 32);
    INSERT INTO x1 VALUES(23, 33);
    INSERT INTO x1 VALUES(24, 34);
    UPDATE t1 SET x=n FROM x1 WHERE x=o;
    SELECT x, y, z FROM t1 ORDER BY 1;
  } {
    21 i one
    22 ii two
    23 iii three
    24 iv four
  }

  do_execsql_test 1.%TN%.4 {
    UPDATE t1 SET x=n FROM x1 WHERE x=o;
    SELECT x, y, z FROM t1 ORDER BY 1;
  } {
    31 i one
    32 ii two
    33 iii three
    34 iv four
  }

  do_execsql_test 1.%TN%.5 {
    INSERT INTO x1 VALUES(31, 32);
    INSERT INTO x1 VALUES(33, 34);
    UPDATE OR REPLACE t1 SET x=n FROM x1 WHERE x=o;
    SELECT x, y, z FROM t1 ORDER BY 1;
  } {
    32 i one
    34 iii three
  }

  do_execsql_test 1.%TN%.6 {
    INSERT INTO t1 VALUES(33, 'ii', 'two');
    INSERT INTO t1 VALUES(35, 'iv', 'four');
  }

  do_execsql_test 1.%TN%.7 {
    CREATE TABLE x2(o, n, zz);
    INSERT INTO x2 VALUES(32, 41, 'four');
    INSERT INTO x2 VALUES(33, 42, 'three');
    UPDATE OR IGNORE t1 SET x=n, z=zz FROM x2 WHERE x=o;
    SELECT x, y, z FROM t1 ORDER BY 1;
  } {
    32 i one 
    33 ii two 
    34 iii three 
    35 iv four
  }

  do_execsql_test 1.%TN%.8 {
    UPDATE OR REPLACE t1 SET x=n, z=zz FROM x2 WHERE x=o;
    SELECT x, y, z FROM t1 ORDER BY 1;
  } {
    41 i four
    42 ii three
  }

  }]
}

do_execsql_test 2.1.1 {
  CREATE TABLE u1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
  INSERT INTO u1 VALUES(0, 0, 0);
  INSERT INTO u1 VALUES(1, 0, 1);
  INSERT INTO u1 VALUES(2, 1, 0);
  INSERT INTO u1 VALUES(3, 1, 1);
}

do_execsql_test 2.1.2 {
  CREATE TABLE map(f, t);
  INSERT INTO map VALUES(0, 10);
  INSERT INTO map VALUES(1, 11);
  UPDATE u1 SET c=t FROM map WHERE c=f;
  SELECT * FROM u1 ORDER BY a;
} {
  0 0 10
  1 0 11
  2 1 10
  3 1 11
}

do_execsql_test 2.1.3 {
  UPDATE u1 SET b=t FROM map WHERE b=f;
  SELECT * FROM u1 ORDER BY a;
} {
  0 10 10
  1 10 11
  2 11 10
  3 11 11
}

do_execsql_test 2.1.4 {
  CREATE TABLE map2(o1, o2, n1, n2);
  INSERT INTO map2 VALUES
    (10, 10, 50, 50), (10, 11, 50, 60), 
    (11, 10, 60, 50), (11, 11, 60, 60);
  UPDATE u1 SET b=n1, c=n2 FROM map2 WHERE b=o1 AND c=o2;
  SELECT * FROM u1 ORDER BY a;
} {
  0 50 50
  1 50 60
  2 60 50
  3 60 60
}

#-------------------------------------------------------------------------
foreach {tn wo} {
  1 ""
  2 "WITHOUT ROWID"
} {
  reset_db
  forcedelete test.db2
  eval [string map [list %WO% $wo %TN% $tn] {
    do_execsql_test 3.$tn.1 {
      CREATE TABLE g1(a, b, c, PRIMARY KEY(a, b)) %WO%;
      INSERT INTO g1 VALUES(1, 1, 1);

      ATTACH 'test.db2' AS aux;
      CREATE TABLE aux.g1(a, b, c, PRIMARY KEY(a, b)) %WO%;
      INSERT INTO aux.g1 VALUES(10, 1, 10);
      INSERT INTO aux.g1 VALUES(20, 2, 20);
      INSERT INTO aux.g1 VALUES(30, 3, 30);
    }

    do_execsql_test 3.$tn.2 {
      UPDATE aux.g1 SET c=101 FROM main.g1;
    }
    do_execsql_test 3.$tn.3 {
      SELECT * FROM aux.g1;
    } {10 1 101  20 2 101  30 3 101}

    do_execsql_test 3.$tn.4 {
      UPDATE g1 SET c=101 FROM g1 AS g2;
    }
    do_execsql_test 3.$tn.5 {
      SELECT * FROM g1;
    } {1 1 101}
  }]
}

#-------------------------------------------------------------------------
reset_db
foreach {tn wo} {
  1 ""
  2 "WITHOUT ROWID"
} {
  reset_db
  forcedelete test.db2
  eval [string map [list %WO% $wo %TN% $tn] {

    do_execsql_test 4.$tn.1 {
      CREATE TABLE p1(a INTEGER PRIMARY KEY, b) %WO%;
      CREATE TABLE c1(x PRIMARY KEY, y REFERENCES p1 ON UPDATE CASCADE) %WO%;
      PRAGMA foreign_keys = 1;

      INSERT INTO p1 VALUES(1, 'one');
      INSERT INTO p1 VALUES(11, 'eleven');
      INSERT INTO p1 VALUES(111, 'eleventyone');

      INSERT INTO c1 VALUES('a', 1);
      INSERT INTO c1 VALUES('b', 11);
      INSERT INTO c1 VALUES('c', 111);
    }

    do_execsql_test 4.$tn.2 {
      CREATE TABLE map(f, t);
      INSERT INTO map VALUES('a', 111);
      INSERT INTO map VALUES('c', 112);
    }

    do_catchsql_test 4.$tn.3 {
      UPDATE c1 SET y=t FROM map WHERE x=f;
    } {1 {FOREIGN KEY constraint failed}}

    do_execsql_test 4.$tn.4 {
      INSERT INTO map VALUES('eleven', 12);
      INSERT INTO map VALUES('eleventyone', 112);
      UPDATE p1 SET a=t FROM map WHERE b=f;
    }

    do_execsql_test 4.$tn.5 {
      SELECT * FROM c1
    } {a 1  b 12  c 112}

  }]
}

finish_test

Deleted test/upfromfault.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












































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 April 29
#
# 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 upfromfault

foreach {tn sql} {
  1 {
    CREATE TABLE t1(x PRIMARY KEY, y, z UNIQUE);
    CREATE INDEX t1y ON t1(y);
  }
  2 {
    CREATE TABLE t1(x PRIMARY KEY, y, z UNIQUE) WITHOUT ROWID;
    CREATE INDEX t1y ON t1(y);
  }
  3 {
    CREATE TABLE t1(x, y, z UNIQUE, PRIMARY KEY(x,y)) WITHOUT ROWID;
  }
  4 {
    CREATE VIRTUAL TABLE t1 USING fts5(x, y, z);
  }
  5 {
    CREATE TABLE real(x, y, z);
    CREATE VIEW t1 AS SELECT * FROM real;
    CREATE TRIGGER t1_insert INSTEAD OF INSERT ON t1 BEGIN
      INSERT INTO real VALUES(new.x, new.y, new.z);
    END;
    CREATE TRIGGER t1_update INSTEAD OF UPDATE ON t1 BEGIN
      INSERT INTO log VALUES(old.z || '->' || new.z);
      UPDATE real SET y=new.y, z=new.z WHERE x=old.x;
    END;
  }
} {
if {$tn<5} continue
  reset_db

  ifcapable !fts5 { if {$tn==4} continue }

  execsql $sql
  do_execsql_test 1.$tn.0 {
    CREATE TABLE log(t TEXT);

    INSERT INTO t1 VALUES(1, 'i',   'one');
    INSERT INTO t1 VALUES(2, 'ii',  'two');
    INSERT INTO t1 VALUES(3, 'iii', 'three');
    INSERT INTO t1 VALUES(4, 'iv',  'four');
  }
  if {$tn!=4 && $tn!=5} {
    do_execsql_test 1.$tn.0b {
      CREATE TRIGGER tr1 BEFORE UPDATE ON t1 BEGIN
        INSERT INTO log VALUES(old.z || '->' || new.z);
      END;
      CREATE TRIGGER tr2 AFTER UPDATE ON t1 BEGIN
        INSERT INTO log VALUES(old.y || '->' || new.y);
      END;
    }
  }
  
  faultsim_save_and_close

  do_faultsim_test 1.$tn -prep {
    faultsim_restore_and_reopen
    execsql { SELECT * FROM t1 }
  } -body {
    execsql {
      WITH data(k, v) AS (
          VALUES(3, 'thirty'), (1, 'ten')
      )
      UPDATE t1 SET z=v FROM data WHERE x=k;
    }
  } -test {
    faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}}
    if {$testrc==0} {
      set res [execsql { SELECT * FROM t1 }]
      if {$res!="1 i ten 2 ii two 3 iii thirty 4 iv four"} {
        error "unexpected result: $res"
      }
    }
  }
}

reset_db
do_execsql_test 2.0 {
  CREATE TABLE t1(a, b, c);
  CREATE TABLE t2(x, y, z);
}
faultsim_save_and_close
do_faultsim_test 2.1 -prep {
  faultsim_restore_and_reopen
} -body {
  execsql {
    CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
      UPDATE t2 SET x=a FROM t1 WHERE c=z;
    END;
  }
} -test {
    faultsim_test_result {0 {}}
}

faultsim_restore_and_reopen
do_execsql_test 2.2 {
  CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
    UPDATE t1 SET a=x FROM t2 WHERE c=z;
  END;

  INSERT INTO t2 VALUES(1, 1, 1);
  INSERT INTO t2 VALUES(2, 2, 2);
  INSERT INTO t2 VALUES(3, 3, 3);
} 
faultsim_save_and_close

do_faultsim_test 2.3 -prep {
  faultsim_restore_and_reopen
} -body {
  execsql {
    INSERT INTO t1 VALUES(NULL, NULL, 1), (NULL, NULL, 3);
  }
} -test {
  faultsim_test_result {0 {}}
  if {$testrc==0} {
    set res [execsql { SELECT * FROM t1 }]
    if {$res!="1 {} 1 3 {} 3"} {
      error "unexpected result: $res"
    }
  }
}


finish_test

Changes to test/upsert1.test.

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
206
207
208
209
210
211
212






























213
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(1,2,33,44,5)
    ON CONFLICT(b) DO UPDATE SET c=excluded.c;
  SELECT * FROM t1;
} {1 2 33 4 5}

# 2019-08-30 ticket https://sqlite.org/src/info/5a3dba8104421320
do_execsql_test upsert1-800 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 REAL UNIQUE, c1);
  CREATE UNIQUE INDEX test800i0 ON t0(0 || c1);
  INSERT INTO t0(c0, c1) VALUES (1, 2),  (2, 1);
  INSERT INTO t0(c0) VALUES (1) ON CONFLICT(c0) DO UPDATE SET c1=excluded.c0;
  PRAGMA integrity_check;
  REINDEX;
} {ok}

# 2019-12-06 gramfuzz find
sqlite3 db :memory:
do_execsql_test upsert1-900 {
  CREATE VIEW t1(a) AS SELECT 1;
  CREATE TRIGGER t1r1 INSTEAD OF INSERT ON t1 BEGIN
     SELECT 2;
  END;
}
do_catchsql_test upsert1-910 {
  INSERT INTO t1 VALUES(3) ON CONFLICT(x) DO NOTHING;
} {1 {cannot UPSERT a view}}

# 2019-12-26 ticket 7c13db5c3bf74001
reset_db
do_catchsql_test upsert1-1000 {
  CREATE TABLE t0(c0 PRIMARY KEY, c1, c2 UNIQUE) WITHOUT ROWID;
  INSERT OR FAIL INTO t0(c2) VALUES (0), (NULL)
    ON CONFLICT(c2) DO UPDATE SET c1 = c0;
} {1 {NOT NULL constraint failed: t0.c0}}

finish_test

Deleted 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
398
399
400
401
402
403
404
405
406
407
408
409
410
411



























































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 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}

}

#--------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t2(a, b, c REAL, d, e, PRIMARY KEY(a,b)) WITHOUT ROWID;
  CREATE UNIQUE INDEX t2c ON t2(c);
}

do_catchsql_test 2.1 {
  INSERT INTO t2(a,b,c,e,d) VALUES(1,2,3,4,5)
      ON CONFLICT(c) DO UPDATE SET b=''
      ON CONFLICT((SELECT t2 FROM nosuchtable)) DO NOTHING;

} {1 {no such table: nosuchtable}}

finish_test

Changes to test/vacuum2.test.

52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
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 {
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}]

############################################################################

Deleted 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.

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
34
35
36
37
38
39
40

















41
42
43
44
45
46
47







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







do_test view-1.1 {
  execsql {
    BEGIN;
    CREATE VIEW IF NOT EXISTS v1 AS SELECT a,b FROM t1;
    SELECT * FROM v1 ORDER BY a;
  }
} {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 {
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
696
697
698
699
700
701
702
703
























































































704








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

set res [list {SQLITE_DELETE sqlite_stat1 {} main {}}]
ifcapable stat4 { lappend res {SQLITE_DELETE sqlite_stat4 {} main {}} }
do_test view-25.2 {
  set log ""
  db eval {DROP TABLE t25;}
  set log
} $res

#-------------------------------------------------------------------------
do_execsql_test view-26.0 {
  CREATE TABLE t16(a, b, c UNIQUE);
  INSERT INTO t16 VALUES(1, 1, 1);
  INSERT INTO t16 VALUES(2, 2, 2);
  INSERT INTO t16 VALUES(3, 3, 3);
  CREATE VIEW v16 AS SELECT max(a) AS mx, min(b) AS mn FROM t16 GROUP BY c;

  SELECT * FROM v16 AS one, v16 AS two WHERE one.mx=1;
} {
  1 1 1 1 
  1 1 2 2 
  1 1 3 3
}
do_execsql_test view-26.1 {
  WITH v17(x,y) AS (SELECT max(a), min(b) FROM t16 GROUP BY c)
  SELECT * FROM v17 AS one, v17 AS two WHERE one.x=1;
} {
  1 1 1 1 
  1 1 2 2 
  1 1 3 3
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test view-27.0 {
  CREATE TABLE t0(c0 TEXT, c1);
  INSERT INTO t0(c0, c1) VALUES (-1, 0);
  CREATE VIEW v0(c0, c1) AS SELECT t0.c0, AVG(t0.c1) FROM t0;
}

do_execsql_test view-27.1 {
  SELECT c0, typeof(c0), c1, typeof(c1) FROM v0;
} {
  -1   text
   0.0 real
}

do_execsql_test view-27.2 { SELECT c0<c1 FROM v0 } 1
do_execsql_test view-27.3 { SELECT c1<c0 FROM v0 } 0
do_execsql_test view-27.4 {
  SELECT 1 FROM v0 WHERE c1<c0
} {}
do_execsql_test view-27.5 {
  SELECT 1 FROM v0 WHERE c0<c1
} {1}

do_execsql_test view-27.6 { 
  SELECT c0<c1 FROM (SELECT t0.c0 AS c0, AVG(t0.c1) AS c1 FROM t0) 
} 1
do_execsql_test view-27.7 { 
  SELECT c1<c0 FROM (SELECT t0.c0 AS c0, AVG(t0.c1) AS c1 FROM t0) 
} 0
do_execsql_test view-27.8 {
  SELECT 1 FROM (SELECT t0.c0 AS c0, AVG(t0.c1) AS c1 FROM t0) WHERE c1<c0
} {}
do_execsql_test view-27.9 {
  SELECT 1 FROM (SELECT t0.c0 AS c0, AVG(t0.c1) AS c1 FROM t0) WHERE c0<c1
} {1}

#-------------------------------------------------------------------------
reset_db
do_execsql_test view-28.0 {
  CREATE TABLE t0(c0 TEXT);
  CREATE VIEW v0(c0) AS SELECT t0.c0 FROM t0;
  INSERT INTO t0(c0) VALUES ('0');
}
do_execsql_test view-28.1 {
  SELECT 0 IN (c0) FROM t0;
} {0}
do_execsql_test view-28.2 {
  SELECT 0 IN (c0) FROM (SELECT c0 FROM t0);
} {0}

#-------------------------------------------------------------------------
# 2020-10-26.  https://sqlite.org/forum/forumpost/daa2c728cc
#
reset_db
do_catchsql_test view-29.0 {
  CREATE TABLE t1(a,b,c);
  CREATE VIEW IF NOT EXISTS IF AS SELECT null;
} {1 {malformed database schema (IF) - near "AS": syntax error}}
do_catchsql_test view-29.1 {
  CREATE TABLE t2(c,d,e);
  SELECT name FROM sqlite_schema ORDER BY name;
} {0 {t1 t2}}


finish_test

Changes to test/vtab1.test.

871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
871
872
873
874
875
876
877








878
879
880
881
882
883
884







-
-
-
-
-
-
-
-







} {31429}
do_test vtab1.7-13 {
  execsql {
    SELECT rowid, a, b, c FROM real_abc
  }
} {}

# PRAGMA index_info and index_xinfo are no-ops on a virtual table
do_test vtab1.7-14 {
  execsql {
    PRAGMA index_info('echo_abc');
    PRAGMA index_xinfo('echo_abc');
  }
} {}

ifcapable attach {
  do_test vtab1.8-1 {
    set echo_module ""
    execsql {
      ATTACH 'test2.db' AS aux;
      CREATE VIRTUAL TABLE aux.e2 USING echo(real_abc);
    }
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-


-
-
+
+


-
+
-
-
-








-
+







-
+







  INSERT INTO t6 VALUES(3, '8James');
  INSERT INTO t6 VALUES(4, '8John');
  INSERT INTO t6 VALUES(5, 'Phillip');
  INSERT INTO t6 VALUES(6, 'Bartholomew');
  CREATE VIRTUAL TABLE e6 USING echo(t6);
}

ifcapable !icu {
  foreach {tn sql res filter} {
    1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5}
      {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James}
  
    1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4}
      {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9}
  
    1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
      {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8J%}
  
    1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4}
      {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8j%}
foreach {tn sql res filter} {
  1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James}

  1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9}

  1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%}

  1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
  
    1.5 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4}
      {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%}
  } {
    set echo_module {}
    do_execsql_test 18.$tn.1 $sql $res
    do_test         18.$tn.2 { lrange $::echo_module 2 end } $filter
  }
}
} {
  set echo_module {}
  do_execsql_test 18.$tn.1 $sql $res
  do_test         18.$tn.2 { lrange $::echo_module 2 end } $filter
}


do_execsql_test 18.2.0 {  PRAGMA case_sensitive_like = ON }
foreach {tn sql res filter} {
  2.1 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%}
  2.1 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%}

  2.2 "SELECT a FROM e6 WHERE b LIKE '8j%'" {}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8j 8k 8j%}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}

  2.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8K 8J%}
} {
  set echo_module {}
  do_execsql_test 18.$tn.1 $sql $res
  do_test         18.$tn.2 { lrange $::echo_module 2 end } $filter
}
do_execsql_test 18.2.x {  PRAGMA case_sensitive_like = OFF }

#-------------------------------------------------------------------------
# Test that it is ok to override and existing module.
# Test that an existing module may not be overridden.
#
do_test 19.1 {
  sqlite3 db2 test.db
  register_echo_module [sqlite3_connection_pointer db2]
} SQLITE_OK
do_test 19.2 {
  register_echo_module [sqlite3_connection_pointer db2]
} SQLITE_OK
} SQLITE_MISUSE
do_test 19.3 {
  db2 close
} {}

#-------------------------------------------------------------------------
# Test that the bug fixed by [b0c1ba655d69] really is fixed.
#

Changes to test/vtabH.test.

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
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







-
-
-
+
+
-
-
+
-
-
+
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-








do_execsql_test 1.0 {
  CREATE TABLE t6(a, b TEXT);
  CREATE INDEX i6 ON t6(b, a);
  CREATE VIRTUAL TABLE e6 USING echo(t6);
}

ifcapable !icu {
  foreach {tn sql expect} {
    1 "SELECT * FROM e6 WHERE b LIKE '8abc'" {
foreach {tn sql expect} {
  1 "SELECT * FROM e6 WHERE b LIKE '8abc'" {
      xBestIndex 
         {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?}
    xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
      xFilter
         {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?}
    xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8abc
         8ABC 8abd 8abc
    }
  
    2 "SELECT * FROM e6 WHERE b GLOB '8abc'" {
  }

  2 "SELECT * FROM e6 WHERE b GLOB '8abc'" {
       xBestIndex
         {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?}
       xFilter
         {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?}
         8abc 8abd 8abc
    }
    3 "SELECT * FROM e6 WHERE b LIKE '8e/'" {
      xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
      xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8e/
    }
    4 "SELECT * FROM e6 WHERE b GLOB '8e/'" {
      xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
      xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8e/
    }
  } {
    do_test 1.$tn {
      set echo_module {}
      execsql $sql
      set ::echo_module
    } [list {*}$expect]
    xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
    xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8abc
  }
} {
  do_test 1.$tn {
    set echo_module {}
    execsql $sql
    set ::echo_module
  } [list {*}$expect]
  }
}


#--------------------------------------------------------------------------

register_tclvar_module db
set ::xyz 10

Changes to test/vtabJ.test.

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
118
119
120
121
122
123
124




























125
126







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


} {xx att}

do_execsql_test 181 {
  DELETE FROM tclvar WHERE name BETWEEN 'xx' AND 'xx' OR name='xx';
  SELECT name, value FROM tclvar where name = 'xx';
} {}

#-------------------------------------------------------------------------

do_execsql_test 200 {
  CREATE TABLE var(k TEXT, v TEXT);
  INSERT INTO var VALUES('testvar1', 10);
  INSERT INTO var VALUES('testvar2', 20);
  INSERT INTO var VALUES('testvar3', 30);
}

do_test 210 {
  foreach {testvar1 testvar2 testvar3} {1 2 3} {}
  execsql {
    UPDATE tclvar SET value = var.v FROM var WHERE name = var.k;
  }
  list $testvar1 $testvar2 $testvar3
} {10 20 30}

do_test 220 {
  execsql {
    CREATE TABLE nam(k TEXT, v TEXT);
    INSERT INTO nam VALUES('testvar1', 'tv1');
    INSERT INTO nam VALUES('testvar2', 'tv2');
    INSERT INTO nam VALUES('testvar3', 'tv3');
    UPDATE tclvar SET fullname = nam.v FROM nam WHERE name = nam.k;
  }
  list $tv1 $tv2 $tv3
} {10 20 30}


finish_test

Changes to test/wal.test.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
39
40
41
42
43
44
45

46
47
48
49
50
51
52







-







proc sqlite3_wal {args} {
  eval sqlite3 $args
  [lindex $args 0] eval { PRAGMA auto_vacuum = 0 }
  [lindex $args 0] eval { PRAGMA page_size = 1024 }
  [lindex $args 0] eval { PRAGMA journal_mode = wal }
  [lindex $args 0] eval { PRAGMA synchronous = normal }
  [lindex $args 0] function blob blob
  db timeout 1000
}

proc log_deleted {logfile} {
  return [expr [file exists $logfile]==0]
}

#
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
1509
1510
1511
1512
1513
1514
1515
1516































1517
1518








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  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/wal2.test.

118
119
120
121
122
123
124
125

126
127
128
129
130

131
132
133
134
135
136
137
118
119
120
121
122
123
124

125





126
127
128
129
130
131
132
133







-
+
-
-
-
-
-
+







  }
} {4 10}
do_test wal2-1.1 {
  execsql { SELECT count(a), sum(a) FROM t1 } db2
} {4 10}

set RECOVER [list                                      \
  {0 1 lock exclusive}   {1 2 lock exclusive}          \
  {0 1 lock exclusive}   {1 2 lock exclusive} {4 4 lock exclusive} \
  {4 1 lock exclusive}   {4 1 unlock exclusive}        \
  {5 1 lock exclusive}   {5 1 unlock exclusive}        \
  {6 1 lock exclusive}   {6 1 unlock exclusive}        \
  {7 1 lock exclusive}   {7 1 unlock exclusive}        \
  {1 2 unlock exclusive} {0 1 unlock exclusive}        \
  {1 2 unlock exclusive} {4 4 unlock exclusive} {0 1 unlock exclusive}  \
]
set READ [list                                         \
  {4 1 lock shared}    {4 1 unlock shared}             \
]
set INITSLOT [list                                     \
  {4 1 lock exclusive} {4 1 unlock exclusive}          \
]
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
390
391
392
393
394
395
396

397








398

399
400
401
402
403
404
405
406







-
+
-
-
-
-
-
-
-
-

-
+







# required the client grabs all exclusive locks (just as it would for a
# recovery performed as a pre-cursor to a normal database transaction).
#
set expected_locks [list]
lappend expected_locks {1 1 lock exclusive}   ;# Lock checkpoint
lappend expected_locks {0 1 lock exclusive}   ;# Lock writer
lappend expected_locks {2 1 lock exclusive}   ;# Lock recovery
# lappend expected_locks {4 4 lock exclusive}   ;# Lock all aReadMark[]
lappend expected_locks {4 4 lock exclusive}   ;# Lock all aReadMark[]
lappend expected_locks {4 1 lock exclusive}   ;# Lock aReadMark[1]
lappend expected_locks {4 1 unlock exclusive} ;# Unlock aReadMark[1]
lappend expected_locks {5 1 lock exclusive}  
lappend expected_locks {5 1 unlock exclusive}
lappend expected_locks {6 1 lock exclusive} 
lappend expected_locks {6 1 unlock exclusive}
lappend expected_locks {7 1 lock exclusive} 
lappend expected_locks {7 1 unlock exclusive}
lappend expected_locks {2 1 unlock exclusive} ;# Unlock recovery 
# lappend expected_locks {4 4 unlock exclusive} ;# Unlock all aReadMark[] 
lappend expected_locks {4 4 unlock exclusive} ;# Unlock all aReadMark[] 
lappend expected_locks {0 1 unlock exclusive} ;# Unlock writer
lappend expected_locks {3 1 lock exclusive}   ;# Lock aReadMark[0]
lappend expected_locks {3 1 unlock exclusive} ;# Unlock aReadMark[0]
lappend expected_locks {1 1 unlock exclusive} ;# Unlock checkpoint
do_test wal2-5.1 {
  proc tvfs_cb {method args} {
    set ::shm_file [lindex $args 0]
633
634
635
636
637
638
639
640

641
642
643
644
645

646
647
648
649
650
651
652
621
622
623
624
625
626
627

628





629
630
631
632
633
634
635
636







-
+
-
-
-
-
-
+







  testvfs tvfs
  tvfs script tvfs_cb
  sqlite3 db test.db -vfs tvfs
  set {} {}
} {}

set RECOVERY {
  {0 1 lock exclusive}   {1 2 lock exclusive}
  {0 1 lock exclusive} {1 2 lock exclusive} {4 4 lock exclusive}
  {4 1 lock exclusive}   {4 1 unlock exclusive}
  {5 1 lock exclusive}   {5 1 unlock exclusive}
  {6 1 lock exclusive}   {6 1 unlock exclusive}
  {7 1 lock exclusive}   {7 1 unlock exclusive}
  {1 2 unlock exclusive} {0 1 unlock exclusive}
  {1 2 unlock exclusive} {4 4 unlock exclusive} {0 1 unlock exclusive}
}
set READMARK0_READ {
  {3 1 lock shared} {3 1 unlock shared}
}
set READMARK0_WRITE {
  {3 1 lock shared} 
  {0 1 lock exclusive} {3 1 unlock shared} 

Changes to test/walprotocol.test.

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
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







-
-
+
+
-
-
-
-
-
+
-






-
-
+
+
-
-
-
-
-
+
-







do_test 1.1 {
  testvfs T
  T filter xShmLock 
  T script lock_callback
  set ::locks [list]
  sqlite3 db test.db -vfs T
  execsql { SELECT * FROM x }
  lrange $::locks 0 11
} [list {0 1 lock exclusive} {1 2 lock exclusive}     \
  lrange $::locks 0 5
} [list {0 1 lock exclusive} {1 2 lock exclusive} {4 4 lock exclusive} \
        {4 1 lock exclusive} {4 1 unlock exclusive}   \
        {5 1 lock exclusive} {5 1 unlock exclusive}   \
        {6 1 lock exclusive} {6 1 unlock exclusive}   \
        {7 1 lock exclusive} {7 1 unlock exclusive}   \
        {1 2 unlock exclusive}   \
        {1 2 unlock exclusive} {4 4 unlock exclusive} {0 1 unlock exclusive}  \
        {0 1 unlock exclusive}  \
]
do_test 1.2 {
  db close
  set ::locks [list]
  sqlite3 db test.db -vfs T
  execsql { SELECT * FROM x }
  lrange $::locks 0 11
} [list {0 1 lock exclusive} {1 2 lock exclusive}     \
  lrange $::locks 0 5
} [list {0 1 lock exclusive} {1 2 lock exclusive} {4 4 lock exclusive} \
        {4 1 lock exclusive} {4 1 unlock exclusive}   \
        {5 1 lock exclusive} {5 1 unlock exclusive}   \
        {6 1 lock exclusive} {6 1 unlock exclusive}   \
        {7 1 lock exclusive} {7 1 unlock exclusive}   \
        {1 2 unlock exclusive}   \
        {1 2 unlock exclusive} {4 4 unlock exclusive} {0 1 unlock exclusive}  \
        {0 1 unlock exclusive}  \
]
proc lock_callback {method filename handle lock} {
  if {$lock == "1 2 lock exclusive"} { return SQLITE_BUSY }
  return SQLITE_OK
}
puts "# Warning: This next test case causes SQLite to call xSleep(1) 100 times."
puts "# Normally this equates to a delay of roughly 10 seconds, but if SQLite"
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111







-
+







  return SQLITE_OK
}
do_test 1.5 {
  db close
  set ::locks [list]
  sqlite3 db test.db -vfs T
  catchsql { SELECT * FROM x }
} {0 z}
} {1 {locking protocol}}
db close
T delete

#-------------------------------------------------------------------------
# 
do_test 2.1 {
  forcedelete test.db test.db-journal test.db wal
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
+







sqlite3 db2 test.db
puts "# Warning: Another slow test!"
do_test 2.5 {
  execsql { SELECT * FROM b }
} {Tehran Qom Markazi Qazvin Gilan Ardabil}
do_test 2.6 {
  set ::r
} {0 {Tehran Qom Markazi Qazvin Gilan Ardabil}}
} {1 {locking protocol}}

db close
db2 close

faultsim_restore_and_reopen
sqlite3 db2 test.db
T filter xShmLock
188
189
190
191
192
193
194
195

196
197
198
199
200
201
178
179
180
181
182
183
184

185
186
187
188
189
190
191







-
+






unset ::r
puts "# Warning: Last one!"
do_test 2.7 {
  execsql { SELECT * FROM b }
} {Tehran Qom Markazi Qazvin Gilan Ardabil}
do_test 2.8 {
  set ::r
} {0 {Tehran Qom Markazi Qazvin Gilan Ardabil}}
} {1 {locking protocol}}

db close
db2 close
T delete

finish_test

Deleted test/walsetlk.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






































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020 May 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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set testprefix walsetlk

ifcapable !wal {finish_test ; return }
db timeout 1000

#-------------------------------------------------------------------------
# 1.*: Test that nothing goes wrong if recovery is forced while opening
#      a write transaction or performing a checkpoint with blocking locks.
#

do_execsql_test 1.0 {
  CREATE TABLE t1(x, y);
  PRAGMA journal_mode = wal;
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
  INSERT INTO t1 VALUES(5, 6);
  INSERT INTO t1 VALUES(7, 8);
} {wal}

sqlite3 db2 test.db
db2 timeout 1000

do_execsql_test -db db2 1.1 {
  SELECT * FROM t1
} {1 2 3 4 5 6 7 8}

set fd [open test.db-shm r+]
puts $fd "blahblahblahblah"
flush $fd

do_execsql_test 1.2 {
  BEGIN;
    INSERT INTO t1 VALUES(9, 10);
}

do_execsql_test -db db2 1.3 {
  SELECT * FROM t1
} {1 2 3 4 5 6 7 8}

do_test 1.4 {
  list [catch {db2 eval { BEGIN EXCLUSIVE }} msg] $msg
} {1 {database is locked}}

do_execsql_test 1.5 { COMMIT }
do_execsql_test -db db2 1.6 {
  SELECT * FROM t1
} {1 2 3 4 5 6 7 8 9 10}

puts $fd "blahblahblahblah"
flush $fd

do_execsql_test -db db2 1.7 {
  PRAGMA wal_checkpoint = TRUNCATE
} {0 0 0}

do_test 1.8 {
  file size test.db-wal
} 0

close $fd
db close
db2 close
#-------------------------------------------------------------------------

do_multiclient_test tn {
  do_test 2.$tn.1 {
    sql1 {
      PRAGMA journal_mode = wal;
      CREATE TABLE t1(s, v);
      INSERT INTO t1 VALUES(1, 2);
      INSERT INTO t1 VALUES(3, 4);
      INSERT INTO t1 VALUES(5, 6);
    }
    code1 { db timeout 2000 }
  } {}

  do_test 2.$tn.2 {
    sql2 {
      BEGIN;
        INSERT INTO t1 VALUES(7, 8);
    }
  } {}

  do_test 2.$tn.3 {
    set us [lindex [time { catch {db eval "BEGIN EXCLUSIVE"} }] 0]
    expr $us>1000000 && $us<4000000
  } {1}

  do_test 2.$tn.4 {
    sql2 { COMMIT }
    sql1 { SELECT * FROM t1 }
  } {1 2 3 4 5 6 7 8}

  do_test 2.$tn.5 {
    sql2 {
      BEGIN;
        INSERT INTO t1 VALUES(9, 10);
    }
  } {}

  do_test 2.$tn.6 {
    set us [lindex [time { catch {db eval "PRAGMA wal_checkpoint=RESTART"} }] 0]
    expr $us>1000000 && $us<4000000
  } {1}

  do_test 2.$tn.7 {
    sql2 {
      COMMIT;
      BEGIN;
        SELECT * FROM t1;
    }
  } {1 2 3 4 5 6 7 8 9 10}

  do_test 2.$tn.8 {
    set us [lindex [time { catch {db eval "PRAGMA wal_checkpoint=RESTART"} }] 0]
    expr $us>1000000 && $us<4000000
  } {1}

  do_test 2.$tn.9 {
    sql3 {
      INSERT INTO t1 VALUES(11, 12);
    }
    sql2 {
      COMMIT;
      BEGIN;
        SELECT * FROM t1;
    }
    sql3 {
      INSERT INTO t1 VALUES(13, 14);
    }
  } {}

  do_test 2.$tn.10 {
    set us [lindex [time { catch {db eval "PRAGMA wal_checkpoint=RESTART"} }] 0]
    expr $us>1000000 && $us<4000000
  } {1}

  do_test 2.$tn.11 {
    sql3 {
      BEGIN;
        SELECT * FROM t1;
    }
    sql1 { INSERT INTO t1 VALUES(15, 16); }
  } {}

  do_test 2.$tn.12 {
    set us [lindex [time { catch {db eval "PRAGMA wal_checkpoint=RESTART"} }] 0]
    expr $us>1000000 && $us<4000000
  } {1}

  do_test 2.$tn.13 {
    sql2 {
      COMMIT;
      BEGIN;
        SELECT * FROM t1;
    }
    sql1 { INSERT INTO t1 VALUES(17, 18); }
  } {}

  do_test 2.$tn.14 {
    set us [lindex [time { catch {db eval "PRAGMA wal_checkpoint=RESTART"} }] 0]
    expr $us>1000000 && $us<4000000
  } {1}
  
}

#-------------------------------------------------------------------------
reset_db
sqlite3 db2 test.db
db2 timeout 1000
do_execsql_test 3.0 {
  PRAGMA journal_mode = wal;
  CREATE TABLE x1(x, y);
  BEGIN;
    INSERT INTO x1 VALUES(1, 2);
} {wal}

do_test 3.1 {
  list [catch { db2 eval {BEGIN EXCLUSIVE} } msg] $msg
} {1 {database is locked}}

finish_test

Changes to test/walvfs.test.

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
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







-
+
-
-
-
+






-



-
-
-
-







} {1 interrupted}

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
      sqlite3_memdebug_fail 5 -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)) }]
      catchsql { SELECT 'a big long string!' }
      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
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
383
384
385
386
387
388
389

390
391
392
393
394
395
396







-







  db2 close
} {}

do_execsql_test 8.3 { 
  PRAGMA wal_checkpoint;
  SELECT count(*) FROM t1 
} {0 5 5 21}
db close
tvfs2 delete

#-------------------------------------------------------------------------
reset_db
db close
sqlite3 db test.db -vfs tvfs
do_execsql_test 9.0 {
430
431
432
433
434
435
436

422
423
424
425
426
427
428
429







+
  catchsql { SELECT count(*) FROM t1 } db2
} {1 {disk I/O error}}

db close
db2 close
tvfs delete
finish_test

Changes to test/wapptest.tcl.

1
2
3
4
5
6
7




8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58

59
60
61
62
63
64
65
66
67
68


69


70

71
72
73




74
75
76
77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92
93
94
95
96
97
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







+
+
+
+











-
+




-
-
-
-




-
+







+
+
+












-
-
-
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+

+
+
-
+
-
-
-
+
+
+
+



-
-
-
-




-
-
-
+
+
-

-







#!/bin/sh
# \
exec wapptclsh "$0" ${1+"$@"}

# package required wapp
source [file join [file dirname [info script]] wapp.tcl]

# Read the data from the releasetest_data.tcl script.
#
source [file join [file dirname [info script]] releasetest_data.tcl]

# Variables set by the "control" form:
#
#   G(platform) - User selected platform.
#   G(test)     - Set to "Normal", "Veryquick", "Smoketest" or "Build-Only".
#   G(keep)     - Boolean. True to delete no files after each test.
#   G(msvc)     - Boolean. True to use MSVC as the compiler.
#   G(tcl)      - Use Tcl from this directory for builds.
#   G(jobs)     - How many sub-processes to run simultaneously.
#
set G(platform) $::tcl_platform(os)-$::tcl_platform(machine)
set G(test)     Normal
set G(keep)     1
set G(keep)     0
set G(msvc)     0
set G(tcl)      [::tcl::pkgconfig get libdir,install]
set G(jobs)     3
set G(debug)    0

set G(noui)     0
set G(stdout)   0


proc wapptest_init {} {
  global G

  set lSave [list platform test keep msvc tcl jobs debug noui stdout] 
  set lSave [list platform test keep msvc tcl jobs debug] 
  foreach k $lSave { set A($k) $G($k) }
  array unset G
  foreach k $lSave { set G($k) $A($k) }

  # The root of the SQLite source tree.
  set G(srcdir)   [file dirname [file dirname [info script]]]

  # releasetest.tcl script
  set G(releaseTest) [file join [file dirname [info script]] releasetest.tcl]

  set G(sqlite_version) "unknown"

  # Either "config", "running" or "stopped":
  set G(state) "config"

  set G(hostname) "(unknown host)"
  catch { set G(hostname) [exec hostname] } 
  set G(host) $G(hostname)
  append G(host) " $::tcl_platform(os) $::tcl_platform(osVersion)"
  append G(host) " $::tcl_platform(machine) $::tcl_platform(byteOrder)"
}

proc wapptest_run {} {
  global G
  set_test_array
  set G(state) "running"

# Check to see if there are uncommitted changes in the SQLite source
  wapptest_openlog

# directory. Return true if there are, or false otherwise.
  wapptest_output "Running the following for $G(platform). $G(jobs) jobs."
  foreach t $G(test_array) {
    set config [dict get $t config]
    set target [dict get $t target]
    wapptest_output [format "    %-25s%s" $config $target]
  }
  wapptest_output [string repeat * 70]
}

proc releasetest_data {args} {
#
proc check_uncommitted {} {
  global G
  set ret 0
  set pwd [pwd]
  set rtd [file join $G(srcdir) test releasetest_data.tcl]
  cd $G(srcdir)
  set fd [open "|[info nameofexecutable] $rtd $args" r+]
  set ret [read $fd]
  close $fd
  if {[catch {exec fossil changes} res]==0 && [string trim $res]!=""} {
    set ret 1
  }
  cd $pwd
  return $ret
}

# Generate the text for the box at the top of the UI. The current SQLite
# version, according to fossil, along with a warning if there are 
# uncommitted changes in the checkout.
#
proc generate_fossil_info {} {
  global G
  set pwd [pwd]
  cd $G(srcdir)
  set rc [catch {
    set r1 [exec fossil info]
    set r2 [exec fossil changes]
  if {[catch {exec fossil info}    r1]} return
  if {[catch {exec fossil changes} r2]} return
  }]
  cd $pwd
  if {$rc} return

  foreach line [split $r1 "\n"] {
    if {[regexp {^checkout: *(.*)$} $line -> co]} {
      wapp-trim { <br> %html($co) }
    }
  }

109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
95
96
97
98
99
100
101



102
103
104
105
106
107
108
109







-
-
-
+







# app is in some other state ("running" or "stopped"), this command
# is a no-op.
#
proc set_test_array {} {
  global G
  if { $G(state)=="config" } {
    set G(test_array) [list]
    set debug "-debug"
    if {$G(debug)==0} { set debug "-nodebug"}
    foreach {config target} [releasetest_data tests $debug $G(platform)] {
    foreach {config target} $::Platforms($G(platform)) {

      # If using MSVC, do not run sanitize or valgrind tests. Or the
      # checksymbols test.
      if {$G(msvc) && (
          "Sanitize" == $config 
       || "checksymbols" in $target
       || "valgrindtest" in $target
139
140
141
142
143
144
145
















146
147
148
149
150
151
152
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







              set target testfixture.exe
            }
          }
        }
      }

      lappend G(test_array) [dict create config $config target $target]

      set exclude [list checksymbols valgrindtest fuzzoomtest]
      if {$G(debug) && !($target in $exclude)} {
        set debug_idx [lsearch -glob $::Configs($config) -DSQLITE_DEBUG*]
        set xtarget $target
        regsub -all {fulltest[a-z]*} $xtarget test xtarget
        if {$debug_idx<0} {
          lappend G(test_array) [
            dict create config $config-(Debug) target $xtarget
          ]
        } else {
          lappend G(test_array) [
            dict create config $config-(NDebug) target $xtarget
          ]
        }
      }
    }
  }
}

proc count_tests_and_errors {name logfile} {
  global G

160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174







-
+







      set seen 1
      if {$nerr>0} {
        set G(test.$name.errmsg) $line
      }
    }
    if {[regexp {runtime error: +(.*)} $line all msg]} {
      # skip over "value is outside range" errors
      if {[regexp {.* is outside the range of representable} $line]} {
      if {[regexp {value .* is outside the range of representable} $line]} {
         # noop
      } else {
        incr G(test.$name.nError)
        if {$G(test.$name.errmsg)==""} {
          set G(test.$name.errmsg) $msg
        }
      }
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-












-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    set G(test.$name.errmsg) "Test did not complete"
    if {[file readable core]} {
      append G(test.$name.errmsg) " - core file exists"
    }
  }
}

proc wapptest_output {str} {
  global G
  if {$G(stdout)} { puts $str }
  if {[info exists G(log)]} { 
    puts $G(log) $str 
    flush $G(log)
  }
}
proc wapptest_openlog {} {
  global G
  set G(log) [open wapptest-out.txt w+]
}
proc wapptest_closelog {} {
  global G
  close $G(log)
  unset G(log)
}

proc format_seconds {seconds} {
  set min [format %.2d [expr ($seconds / 60) % 60]]
  set  hr [format %.2d [expr $seconds / 3600]]
  set sec [format %.2d [expr $seconds % 60]]
  return "$hr:$min:$sec"
}

# This command is invoked once a slave process has finished running its
# tests, successfully or otherwise. Parameter $name is the name of the 
# test, $rc the exit code returned by the slave process.
#
proc slave_test_done {name rc} {
  global G
  set G(test.$name.done) [clock seconds]
  set G(test.$name.nError) 0
  set G(test.$name.nTest) 0
  set G(test.$name.errmsg) ""
  if {$rc} {
    incr G(test.$name.nError)
  }
  if {[file exists $G(test.$name.log)]} {
    count_tests_and_errors $name $G(test.$name.log)
  }

}
  # If the "keep files" checkbox is clear, delete all files except for
  # the executables and test logs. And any core file that is present.
  if {$G(keep)==0} {
    set keeplist {
      testfixture testfixture.exe
      sqlite3 sqlite3.exe
      test.log test-out.txt
      core
      wapptest_make.sh
      wapptest_configure.sh
      wapptest_run.tcl
    }

    foreach f [glob -nocomplain [file join $G(test.$name.dir) *]] {
      set t [file tail $f]
      if {[lsearch $keeplist $t]<0} {
        catch { file delete -force $f }
      }
    }
  }

  # Format a message regarding the success or failure of hte test.
  set t [format_seconds [expr $G(test.$name.done) - $G(test.$name.start)]]
  set res "OK"
  if {$G(test.$name.nError)} { set res "FAILED" }
  set dots [string repeat . [expr 60 - [string length $name]]]
  set msg "$name $dots $res ($t)"

  wapptest_output $msg
  if {[info exists G(test.$name.errmsg)] && $G(test.$name.errmsg)!=""} {
    wapptest_output "    $G(test.$name.errmsg)"
  }
}

# This is a fileevent callback invoked each time a file-descriptor that
# connects this process to a slave process is readable.
#
proc slave_fileevent {name} {
  global G
  set fd $G(test.$name.channel)

  if {[eof $fd]} {
    fconfigure $fd -blocking 1
    set rc [catch { close $fd }]
    unset G(test.$name.channel)
    slave_test_done $name $rc
  } else {
    set line [gets $fd]
    if {[string trim $line] != ""} { puts "Trace   : $name - \"$line\"" }
  }

  do_some_stuff
}

# Return the contents of the "slave script" - the script run by slave 
# processes to actually perform the test. All it does is execute the
# test script already written to disk (wapptest_cmd.sh or wapptest_cmd.bat).
#
proc wapptest_slave_script {} {
  global G
  if {$G(msvc)==0} {
    set dir [file join .. $G(srcdir)]
    set res [subst -nocommands {
      set rc [catch "exec sh wapptest_cmd.sh {$dir} >>& test.log" ]
      exit [set rc]
    }]
  } else {
    set dir [file nativename [file normalize $G(srcdir)]]
    set dir [string map [list "\\" "\\\\"] $dir]
    set res [subst -nocommands {
      set rc [catch "exec wapptest_cmd.bat {$dir} >>& test.log" ]
      exit [set rc]
    }]
  }

  set res
}


# Launch a slave process to run a test.
#
proc slave_launch {name target dir} {
  global G

  catch { file mkdir $dir } msg
  foreach f [glob -nocomplain [file join $dir *]] {
    catch { file delete -force $f }
  }
  set G(test.$name.dir) $dir

  # Write the test command to wapptest_cmd.sh|bat.
  #
  set ext sh
  if {$G(msvc)} { set ext bat }
  set fd1 [open [file join $dir wapptest_cmd.$ext] w]
  if {$G(msvc)} {
    puts $fd1 [releasetest_data script -msvc $name $target]
  } else {
    puts $fd1 [releasetest_data script $name $target]
  }
  close $fd1

  # Write the wapptest_run.tcl script to the test directory. To run the
  # commands in the other two files.
  #
  set fd3 [open [file join $dir wapptest_run.tcl] w]
  puts $fd3 [wapptest_slave_script]
  close $fd3

  set pwd [pwd]
  cd $dir
  set fd [open "|[info nameofexecutable] wapptest_run.tcl" r+]
  cd $pwd

  set G(test.$name.channel) $fd
  fconfigure $fd -blocking 0
  fileevent $fd readable [list slave_fileevent $name]
}

proc do_some_stuff {} {
  global G

  # Count the number of running jobs. A running job has an entry named
  # "channel" in its dictionary.
  set nRunning 0
  set bFinished 1
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
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







-
-


-


-
-








-

-

+
-
+
+
+

+
-
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    foreach j $G(test_array) {
      set name [dict get $j config]
      incr nError $G(test.$name.nError)
      incr nTest $G(test.$name.nTest)
      incr nConfig 
    }
    set G(result) "$nError errors from $nTest tests in $nConfig configurations."
    wapptest_output [string repeat * 70]
    wapptest_output $G(result)
    catch {
      append G(result) " SQLite version $G(sqlite_version)"
      wapptest_output " SQLite version $G(sqlite_version)"
    }
    set G(state) "stopped"
    wapptest_closelog
    if {$G(noui)} { exit 0 }
  } else {
    set nLaunch [expr $G(jobs) - $nRunning]
    foreach j $G(test_array) {
      if {$nLaunch<=0} break
      set name [dict get $j config]
      if { ![info exists G(test.$name.channel)]
        && ![info exists G(test.$name.done)]
      } {

        set target [dict get $j target]
        set dir [string tolower [string map {" " _ "-" _} $name]]
        set G(test.$name.start) [clock seconds]
        set fd [open "|[info nameofexecutable] $G(releaseTest) --slave" r+]
        set G(test.$name.log) [file join $dir test.log]
        set G(test.$name.channel) $fd
        fconfigure $fd -blocking 0
        fileevent $fd readable [list slave_fileevent $name]

        puts $fd [list 0 $G(msvc) 0 $G(keep)]
        slave_launch $name $target $dir

        set wtcl ""
        if {$G(tcl)!=""} { set wtcl "--with-tcl=$G(tcl)" }

        # If this configuration is named <name>-(Debug) or <name>-(NDebug),
        # then add or remove the SQLITE_DEBUG option from the base
        # configuration before running the test.
        if {[regexp -- {(.*)-(\(.*\))} $name -> head tail]} {
          set opts $::Configs($head)
          if {$tail=="(Debug)"} {
            append opts " -DSQLITE_DEBUG=1 -DSQLITE_EXTRA_IFNULLROW=1"
          } else {
            regsub { *-DSQLITE_MEMDEBUG[^ ]* *} $opts { } opts
            regsub { *-DSQLITE_DEBUG[^ ]* *} $opts { } opts
          }
        } else {
          set opts $::Configs($name)
        }

        set L [make_test_suite $G(msvc) $wtcl $name $target $opts]
        puts $fd $L
        flush $fd
        set G(test.$name.log) [file join [lindex $L 1] test.log]
        incr nLaunch -1
      }
    }
  }
}

proc generate_select_widget {label id lOpt opt} {
458
459
460
461
462
463
464
465

466
467
468
469
470
471
472
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361







-
+







  wapp-trim {
    </div>
    <div class="border" id=controls> 
    <form action="control" method="post" name="control">
  }

  # Build the "platform" select widget. 
  set lOpt [releasetest_data platforms]
  set lOpt [array names ::Platforms]
  generate_select_widget Platform control_platform $lOpt $G(platform)

  # Build the "test" select widget. 
  set lOpt [list Normal Veryquick Smoketest Build-Only] 
  generate_select_widget Test control_test $lOpt $G(test)

  # Build the "jobs" select widget. Options are 1 to 8.
546
547
548
549
550
551
552




553

554
555
556
557
558
559
560
435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453







+
+
+
+
-
+







        if {$G(test.$config.nError)>0} {
          set class "testfail" 
        } else {
          set class "testdone"
        }
        set seconds [expr $G(test.$config.done) - $G(test.$config.start)]
      }

      set min [format %.2d [expr ($seconds / 60) % 60]]
      set  hr [format %.2d [expr $seconds / 3600]]
      set sec [format %.2d [expr $seconds % 60]]
      set seconds [format_seconds $seconds]
      set seconds "$hr:$min:$sec"
    }

    wapp-trim {
      <tr class=%string($class)>
      <td class="nowrap"> %html($config) 
      <td class="padleft nowrap"> %html($target)
      <td class="padleft nowrap"> %html($seconds)
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
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







-
+
+














-







    if {[wapp-param-exists control_$v]} {
      set G($v) [wapp-param control_$v]
    }
  }

  if {[wapp-param-exists control_run]} {
    # This is a "run test" command.
    wapptest_run
    set_test_array
    set ::G(state) "running"
  }

  if {[wapp-param-exists control_stop]} {
    # A "STOP tests" command.
    set G(state) "stopped"
    set G(result) "Test halted by user"
    foreach j $G(test_array) {
      set name [dict get $j config]
      if { [info exists G(test.$name.channel)] } {
        close $G(test.$name.channel)
        unset G(test.$name.channel)
        slave_test_done $name 1
      }
    }
    wapptest_closelog
  }

  if {[wapp-param-exists control_reset]} {
    # A "reset app" command.
    set G(state) "config"
    wapptest_init
  }
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891

892
893
894
895
896

665
666
667
668
669
670
671

















































672































































673





674







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+
  wapp-trim {
    <pre>
    %html($data)
    </pre>
  }
}

# Print out a usage message. Then do [exit 1].
#
proc wapptest_usage {} {
  puts stderr {
This Tcl script is used to test various configurations of SQLite. By
default it uses "wapp" to provide an interactive interface. Supported 
command line options (all optional) are:

    --platform    PLATFORM         (which tests to run)
    --smoketest                    (run "make smoketest" only)
    --veryquick                    (run veryquick.test only)
    --buildonly                    (build executables, do not run tests)
    --jobs        N                (number of concurrent jobs)
    --tcl         DIR              (where to find tclConfig.sh)
    --deletefiles                  (delete extra files after each test)
    --msvc                         (Use MS Visual C)
    --debug                        (Also run [n]debugging versions of tests)
    --noui                         (do not use wapp)
  }
  exit 1
}

# Sort command line arguments into two groups: those that belong to wapp,
# and those that belong to the application.
set WAPPARG(-server)      1
set WAPPARG(-local)       1
set WAPPARG(-scgi)        1
set WAPPARG(-remote-scgi) 1
set WAPPARG(-fromip)      1
set WAPPARG(-nowait)      0
set WAPPARG(-cgi)         0
set lWappArg [list]
set lTestArg [list]
for {set i 0} {$i < [llength $argv]} {incr i} {
  set arg [lindex $argv $i]
  if {[string range $arg 0 1]=="--"} {
    set arg [string range $arg 1 end]
  }
  if {[info exists WAPPARG($arg)]} {
    lappend lWappArg $arg
    if {$WAPPARG($arg)} {
      incr i
      lappend lWappArg [lindex $argv $i]
    }
  } else {
    lappend lTestArg $arg
  }
}

wapptest_init
for {set i 0} {$i < [llength $lTestArg]} {incr i} {
  set opt [lindex $lTestArg $i]
  if {[string range $opt 0 1]=="--"} {
    set opt [string range $opt 1 end]
  }
  switch -- $opt {
    -platform {
      if {$i==[llength $lTestArg]-1} { wapptest_usage }
      incr i
      set arg [lindex $lTestArg $i]
      set lPlatform [releasetest_data platforms]
      if {[lsearch $lPlatform $arg]<0} {
        puts stderr "No such platform: $arg. Platforms are: $lPlatform"
        exit -1
      }
      set G(platform) $arg
    }

    -smoketest { set G(test) Smoketest }
    -veryquick { set G(test) Veryquick }
    -buildonly { set G(test) Build-Only }
    -jobs {
      if {$i==[llength $lTestArg]-1} { wapptest_usage }
      incr i
      set G(jobs) [lindex $lTestArg $i]
    }

    -tcl {
      if {$i==[llength $lTestArg]-1} { wapptest_usage }
      incr i
      set G(tcl) [lindex $lTestArg $i]
    }

    -deletefiles {
      set G(keep) 0
    }

    -msvc {
      set G(msvc) 1
    }

    -debug {
      set G(debug) 1
    }

    -noui {
      set G(noui) 1
      set G(stdout) 1
    }

    -stdout {
      set G(stdout) 1
    }

    default {
      puts stderr "Unrecognized option: [lindex $lTestArg $i]"
      wapptest_usage
    }
  }
}

if {$G(noui)==0} {
  wapp-start $lWappArg
wapp-start $argv
} else {
  wapptest_run
  do_some_stuff
  vwait forever
}

Changes to test/where.test.

486
487
488
489
490
491
492
493

494
495
496
497
498

499
500
501
502
503
504
505
486
487
488
489
490
491
492

493
494
495
496
497

498
499
500
501
502
503
504
505







-
+




-
+







      SELECT * FROM t1 WHERE x IN (1,7) AND y NOT IN (6400,8100) ORDER BY 1;
    }
  } {2 1 9 3 1 16 6}
  do_test where-5.14 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1;
    }
  } {2 1 9 5}
  } {2 1 9 4}
  do_test where-5.15 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,16) ORDER BY 1;
    }
  } {2 1 9 3 1 16 9}
  } {2 1 9 3 1 16 8}
  do_test where-5.100 {
    db eval {
      SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969)
       ORDER BY x, y
    }
  } {2 1 9 54 5 3025 62 5 3969}
  do_test where-5.101 {
1492
1493
1494
1495
1496
1497
1498
1499
1500


1501
1502
1503
1504
1505
1506
1507
1492
1493
1494
1495
1496
1497
1498


1499
1500
1501
1502
1503
1504
1505
1506
1507







-
-
+
+







  CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c);
  CREATE UNIQUE INDEX i2 ON t2(c);
  INSERT INTO t2 VALUES(1, 'one', 'i');
  INSERT INTO t2 VALUES(2, 'two', 'ii');
  INSERT INTO t2 VALUES(3, 'three', 'iii');

  PRAGMA writable_schema = 1;
  UPDATE sqlite_schema SET rootpage = (
    SELECT rootpage FROM sqlite_schema WHERE name = 'i2'
  UPDATE sqlite_master SET rootpage = (
    SELECT rootpage FROM sqlite_master WHERE name = 'i2'
  ) WHERE name = 'i1';
}
db close
sqlite3 db test.db
do_catchsql_test where-25.1 {
  DELETE FROM t1 WHERE c='iii'
} {1 {database disk image is malformed}}
1520
1521
1522
1523
1524
1525
1526
1527
1528


1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545

1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1520
1521
1522
1523
1524
1525
1526


1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540





1541



























1542








-
-
+
+












-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c);
  CREATE UNIQUE INDEX i2 ON t2(c);
  INSERT INTO t2 VALUES(1, 'one', 'i');
  INSERT INTO t2 VALUES(2, 'two', 'ii');
  INSERT INTO t2 VALUES(3, 'three', 'iii');

  PRAGMA writable_schema = 1;
  UPDATE sqlite_schema SET rootpage = (
    SELECT rootpage FROM sqlite_schema WHERE name = 'i2'
  UPDATE sqlite_master SET rootpage = (
    SELECT rootpage FROM sqlite_master WHERE name = 'i2'
  ) WHERE name = 'i1';
}
db close
sqlite3 db test.db
do_catchsql_test where-25.4 {
  SELECT * FROM t1 WHERE c='iii'
} {0 {}}
do_catchsql_test where-25.5 {
  INSERT INTO t1 VALUES(4, 'four', 'iii') 
    ON CONFLICT(c) DO UPDATE SET b=NULL
} {1 {corrupt database}}

# 2019-08-21 Ticket https://www.sqlite.org/src/info/d9f584e936c7a8d0
#
db close
sqlite3 db :memory:
do_execsql_test where-26.1 {
finish_test
  CREATE TABLE t0(c0 INTEGER PRIMARY KEY, c1 TEXT);
  INSERT INTO t0(c0, c1) VALUES (1, 'a');
  CREATE TABLE t1(c0 INT PRIMARY KEY, c1 TEXT);
  INSERT INTO t1(c0, c1) VALUES (1, 'a');
  SELECT * FROM t0 WHERE '-1' BETWEEN 0 AND t0.c0;
} {1 a}
do_execsql_test where-26.2 {
  SELECT * FROM t1 WHERE '-1' BETWEEN 0 AND t1.c0;
} {1 a}
do_execsql_test where-26.3 {
  SELECT * FROM t0 WHERE '-1'>=0 AND '-1'<=t0.c0;
} {1 a}
do_execsql_test where-26.4 {
  SELECT * FROM t1 WHERE '-1'>=0 AND '-1'<=t1.c0;
} {1 a}
do_execsql_test where-26.5 {
  SELECT '-1' BETWEEN 0 AND t0.c0 FROM t0;
} {1}
do_execsql_test where-26.6 {
  SELECT '-1' BETWEEN 0 AND t1.c0 FROM t1;
} {1}
do_execsql_test where-26.7 {
  SELECT '-1'>=0 AND '-1'<=t0.c0 FROM t0;
} {1}
do_execsql_test where-26.8 {
  SELECT '-1'>=0 AND '-1'<=t1.c0 FROM t1;
} {1}

finish_test

Changes to test/where9.test.

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
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







-
+















-
+







-
+







do_test where9-4.5 {
  catchsql {
    SELECT a FROM t1 INDEXED BY t1b
     WHERE +b>1000
       AND (c=31031 OR d IS NULL)
     ORDER BY +a
  }
} {0 {92 93 97}}
} {1 {no query solution}}
do_test where9-4.6 {
  count_steps {
    SELECT a FROM t1 NOT INDEXED
     WHERE b>1000
       AND (c=31031 OR d IS NULL)
     ORDER BY +a
  }
} {92 93 97 scan 98 sort 1}
do_test where9-4.7 {
  catchsql {
    SELECT a FROM t1 INDEXED BY t1c
     WHERE b>1000
       AND (c=31031 OR d IS NULL)
     ORDER BY +a
  }
} {0 {92 93 97}}
} {1 {no query solution}}
do_test where9-4.8 {
  catchsql {
    SELECT a FROM t1 INDEXED BY t1d
     WHERE b>1000
       AND (c=31031 OR d IS NULL)
     ORDER BY +a
  }
} {0 {92 93 97}}
} {1 {no query solution}}

# The (c=31031 OR d IS NULL) clause is preferred over b>1000 because
# the former is an equality test which is expected to return fewer rows.
#
do_eqp_test where9-5.1 {
  SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL)
} {
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
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







-
+







-
+


-
+







do_test where9-6.8.1 {
  catchsql {
    DELETE FROM t1 INDEXED BY t1b
     WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL)
        OR (b NOT NULL AND c IS NULL AND d NOT NULL)
        OR (b NOT NULL AND c NOT NULL AND d IS NULL)
  }
} {0 {}}
} {1 {no query solution}}
do_test where9-6.8.2 {
  catchsql {
    UPDATE t1 INDEXED BY t1b SET a=a+100
     WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL)
        OR (b NOT NULL AND c IS NULL AND d NOT NULL)
        OR (b NOT NULL AND c NOT NULL AND d IS NULL)
  }
} {0 {}}
} {1 {no query solution}}

set solution_possible 0
ifcapable stat4 {
ifcapable stat4||stat3 {
  if {[permutation] != "no_optimization"} { set solution_possible 1 }
}
if $solution_possible {
  # When STAT3 is enabled, the "b NOT NULL" terms get translated
  # into b>NULL, which can be satified by the index t1b.  It is a very
  # expensive way to do the query, but it works, and so a solution is possible.
  do_test where9-6.8.3-stat4 {
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828
829

830
831
832
833
834
835
836
814
815
816
817
818
819
820

821
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836







-
+







-
+







  do_test where9-6.8.3 {
    catchsql {
      UPDATE t1 INDEXED BY t1b SET a=a+100
       WHERE (b IS NULL AND c NOT NULL AND d NOT NULL)
          OR (b NOT NULL AND c IS NULL AND d NOT NULL)
          OR (b NOT NULL AND c NOT NULL AND d IS NULL)
    }
  } {0 {}}
  } {1 {no query solution}}
  do_test where9-6.8.4 {
    catchsql {
      DELETE FROM t1 INDEXED BY t1b
       WHERE (b IS NULL AND c NOT NULL AND d NOT NULL)
          OR (b NOT NULL AND c IS NULL AND d NOT NULL)
          OR (b NOT NULL AND c NOT NULL AND d IS NULL)
    }
  } {0 {}}
  } {1 {no query solution}}
}
############################################################################
# Test cases where terms inside an OR series are combined with AND terms
# external to the OR clause.  In other words, cases where
#
#              x AND (y OR z)
#
855
856
857
858
859
860
861





862
863
864
865
866
867
868
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873







+
+
+
+
+







    CREATE INDEX t5yd ON t5(y, d);
    CREATE INDEX t5ye ON t5(y, e);
    CREATE INDEX t5yf ON t5(y, f);
    CREATE INDEX t5yg ON t5(y, g);
    CREATE TABLE t6(a, b, c, e, d, f, g, x, y);
    INSERT INTO t6 SELECT * FROM t5;
    ANALYZE t5;
  }
  ifcapable stat3 {
    sqlite3 db2 test.db
    db2 eval { DROP TABLE IF EXISTS sqlite_stat3 }
    db2 close
  }
} {}
do_test where9-7.1.1 {
  count_steps {
    SELECT a FROM t5 WHERE x='y' AND (b=913 OR c=27027) ORDER BY a;
  }
} {79 81 83 scan 0 sort 1}

Changes to test/whereA.test.

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
166
167
168
169
170
171
172















173
174







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a,b);
  INSERT INTO t1 VALUES(1,2);
  CREATE INDEX t1b ON t1(b);
  SELECT a FROM t1 WHERE b=-99 OR b>1;
} {1}

# 2020-10-02 OSSFuzz find for an issue introduced by a check-in
# on the previous day.
#
reset_db
do_execsql_test whereA-6.1 {
  CREATE TABLE t1(a, b);
  CREATE INDEX t1aa ON t1(a,a);
  INSERT INTO t1 VALUES(1,2);
  ANALYZE;
  UPDATE sqlite_stat1 SET stat='27 3 3' WHERE idx='t1aa';
  ANALYZE sqlite_schema;
  PRAGMA reverse_unordered_selects (1) ;
  SELECT a FROM t1 WHERE  a=1 OR a=2;
} {1}


finish_test

Changes to test/whereD.test.

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
332
333
334
335
336
337
338
















339
340
341
342
343
344
345







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







} {3 7 11 search 7}
do_searchcount_test 6.6.3 {
  SELECT c FROM x1 WHERE c=11 OR a=1 OR b=6 
} {11 3 7 search 7}
do_searchcount_test 6.6.4 {
  SELECT c FROM x1 WHERE b=6 OR c=11 OR a=1
} {7 11 3 search 7}

# 2020-02-22 ticket aa4378693018aa99
# In the OP_Column opcode, if a cursor is marked with OP_NullRow
# (because it is the right table of a LEFT JOIN that does not match)
# then do not substitute index cursors, as the index cursors do not
# have the VdbeCursor.nullRow flag set.
#
do_execsql_test 6.7 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t1(a UNIQUE, b UNIQUE);
  INSERT INTO t1(a,b) VALUES(null,2);
  CREATE VIEW t2 AS SELECT * FROM t1 WHERE b<10 OR a<7 ORDER BY b;
  SELECT t1.* FROM t1 LEFT JOIN t2 ON abs(t1.a)=abs(t2.b);
} {{} 2}


#-------------------------------------------------------------------------
#
do_execsql_test 7.0 {
  CREATE TABLE y1(a, b);
  CREATE TABLE y2(x, y);
  CREATE INDEX y2xy ON y2(x, y);

Changes to test/whereG.test.

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230



231
232
233
234
235
236
237
238
216
217
218
219
220
221
222








223
224
225

226
227
228
229
230
231
232







-
-
-
-
-
-
-
-
+
+
+
-







do_eqp_test 5.2.3 {
  SELECT * FROM t1 WHERE likelihood(b>?, 0.9)
} {SCAN TABLE t1}
do_eqp_test 5.2.4 {
  SELECT * FROM t1 WHERE likely(b>?)
} {SCAN TABLE t1}

ifcapable stat4 {
  do_eqp_test 5.3.1.stat4 {
    SELECT * FROM t1 WHERE a=?
  } {SCAN TABLE t1}
} else {
  do_eqp_test 5.3.1 {
    SELECT * FROM t1 WHERE a=?
  } {SEARCH TABLE t1 USING INDEX i1}
do_eqp_test 5.3.1 {
  SELECT * FROM t1 WHERE a=?
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
}
do_eqp_test 5.3.2 {
  SELECT * FROM t1 WHERE likelihood(a=?, 0.9)
} {SCAN TABLE t1}
do_eqp_test 5.3.3 {
  SELECT * FROM t1 WHERE likely(a=?)
} {SCAN TABLE t1}

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
262
263
264
265
266
267
268



269



























































270







-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_execsql_test 7.2 {
  SELECT likelihood(a,0.5), x FROM t1, t2 ORDER BY 1, 2;
} {1 3 1 4 9 3 9 4}
do_execsql_test 7.3 {
  SELECT coalesce(a,a), x FROM t1, t2 ORDER BY 1, 2;
} {1 3 1 4 9 3 9 4}

# 2019-08-22
# Ticket https://www.sqlite.org/src/info/7e07a3dbf5a8cd26
#

do_execsql_test 8.1 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0 (c0);
  INSERT INTO t0(c0) VALUES ('a');
  SELECT LIKELY(t0.rowid) <= '0' FROM t0;
} {1}
do_execsql_test 8.2 {
  SELECT * FROM t0 WHERE LIKELY(t0.rowid) <= '0';
} {a}
do_execsql_test 8.3 {
  SELECT (t0.rowid) <= '0' FROM t0;
} {0}
do_execsql_test 8.4 {
  SELECT * FROM t0 WHERE (t0.rowid) <= '0';
} {}
do_execsql_test 8.5 {
  SELECT unlikely(t0.rowid) <= '0', likelihood(t0.rowid,0.5) <= '0' FROM t0;
} {1 1}
do_execsql_test 8.6 {
  SELECT * FROM t0 WHERE unlikely(t0.rowid) <= '0';
} {a}
do_execsql_test 8.7 {
  SELECT * FROM t0 WHERE likelihood(t0.rowid, 0.5) <= '0';
} {a}
do_execsql_test 8.8 {
  SELECT unlikely(t0.rowid <= '0'),
         likely(t0.rowid <= '0'),
         likelihood(t0.rowid <= '0',0.5)
    FROM t0;
} {0 0 0}
do_execsql_test 8.9 {
  SELECT * FROM t0 WHERE unlikely(t0.rowid <= '0');
} {}
do_execsql_test 8.10 {
  SELECT * FROM t0 WHERE likelihood(t0.rowid <= '0', 0.5);
} {}

# 2019-12-31: assertion fault discovered by Yongheng's fuzzer.
# Harmless memIsValid() due to the code generators failure to
# release the registers used by OP_ResultRow.
#
do_execsql_test 9.10 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a, b FLOAT);
  INSERT INTO t1(a) VALUES(''),(NULL),('X'),(NULL);
  SELECT coalesce(max(quote(a)),10) FROM t1 GROUP BY a;
} {NULL '' 'X'}

# 2020-06-14: assert() changed back into testcase()
# ticket 9fb26d37cefaba40
#
reset_db
do_execsql_test 10.1 {
  CREATE TABLE a(b TEXT);  INSERT INTO a VALUES(0),(4),(9);
  CREATE TABLE c(d NUM);
  CREATE VIEW f(g, h) AS SELECT b, 0 FROM a UNION SELECT d, d FROM c;
  SELECT g = g FROM f GROUP BY h;
} {1}

finish_test

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
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=?)
  |  `--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=?)
  |     `--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 {
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
117
118
119
120
121
122
123
124





































































125








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

do_execsql_test 400 {
  CREATE TABLE x(a, b, c);
  CREATE TABLE y(a, b);
  INSERT INTO x VALUES (1, 0, 1);
  INSERT INTO y VALUES (1, 2);
  SELECT x.a FROM x JOIN y ON x.c = y.a WHERE x.b = 1 AND x.b = 1;
} {}

# 2020-01-07: ticket 82ac75ba0093e5dc
# Incorrect join result due to mishandling of affinity in constant
# propagation.
#
reset_db
do_execsql_test 500 {
  PRAGMA automatic_index=OFF;
  CREATE TABLE t0(c0);
  INSERT INTO t0 VALUES('0');
  CREATE VIEW v0(c0) AS SELECT CAST(0 AS INT) FROM t0;
  SELECT 200, * FROM t0, v0 WHERE 0 = t0.c0 AND t0.c0 = v0.c0;
} {}
do_execsql_test 510 {
  SELECT 200, * FROM t0, v0 WHERE t0.c0 = 0 AND t0.c0 = v0.c0;
} {}
do_execsql_test 520 {
  SELECT 200, * FROM t0, v0 WHERE 0 = t0.c0 AND v0.c0 = t0.c0;
} {}
do_execsql_test 530 {
  SELECT 200, * FROM t0, v0 WHERE t0.c0 = 0 AND v0.c0 = t0.c0;
} {}

# 2020-02-13: ticket 1dcb4d44964846ad
# A problem introduced while making optimizations on the fixes above.
#
reset_db
do_execsql_test 600 {
  CREATE TABLE t1(x TEXT);
  CREATE TABLE t2(y TEXT);
  INSERT INTO t1 VALUES('good'),('bad');
  INSERT INTO t2 VALUES('good'),('bad');
  SELECT * FROM t1 JOIN t2 ON x=y
   WHERE x='good' AND y='good';
} {good good}

# 2020-04-24: Another test case for the previous (1dcb4d44964846ad)
# ticket.  The test case comes from 
# https://stackoverflow.com/questions/61399253/sqlite3-different-result-in-console-compared-to-python-script/
# Output verified against postgresql.
#
do_execsql_test 610 {
  CREATE TABLE tableA(
    ID           int,
    RunYearMonth int
  );
  INSERT INTO tableA VALUES(1,202003),(2,202003),(3,202003),(4,202004),
    (5,202004),(6,202004),(7,202004),(8,202004);
  CREATE TABLE tableB (
    ID           int,
    RunYearMonth int
  );
  INSERT INTO tableB VALUES(1,202004),(2,202004),(3,202004),(4,202004),
  (5,202004);
  SELECT *
   FROM (
        SELECT *
        FROM tableA
        WHERE RunYearMonth = 202004
    ) AS A
    INNER JOIN (
        SELECT *
        FROM tableB
        WHERE RunYearMonth = 202004
    ) AS B
    ON A.ID = B.ID
    AND A.RunYearMonth = B.RunYearMonth;
} {4 202004 4 202004 5 202004 5 202004}


finish_test

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
119
120
121

122
123
124
125
126
127
128
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}
  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}
    execsql {DELETE FROM t1 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}
  } {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}
  } {1}
  } {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}
  } {1}
  } {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 {
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
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 RETURNING x, y, '|' LIMIT 5}
    execsql {UPDATE t1 SET y=1 WHERE x=1 LIMIT 5}
  } {1 1 | 1 1 | 1 1 | 1 1 | 1 1 |}
  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/wherelimit2.test.

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
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







-
-
-
-
-
+
+
+






-
-
-
-
-
+
+
+







do_execsql_test 4.1 {
  BEGIN;
    DELETE FROM x1 ORDER BY a LIMIT 2;
    SELECT a FROM x1;
  ROLLBACK;
} {3 4 5 6}

# 2020-06-03: Query planner improved so that a solution is possible.
#
#do_catchsql_test 4.2 {
#  DELETE FROM x1 INDEXED BY x1bc WHERE d=3 LIMIT 1;
#} {1 {no query solution}}
do_catchsql_test 4.2 {
  DELETE FROM x1 INDEXED BY x1bc WHERE d=3 LIMIT 1;
} {1 {no query solution}}

do_execsql_test 4.3 {
  DELETE FROM x1 INDEXED BY x1bc WHERE b=3 LIMIT 1;
  SELECT a FROM x1;
} {1 2 3 4 6}

# 2020-06-03: Query planner improved so that a solution is possible.
#
#do_catchsql_test 4.4 {
#  UPDATE x1 INDEXED BY x1bc SET d=5 WHERE d=3 LIMIT 1;
#} {1 {no query solution}}
do_catchsql_test 4.4 {
  UPDATE x1 INDEXED BY x1bc SET d=5 WHERE d=3 LIMIT 1;
} {1 {no query solution}}

do_execsql_test 4.5 {
  UPDATE x1 INDEXED BY x1bc SET d=5 WHERE b=2 LIMIT 1;
  SELECT a, d FROM x1;
} {1 1 2 2 3 5 4 3 6 1}

#-------------------------------------------------------------------------

Added test/wild001.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2013-07-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 is a test case from content taken "from the wild".  In this
# particular instance, the query was provided with permission by
# Elan Feingold on 2013-06-27.  His message on the SQLite mailing list
# on that date reads:
#
#------------------------------------------------------------------------------
# > Can you send (1) the schema (2) the query that is giving problems, and (3)
# > the content of the sqlite_stat1 table after you have run ANALYZE?   If you
# > can combine all of the above into a script, that would be great!
# >
# > If you send (1..3) above and you give us written permission to include the
# > query in our test suite, that would be off-the-chain terrific.
#
# Please find items 1..3 in this file: http://www.plexapp.com/elan/sqlite_bug.txt
# 
# You have our permission to include the query in your test suite.
# 
# Thanks for an amazing product.
#-----------------------------------------------------------------------------
#
# This test case merely creates the schema and populates SQLITE_STAT1 and
# SQLITE_STAT3 then runs an EXPLAIN QUERY PLAN to ensure that the right plan
# is discovered.  This test case may need to be adjusted for future revisions
# of the query planner manage to select a better query plan.  The query plan
# shown here is known to be very fast with the original data.
#
# This test should work the same with and without SQLITE_ENABLE_STAT3
#
###############################################################################

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !stat3 {
  finish_test
  return
}

do_execsql_test wild001.01 {
  CREATE TABLE "items" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "secid" integer, "parent_id" integer, "metadata_type" integer, "guid" varchar(255), "media_item_count" integer, "title" varchar(255), "title_sort" varchar(255) COLLATE NOCASE, "original_title" varchar(255), "studio" varchar(255), "rating" float, "rating_count" integer, "tagline" varchar(255), "summary" text, "trivia" text, "quotes" text, "content_rating" varchar(255), "content_rating_age" integer, "index" integer, "absolute_index" integer, "duration" integer, "user_thumb_url" varchar(255), "user_art_url" varchar(255), "user_banner_url" varchar(255), "user_music_url" varchar(255), "user_fields" varchar(255), "tags_genre" varchar(255), "tags_collection" varchar(255), "tags_director" varchar(255), "tags_writer" varchar(255), "tags_star" varchar(255), "originally_available_at" datetime, "available_at" datetime, "expires_at" datetime, "refreshed_at" datetime, "year" integer, "added_at" datetime, "created_at" datetime, "updated_at" datetime, "deleted_at" datetime, "tags_country" varchar(255), "extra_data" varchar(255), "hash" varchar(255));
  CREATE INDEX "i_secid" ON "items" ("secid" );
  CREATE INDEX "i_parent_id" ON "items" ("parent_id" );
  CREATE INDEX "i_created_at" ON "items" ("created_at" );
  CREATE INDEX "i_index" ON "items" ("index" );
  CREATE INDEX "i_title" ON "items" ("title" );
  CREATE INDEX "i_title_sort" ON "items" ("title_sort" );
  CREATE INDEX "i_guid" ON "items" ("guid" );
  CREATE INDEX "i_metadata_type" ON "items" ("metadata_type" );
  CREATE INDEX "i_deleted_at" ON "items" ("deleted_at" );
  CREATE INDEX "i_secid_ex1" ON "items" ("secid", "metadata_type", "added_at" );
  CREATE INDEX "i_hash" ON "items" ("hash" );
  CREATE TABLE "settings" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "account_id" integer, "guid" varchar(255), "rating" float, "view_offset" integer, "view_count" integer, "last_viewed_at" datetime, "created_at" datetime, "updated_at" datetime);
  CREATE INDEX "s_account_id" ON "settings" ("account_id" );
  CREATE INDEX "s_guid" ON "settings" ("guid" );
  ANALYZE;
  INSERT INTO sqlite_stat1 VALUES('settings','s_guid','4740 1');
  INSERT INTO sqlite_stat1 VALUES('settings','s_account_id','4740 4740');
  INSERT INTO sqlite_stat1 VALUES('items','i_hash','27316 2');
  INSERT INTO sqlite_stat1 VALUES('items','i_secid_ex1','27316 6829 4553 3');
  INSERT INTO sqlite_stat1 VALUES('items','i_deleted_at','27316 27316');
  INSERT INTO sqlite_stat1 VALUES('items','i_metadata_type','27316 6829');
  INSERT INTO sqlite_stat1 VALUES('items','i_guid','27316 2');
  INSERT INTO sqlite_stat1 VALUES('items','i_title_sort','27316 2');
  INSERT INTO sqlite_stat1 VALUES('items','i_title','27316 2');
  INSERT INTO sqlite_stat1 VALUES('items','i_index','27316 144');
  INSERT INTO sqlite_stat1 VALUES('items','i_created_at','27316 2');
  INSERT INTO sqlite_stat1 VALUES('items','i_parent_id','27316 15');
  INSERT INTO sqlite_stat1 VALUES('items','i_secid','27316 6829');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,150,150,'com.plexapp.agents.thetvdb://153021/2/9?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,198,198,'com.plexapp.agents.thetvdb://194031/1/10?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,526,526,'com.plexapp.agents.thetvdb://71256/12/92?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,923,923,'com.plexapp.agents.thetvdb://71256/15/16?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1008,1008,'com.plexapp.agents.thetvdb://71256/15/93?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1053,1053,'com.plexapp.agents.thetvdb://71256/16/21?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1068,1068,'com.plexapp.agents.thetvdb://71256/16/35?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1235,1235,'com.plexapp.agents.thetvdb://71256/17/44?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1255,1255,'com.plexapp.agents.thetvdb://71256/17/62?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1573,1573,'com.plexapp.agents.thetvdb://71663/20/9?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1580,1580,'com.plexapp.agents.thetvdb://71663/21/16?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2000,2000,'com.plexapp.agents.thetvdb://73141/9/8?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2107,2107,'com.plexapp.agents.thetvdb://73244/6/17?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2256,2256,'com.plexapp.agents.thetvdb://74845/4/7?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2408,2408,'com.plexapp.agents.thetvdb://75978/2/21?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2634,2634,'com.plexapp.agents.thetvdb://79126/1/1?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2962,2962,'com.plexapp.agents.thetvdb://79274/3/94?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3160,3160,'com.plexapp.agents.thetvdb://79274/5/129?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3161,3161,'com.plexapp.agents.thetvdb://79274/5/12?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3688,3688,'com.plexapp.agents.thetvdb://79274/8/62?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3714,3714,'com.plexapp.agents.thetvdb://79274/8/86?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4002,4002,'com.plexapp.agents.thetvdb://79590/13/17?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4215,4215,'com.plexapp.agents.thetvdb://80727/3/6?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4381,4381,'com.plexapp.agents.thetvdb://83462/3/24?lang=en');
  INSERT INTO sqlite_stat3 VALUES('settings','s_account_id',4740,0,0,1);
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,1879,1879,'1113f632ccd52ec8b8d7ca3d6d56da4701e48018');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,2721,2721,'1936154b97bb5567163edaebc2806830ae419ccf');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,3035,3035,'1c122331d4b7bfa0dc2c003ab5fb4f7152b9987a');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,3393,3393,'1f81bdbc9acc3321dc592b1a109ca075731b549a');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,6071,6070,'393cf7713efb4519c7a3d1d5403f0d945d15a16a');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,7462,7461,'4677dd37011f8bd9ae7fbbdd3af6dcd8a5b4ab2d');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,8435,8434,'4ffa339485334e81a5e12e03a63b6508d76401cf');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,8716,8714,'52a093852e6599dd5004857b7ff5b5b82c7cdb25');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,9107,9104,'561183e39f866d97ec728e9ff16ac4ad01466111');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,10942,10939,'66e99b72e29610f49499ae09ee04a376210d1f08');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,12143,12139,'71f0602427e173dc2c551535f73fdb6885fe4302');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,14962,14958,'8ca8e4dfba696019830c19ab8a32c7ece9d8534b');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,15179,15174,'8ebf1a5cf33f8ada1fc5853ac06ac4d7e074f825');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,15375,15370,'908bc211bebdf21c79d2d2b54ebaa442ac1f5cae');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18215,18210,'ab29e4e18ec5a14fef95aa713d69e31c045a22c1');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18615,18610,'ae84c008cc0c338bf4f28d798a88575746452f6d');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18649,18644,'aec7c901353e115aa5307e94018ba7507bec3a45');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,19517,19512,'b75025fbf2e9c504e3c1197ff1b69250402a31f8');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,21251,21245,'c7d32f0e3a8f3a0a3dbd00833833d2ccee62f0fd');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,23616,23610,'dd5ff61479a9bd4100de802515d9dcf72d46f07a');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,24287,24280,'e3db00034301b7555419d4ef6f64769298d5845e');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,24949,24942,'ea336abd197ecd7013854a25a4f4eb9dea7927c6');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,25574,25567,'f018ea5182ec3f32768ca1c3cefbf3ad160ec20b');
  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,26139,26132,'f53709a8d81c12cb0f4f8d58004a25dd063de67c');
  INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',25167,0,0,2);
  INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',736,25167,1,3);
  INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',15,25903,2,4);
  INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',1398,25918,3,5);
  INSERT INTO sqlite_stat3 VALUES('items','i_deleted_at',27316,0,0,NULL);
  INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',2149,0,0,1);
  INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',411,2149,1,2);
  INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',1440,2560,2,3);
  INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',23316,4000,3,4);
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,215,215,'com.plexapp.agents.imdb://tt0065702?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,711,711,'com.plexapp.agents.imdb://tt0198781?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,987,986,'com.plexapp.agents.imdb://tt0454876?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1004,1002,'com.plexapp.agents.imdb://tt0464154?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1056,1053,'com.plexapp.agents.imdb://tt0499549?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1120,1116,'com.plexapp.agents.imdb://tt0903624?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1250,1245,'com.plexapp.agents.imdb://tt1268799?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1270,1264,'com.plexapp.agents.imdb://tt1320261?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1376,1369,'com.plexapp.agents.imdb://tt1772341?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,3035,3027,'com.plexapp.agents.thetvdb://153021/3/14?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,6071,6063,'com.plexapp.agents.thetvdb://71173/1/18?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,6342,6334,'com.plexapp.agents.thetvdb://71256/13/4?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,9107,9099,'com.plexapp.agents.thetvdb://72389/2/19?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,11740,11732,'com.plexapp.agents.thetvdb://73893/2/13?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,12143,12135,'com.plexapp.agents.thetvdb://73976/4/23?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,15179,15171,'com.plexapp.agents.thetvdb://75897/16/12?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,17408,17400,'com.plexapp.agents.thetvdb://76808/2/16?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,17984,17976,'com.plexapp.agents.thetvdb://77068/1/16?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,18215,18207,'com.plexapp.agents.thetvdb://77259/1/1?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,21251,21243,'com.plexapp.agents.thetvdb://78957/8/2?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,24287,24279,'com.plexapp.agents.thetvdb://80337/5/8?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,25513,25505,'com.plexapp.agents.thetvdb://82226/6?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,25548,25540,'com.plexapp.agents.thetvdb://82339/2/10?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,26770,26762,'com.plexapp.agents.thetvdb://86901/1/3?lang=en');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1524,0,0,'');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',2,3034,1391,'Attack of the Giant Squid');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',51,4742,2895,'Brad Sherwood');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',11,4912,2996,'Brian Williams');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',39,5847,3857,'Chip Esten');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,6071,4015,'Chuck Versus the DeLorean');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',12,7625,5436,'Denny Siegel');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',30,8924,6618,'Episode 1');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',29,9015,6629,'Episode 2');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',32,9082,6643,'Episode 3');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',28,9135,6654,'Episode 4');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',26,9183,6665,'Episode 5');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',27,9229,6677,'Episode 6');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',22,9266,6688,'Episode 7');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',20,9298,6699,'Episode 8');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',55,11750,8817,'Greg Proops');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,12143,9120,'Hardware Jungle');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',33,14712,11435,'Kathy Greenwood');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',3,15179,11840,'Last Call');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,18215,14601,'Nature or Nurture?');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',12,18241,14623,'Neil DeGrasse Tyson');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',68,19918,16144,'Pilot');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',7,21251,17298,'Reza Aslan');
  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,24287,20035,'Technoviking');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',1524,0,0,'');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,3035,1429,'Anderson Can''t Dance');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',51,4782,2991,'Brad Sherwood');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',11,4936,3079,'Brian Williams');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',39,5694,3783,'Chip Esten');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,6071,4100,'Clive Warren');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',12,7144,5078,'Denny Siegel');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',30,8249,6097,'Episode 1');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',29,8340,6108,'Episode 2');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',32,8407,6122,'Episode 3');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',28,8460,6133,'Episode 4');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',26,8508,6144,'Episode 5');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',27,8554,6156,'Episode 6');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',22,8591,6167,'Episode 7');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',20,8623,6178,'Episode 8');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,9107,6537,'Fat Albert and the Cosby Kids');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',55,10539,7843,'Greg Proops');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,12143,9276,'Iron Age Remains');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',33,13118,10143,'Kathy Greenwood');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,15179,11972,'Mink');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',68,17411,14035,'Pilot');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',2,18214,14727,'Reflections');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',4,21250,17481,'The Apartment');
  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,24287,20283,'The Simpsons Already Did It');
  INSERT INTO sqlite_stat3 VALUES('items','i_index',4315,95,2,1);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1553,4410,3,2);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1485,5963,4,3);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1414,7448,5,4);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1367,8862,6,5);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1328,10229,7,6);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1161,11557,8,7);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1108,12718,9,8);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1033,13826,10,9);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',1014,14859,11,10);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',929,15873,12,11);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',906,16802,13,12);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',844,17708,14,13);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',690,18552,15,14);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',655,19242,16,15);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',625,19897,17,16);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',579,20522,18,17);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',555,21101,19,18);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',526,21656,20,19);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',501,22182,21,20);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',459,22683,22,21);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',439,23142,23,22);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',315,23581,24,23);
  INSERT INTO sqlite_stat3 VALUES('items','i_index',192,24177,26,25);
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1851,0,0,NULL);
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',373,1857,2,'2011-10-22 14:54:39');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',595,2230,3,'2011-10-22 14:54:41');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',337,2825,4,'2011-10-22 14:54:43');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',361,3378,8,'2011-10-22 14:54:54');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',160,3739,9,'2011-10-22 14:54:56');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',315,4000,11,'2011-10-22 14:54:59');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',321,4334,13,'2011-10-22 14:55:02');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1292,4723,16,'2011-10-22 14:55:06');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',161,6015,17,'2011-10-22 14:55:07');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,9107,2677,'2012-09-04 18:07:50');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',313,9717,3270,'2012-10-18 16:50:21');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',450,10030,3271,'2012-10-18 16:50:22');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',389,10668,3275,'2012-10-18 16:50:26');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',796,11057,3276,'2012-10-18 16:51:06');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',161,12041,3280,'2012-10-19 19:52:37');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',135,13281,4186,'2013-02-19 00:56:10');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1063,13416,4187,'2013-02-19 00:56:11');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',797,14479,4188,'2013-02-19 00:56:13');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',147,15276,4189,'2013-02-19 00:56:15');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',346,15423,4190,'2013-02-19 00:56:16');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,18215,6436,'2013-05-05 14:09:54');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',2,21251,8122,'2013-05-24 15:25:45');
  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,24287,11116,'2013-05-26 14:17:39');
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',2560,0,0,NULL);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',18,3022,31,2350);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',10,6068,285,8150);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',158,6346,315,8949);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',34,9094,562,18831);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',20,12139,794,22838);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',134,14033,886,24739);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',159,14167,887,24740);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,14326,888,24741);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,14487,889,24742);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',124,14648,890,24743);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',157,14772,891,24744);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',126,15043,894,24747);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',40,15169,895,24748);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15243,898,24753);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',138,15404,899,24754);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',160,15542,900,24755);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15702,901,24756);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15863,902,24757);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',124,16024,903,24758);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',155,16148,904,24759);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',26,18208,1043,29704);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',2,21251,1282,32952);
  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',13,24279,1583,36068);
  INSERT INTO sqlite_stat3 VALUES('items','i_secid',25167,0,0,2);
  INSERT INTO sqlite_stat3 VALUES('items','i_secid',736,25167,1,3);
  INSERT INTO sqlite_stat3 VALUES('items','i_secid',15,25903,2,4);
  INSERT INTO sqlite_stat3 VALUES('items','i_secid',1398,25918,3,5);
  ANALYZE sqlite_master;
  
  explain query plan
  select items.title
    from items
         join items as child on child.parent_id=items.id
         join items as grandchild on grandchild.parent_id=child.id
         join settings
                    on settings.guid=grandchild.guid
                   and settings.account_id=1
   where items.metadata_type=2
     and items.secid=2
     and settings.last_viewed_at is not null
   group by items.id
   order by settings.last_viewed_at desc
   limit 10;
} [list \
 0 0 3 {SEARCH TABLE settings USING INDEX s_account_id (account_id=?)} \
 0 1 2 {SEARCH TABLE items AS grandchild USING INDEX i_guid (guid=?)} \
 0 2 1 {SEARCH TABLE items AS child USING INTEGER PRIMARY KEY (rowid=?)} \
 0 3 0 {SEARCH TABLE items USING INTEGER PRIMARY KEY (rowid=?)} \
 0 0 0 {USE TEMP B-TREE FOR GROUP BY} \
 0 0 0 {USE TEMP B-TREE FOR ORDER BY}]


finish_test

Changes to test/win32longpath.test.

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
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







-
-
+




















-
-
-



-
-
-



-
-
-




-
-
-
-
-
-
-







set testprefix win32longpath

do_test 1.0 {
  file_control_vfsname db
} win32

db close
set rawPath [get_pwd]
set path [file nativename $rawPath]
set path [file nativename [get_pwd]]
sqlite3 db [file join $path test.db] -vfs win32-longpath

do_test 1.1 {
  file_control_vfsname db
} win32-longpath

do_test 1.2 {
  db eval {
    BEGIN EXCLUSIVE;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(1);
    INSERT INTO t1 VALUES(2);
    INSERT INTO t1 VALUES(3);
    INSERT INTO t1 VALUES(4);
    SELECT x FROM t1 ORDER BY x;
    COMMIT;
  }
} {1 2 3 4}

set longPath(1) \\\\?\\$path\\[pid]
set uriPath(1a) %5C%5C%3F%5C$path\\[pid]
set uriPath(1b) %5C%5C%3F%5C$rawPath/[pid]

make_win32_dir $longPath(1)

set longPath(2) $longPath(1)\\[string repeat X 255]
set uriPath(2a) $uriPath(1a)\\[string repeat X 255]
set uriPath(2b) $uriPath(1b)/[string repeat X 255]

make_win32_dir $longPath(2)

set longPath(3) $longPath(2)\\[string repeat Y 255]
set uriPath(3a) $uriPath(2a)\\[string repeat Y 255]
set uriPath(3b) $uriPath(2b)/[string repeat Y 255]

make_win32_dir $longPath(3)

set fileName $longPath(3)\\test.db

set uri(1a) file:$uriPath(3a)\\test.db
set uri(1b) file:$uriPath(3b)/test.db
set uri(1c) file:///$uriPath(3a)\\test.db
set uri(1d) file:///$uriPath(3b)/test.db
set uri(1e) file://localhost/$uriPath(3a)\\test.db
set uri(1f) file://localhost/$uriPath(3b)/test.db

do_test 1.3 {
  list [catch {sqlite3 db2 [string range $fileName 4 end]} msg] $msg
} {1 {unable to open database file}}

sqlite3 db3 $fileName -vfs win32-longpath

do_test 1.4 {
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
96
97
98
99
100
101
102












103
104
105
106
107
108
109
110







-
-
-
-
-
-
-
-
-
-
-
-








    COMMIT;
  }
} {5 6 7 8 9 10 11 12}

db3 close
# puts "  Database exists \{[exists_win32_path $fileName]\}"

foreach tn {1a 1b 1c 1d 1e 1f} {
  sqlite3 db3 $uri($tn) -vfs win32-longpath -uri 1 -translatefilename 0

  do_test 1.7.$tn {
    db3 eval {
      SELECT x FROM t1 ORDER BY x;
    }
  } {5 6 7 8 9 10 11 12}

  db3 close
}

do_delete_win32_file $fileName
# puts "  Files remaining \{[find_win32_file $longPath(3)\\*]\}"

do_remove_win32_dir $longPath(3)
do_remove_win32_dir $longPath(2)
do_remove_win32_dir $longPath(1)

finish_test

Changes to test/window1.test.

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
253
254
255
256
257
258
259



260
261
262
263
264
265
266







-
-
-







} {1 {no such column: x}}
do_catchsql_test 7.1.6 {
  SELECT trim(x) OVER (ORDER BY y) FROM t1;
} {1 {trim() may not be used as a window function}}
do_catchsql_test 7.1.7 {
  SELECT max(x) OVER abc FROM t1 WINDOW def AS (ORDER BY y);
} {1 {no such window: abc}}
do_catchsql_test 7.1.8 {
  SELECT row_number(x) OVER () FROM t1
} {1 {wrong number of arguments to function row_number()}}

do_execsql_test 7.2 {
  SELECT 
    lead(y) OVER win, 
    lead(y, 2) OVER win, 
    lead(y, 3, 'default') OVER win
  FROM t1
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192

1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
1163
1164
1165
1166
1167
1168
1169




















1170













































































































































































































































































































































































































1171




1172
































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
  13 M cc NULL JM | 
  3 C cc 1 {} | 
  4 D cc 8.25 {} | 
  12 L cc 'xyZ' L | 
  11 K cc 'xyz' K |
}

# 2019-07-18
# Check-in [7ef7b23cbb1b9ace] (which was itself a fix for ticket
# https://www.sqlite.org/src/info/1be72aab9) introduced a new problem
# if the LHS of a BETWEEN operator is a WINDOW function.  The problem
# was found by (the recently enhanced) dbsqlfuzz.
#
do_execsql_test 30.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES('BB','aa',399);
  SELECT
    count () OVER win1 NOT BETWEEN 'a' AND 'mmm',
    count () OVER win3
  FROM t1
  WINDOW win1 AS (ORDER BY a GROUPS BETWEEN 4 PRECEDING AND 1 FOLLOWING
                  EXCLUDE CURRENT ROW),
         win2 AS (PARTITION BY b ORDER BY a),
         win3 AS (win2 RANGE BETWEEN 5.2 PRECEDING AND true PRECEDING );
} {1 1}

finish_test
#-------------------------------------------------------------------------
reset_db
do_execsql_test 31.1 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d);
  CREATE TABLE t3(e, f);

  INSERT INTO t1 VALUES(1, 1);
  INSERT INTO t2 VALUES(1, 1);
  INSERT INTO t3 VALUES(1, 1);
}

do_execsql_test 31.2 {
  SELECT d IN (SELECT sum(c) OVER (ORDER BY e+c) FROM t3) FROM (
    SELECT * FROM t2
  );
} {1}

do_execsql_test 31.3 {
  SELECT d IN (SELECT sum(c) OVER (PARTITION BY d ORDER BY e+c) FROM t3) FROM (
    SELECT * FROM t2
  );
} {1}

do_catchsql_test 31.3 {
  SELECT d IN (
    SELECT sum(c) OVER ( ROWS BETWEEN d FOLLOWING AND UNBOUNDED FOLLOWING) 
    FROM t3
  )
  FROM (
    SELECT * FROM t2
  );
} {1 {frame starting offset must be a non-negative integer}}

do_catchsql_test 31.3 {
  SELECT d IN (
    SELECT sum(c) OVER ( ROWS BETWEEN CURRENT ROW AND c FOLLOWING) 
    FROM t3
  )
  FROM (
    SELECT * FROM t2
  );
} {1 {frame ending offset must be a non-negative integer}}

# 2019-11-16 chromium issue 1025467
db close
sqlite3 db :memory:
do_catchsql_test 32.10 {
  CREATE VIEW a AS SELECT NULL INTERSECT SELECT NULL ORDER BY s() OVER R;
  CREATE TABLE a0 AS SELECT 0;
  ALTER TABLE a0 RENAME TO S;
} {1 {error in view a: 1st ORDER BY term does not match any column in the result set}}

reset_db
do_execsql_test 33.1 {
  CREATE TABLE t1(aa, bb);
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(5, 6);
  CREATE TABLE t2(x);
  INSERT INTO t2 VALUES(1);
}
do_execsql_test 33.2 {
  SELECT (SELECT DISTINCT sum(aa) OVER() FROM t1 ORDER BY 1), x FROM t2 
  ORDER BY 1;
} {6 1}

reset_db
do_execsql_test 34.1 {
  CREATE TABLE t1(a,b,c);
}
do_execsql_test 34.2 {
  SELECT avg(a) OVER (
      ORDER BY (SELECT sum(b) OVER ()
        FROM t1 ORDER BY (
          SELECT total(d) OVER (ORDER BY c)
          FROM (SELECT 1 AS d) ORDER BY 1
          )
        )
      )
  FROM t1;
}

#-------------------------------------------------------------------------
reset_db
do_catchsql_test 35.0 {
  SELECT * WINDOW f AS () ORDER BY name COLLATE nocase;
} {1 {no tables specified}}

do_catchsql_test 35.1 {
  VALUES(1) INTERSECT SELECT * WINDOW f AS () ORDER BY x COLLATE nocase;
} {1 {no tables specified}}

do_execsql_test 35.2 {
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(1), (2), (3);
  VALUES(1) INTERSECT 
  SELECT sum(x) OVER f FROM t1 WINDOW f AS (ORDER BY x) ORDER BY 1;
} {1}

do_execsql_test 35.3 {
  VALUES(8) EXCEPT 
  SELECT sum(x) OVER f FROM t1 WINDOW f AS (ORDER BY x) ORDER BY 1;
} {8}

do_execsql_test 35.4 {
  VALUES(1) UNION 
  SELECT sum(x) OVER f FROM t1 WINDOW f AS (ORDER BY x) ORDER BY 1;
} {1 3 6}

# 2019-12-07 gramfuzz find
#
do_execsql_test 36.10 {
  VALUES(count(*)OVER());
} {1}
do_execsql_test 36.20 {
  VALUES(count(*)OVER()),(2);
} {1 2}
do_execsql_test 36.30 {
  VALUES(2),(count(*)OVER());
} {2 1}
do_execsql_test 36.40 {
  VALUES(2),(3),(count(*)OVER()),(4),(5);
} {2 3 1 4 5}

# 2019-12-17 crash test case found by Yongheng and Rui
# See check-in 1ca0bd982ab1183b
#
reset_db
do_execsql_test 37.10 {
  CREATE TABLE t0(a UNIQUE, b PRIMARY KEY);
  CREATE VIEW v0(c) AS SELECT max((SELECT count(a)OVER(ORDER BY 1))) FROM t0;
  SELECT c FROM v0 WHERE c BETWEEN 10 AND 20;
} {}
do_execsql_test 37.20 {
  DROP VIEW v0;
  CREATE VIEW v0(c) AS SELECT max((SELECT count(a)OVER(ORDER BY 1234))) FROM t0;
  SELECT c FROM v0 WHERE c BETWEEN -10 AND 20;
} {}

# 2019-12-20 mrigger reported problem with a FILTER clause on an aggregate
# in a join.
#
reset_db
do_catchsql_test 38.10 {
  CREATE TABLE t0(c0);
  CREATE TABLE t1(c0, c1 UNIQUE);
  INSERT INTO t0(c0) VALUES(1);
  INSERT INTO t1(c0,c1) VALUES(2,3);
  SELECT COUNT(*) FROM t0, t1 WHERE (SELECT AVG(0) FILTER(WHERE t1.c1));
} {1 {misuse of aggregate: AVG()}}
do_execsql_test 38.20 {
  SELECT COUNT(*), AVG(1) FILTER(WHERE t1.c1) FROM t0, t1;
} {1 1.0}
do_catchsql_test 38.30 {
  SELECT COUNT(*) FROM t0, t1 WHERE (SELECT AVG(1) FILTER(WHERE t1.c1));
} {1 {misuse of aggregate: AVG()}}

reset_db
do_execsql_test 39.1 {
  CREATE TABLE t0(c0 UNIQUE);
}
do_execsql_test 39.2 {
  SELECT FIRST_VALUE(0) OVER();
} {0}
do_execsql_test 39.3 {
  SELECT * FROM t0 WHERE(c0, 0) IN(SELECT FIRST_VALUE(0) OVER(), 0);
}
do_execsql_test 39.4 {
  SELECT * FROM t0 WHERE (t0.c0, 1) IN(SELECT NTILE(1) OVER(), 0 FROM t0);
}

ifcapable rtree {
  # 2019-12-25 ticket d87336c81c7d0873
  #
  reset_db
  do_catchsql_test 40.1 {
    CREATE VIRTUAL TABLE t0 USING rtree(c0, c1, c2);
    SELECT * FROM t0
     WHERE ((0,0) IN (SELECT COUNT(*),LAG(5)OVER(PARTITION BY 0) FROM t0),0)<=(c1,0);
  } {0 {}}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 41.1 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(NULL,'bb',355);
  INSERT INTO t1 VALUES('CC','aa',158);
  INSERT INTO t1 VALUES('GG','bb',929);
  INSERT INTO t1 VALUES('FF','Rb',574);
}

do_execsql_test 41.2 {
  SELECT min(c) OVER (
    ORDER BY a RANGE BETWEEN 5.2 PRECEDING AND 0.1 PRECEDING
  ) FROM t1
} {355 158 574 929}

do_execsql_test 41.2 {
  SELECT min(c) OVER (
    ORDER BY a RANGE BETWEEN 5.2 PRECEDING AND 0.1 PRECEDING
  ) << 100 FROM t1
} {0 0 0 0}

do_execsql_test 41.3 {
  SELECT
    min(c) OVER win3 << first_value(c) OVER win3,
    min(c) OVER win3 << first_value(c) OVER win3
  FROM t1
  WINDOW win3 AS (
    PARTITION BY 6 ORDER BY a RANGE BETWEEN 5.2 PRECEDING AND 0.1 PRECEDING
  );
} {0 0  0 0  0 0  0 0}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 42.1 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(1, 1, 1);
  INSERT INTO t1 VALUES(2, 2, 2);
}
do_execsql_test 42.2 {
  SELECT * FROM t1 WHERE (0, 0) IN ( SELECT count(*), 0 FROM t1 )
} {}
do_execsql_test 42.3 {
  SELECT * FROM t1 WHERE (2, 0) IN ( SELECT count(*), 0 FROM t1 )
} {1 1 1 2 2 2}

do_execsql_test 42.3 {
  SELECT count(*), max(a) OVER () FROM t1 GROUP BY c; 
} {1 2 1 2}

do_execsql_test 42.4 {
  SELECT sum(a), max(b) OVER () FROM t1;
} {3 1}

do_execsql_test 42.5 {
  CREATE TABLE t2(a, b);
  INSERT INTO t2 VALUES('a', 1);
  INSERT INTO t2 VALUES('a', 2);
  INSERT INTO t2 VALUES('a', 3);
  INSERT INTO t2 VALUES('b', 4);
  INSERT INTO t2 VALUES('b', 5);
  INSERT INTO t2 VALUES('b', 6);
}

do_execsql_test 42.6 {
  SELECT a, sum(b), sum( sum(b) ) OVER (ORDER BY a) FROM t2 GROUP BY a;
} {a 6 6   b 15 21}

do_execsql_test 42.7 {
  SELECT sum(b), sum( sum(b) ) OVER (ORDER BY a) FROM t2;
} {21 21}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 43.1.1 {
  CREATE TABLE t1(x INTEGER PRIMARY KEY);
  INSERT INTO t1 VALUES (10);
}
do_catchsql_test 43.1.2 {
  SELECT count() OVER() AS m FROM t1 ORDER BY (SELECT m);
} {1 {misuse of aliased window function m}}

reset_db
do_execsql_test 43.2.1 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER);
  INSERT INTO t1(a, b) VALUES(1,  10); -- 10
  INSERT INTO t1(a, b) VALUES(2,  15); -- 25
  INSERT INTO t1(a, b) VALUES(3,  -5); -- 20
  INSERT INTO t1(a, b) VALUES(4,  -5); -- 15
  INSERT INTO t1(a, b) VALUES(5,  20); -- 35
  INSERT INTO t1(a, b) VALUES(6, -11); -- 24
}

do_execsql_test 43.2.2 {
  SELECT a, sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY 2
} {
  1 10   4 15   3 20   6 24   2 25   5 35
}

do_execsql_test 43.2.3 {
  SELECT a, sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY abc
} {
  1 10   4 15   3 20   6 24   2 25   5 35
}

do_execsql_test 43.2.4 {
  SELECT a, sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY abc+5
} {
  1 10   4 15   3 20   6 24   2 25   5 35
}

do_catchsql_test 43.2.5 {
  SELECT a, sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY (SELECT abc)
} {1 {misuse of aliased window function abc}}

do_catchsql_test 43.2.6 {
  SELECT a, 1+sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY (SELECT abc)
} {1 {misuse of aliased window function abc}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 44.1 {
  CREATE TABLE t0(c0);
}

do_catchsql_test 44.2.1 {
  SELECT ntile(0) OVER ();
} {1 {argument of ntile must be a positive integer}}
do_catchsql_test 44.2.2 {
  SELECT (0, 0) IN(SELECT MIN(c0), NTILE(0) OVER()) FROM t0;
} {1 {argument of ntile must be a positive integer}}

do_execsql_test 44.3.1 {
  SELECT ntile(1) OVER ();
} {1}
do_execsql_test 44.3.2 {
  SELECT (0, 0) IN(SELECT MIN(c0), NTILE(1) OVER()) FROM t0;
} {0}

do_execsql_test 44.4.2 {
  INSERT INTO t0 VALUES(2), (1), (0);
  SELECT (0, 1) IN(SELECT MIN(c0), NTILE(1) OVER()) FROM t0;
} {1}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 45.1 {
  CREATE TABLE t0(x);
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(1000);
  INSERT INTO t1 VALUES(1000);
  INSERT INTO t0 VALUES(10000);
}
do_execsql_test 45.2 {
  SELECT * FROM (
      SELECT sum (a) OVER() FROM t1 UNION ALL SELECT x FROM t0
  );
} {2000 2000 10000}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 46.1 {
  CREATE TABLE t1 (a);
  CREATE INDEX i1 ON t1(a);

  INSERT INTO t1 VALUES (10);
}

do_execsql_test 46.2 {
  SELECT (SELECT sum(a) OVER(ORDER BY a)) FROM t1
} 10

do_execsql_test 46.3 {
  SELECT * FROM t1 WHERE (SELECT sum(a) OVER(ORDER BY a));
} 10

do_execsql_test 46.4 {
  SELECT * FROM t1 NATURAL JOIN t1
    WHERE a=1
    OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)
} 10

#-------------------------------------------------------------------------
reset_db
do_execsql_test 47.0 {
  CREATE TABLE t1(
      a,
      e,
      f,
      g UNIQUE,
      h UNIQUE
  );
}

do_execsql_test 47.1 {
  CREATE VIEW t2(k) AS
     SELECT e FROM t1 WHERE g = 'abc' OR h BETWEEN 10 AND f;
}

do_catchsql_test 47.2 {
  SELECT 234 FROM t2
    WHERE k=1
    OR (SELECT k FROM t2 WHERE (SELECT sum(a) OVER() FROM t1 GROUP BY 1));
} {1 {misuse of window function sum()}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 48.0 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(1);
  INSERT INTO t1 VALUES(2);
  INSERT INTO t1 VALUES(3);
  SELECT (SELECT max(x)OVER(ORDER BY x) + min(x)OVER(ORDER BY x))
    FROM (SELECT (SELECT sum(a) FROM t1) AS x FROM t1);
} {12 12 12}

do_execsql_test 48.1 {
  SELECT (SELECT max(x)OVER(ORDER BY x) + min(x)OVER(ORDER BY x))
    FROM (SELECT (SELECT sum(a) FROM t1 GROUP BY a) AS x FROM t1);
} {2 2 2}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 49.1 {
  CREATE TABLE t1 (a PRIMARY KEY);
  INSERT INTO t1 VALUES(1);
}

do_execsql_test 49.2 {
  SELECT b AS c FROM (
    SELECT a AS b FROM (
      SELECT a FROM t1 WHERE a=1 OR (SELECT sum(a) OVER ())
    ) 
    WHERE b=1 OR b<10
  ) 
  WHERE c=1 OR c>=10;
} {1}


#-------------------------------------------------------------------------
reset_db
do_execsql_test 50.0 {
  CREATE TABLE t1 (a DOUBLE PRIMARY KEY);
  INSERT INTO t1 VALUES(10.0);
}

do_execsql_test 50.1 {
  SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2))
} {10.0}

do_execsql_test 50.2 {
  SELECT * FROM (
    SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2))
  ) 
  WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 )
} {10.0}

do_execsql_test 50.3 {
  SELECT a FROM (
    SELECT * FROM (
      SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2))
    ) 
    WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 )
  ) 
  WHERE a=1 OR a=10.0
} {10.0}

do_execsql_test 50.4 {
  SELECT a FROM (
    SELECT * FROM (
      SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2))
    ) 
    WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 )
  ) 
  WHERE a=1 OR ((SELECT sum(a) OVER(ORDER BY a%8)) AND 10<=a)
} {10.0}

do_execsql_test 50.5 {
SELECT * FROM (SELECT * FROM t1 NATURAL JOIN t1 WHERE a%1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum((SELECT * FROM (SELECT * FROM (SELECT * FROM t1 NATURAL JOIN t1 WHERE a%1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum((SELECT * FROM t1 NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)))OVER(ORDER BY a% 1 )) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND 10<=a)))OVER(ORDER BY a%5)) AND a<=10);
} {10.0}

# 2020-04-03 ticket af4556bb5c285c08
#
reset_db
do_catchsql_test 51.1 {
  CREATE TABLE a(b, c);
  SELECT c FROM a GROUP BY c
    HAVING(SELECT(sum(b) OVER(ORDER BY b),
                  sum(b) OVER(PARTITION BY min(DISTINCT c), c ORDER BY b)));
} {1 {row value misused}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 52.1 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES('AA','bb',356);
  INSERT INTO t1 VALUES('CC','aa',158);
  INSERT INTO t1 VALUES('BB','aa',399);
  INSERT INTO t1 VALUES('FF','bb',938);
}

do_execsql_test 52.2 {
  SELECT
    count() OVER win1,
    sum(c) OVER win2, 
    first_value(c) OVER win2,
    count(a) OVER (ORDER BY b)
      FROM t1
      WINDOW
      win1 AS (ORDER BY a),
    win2 AS (PARTITION BY 6 ORDER BY a
        RANGE BETWEEN 5 PRECEDING AND 0 PRECEDING );
} {
  1 356 356 4 
  2 399 399 2 
  3 158 158 2 
  4 938 938 4
}

do_execsql_test 52.3 {
SELECT
  count() OVER (),
  sum(c) OVER win2, 
  first_value(c) OVER win2,
  count(a) OVER (ORDER BY b)
FROM t1
WINDOW
  win1 AS (ORDER BY a),
  win2 AS (PARTITION BY 6 COLLATE binary ORDER BY a
           RANGE BETWEEN 5 PRECEDING AND 0 PRECEDING );
} {
  4 356 356 4 
  4 399 399 2 
  4 158 158 2 
  4 938 938 4
}

do_execsql_test 52.4 {
  SELECT
    count() OVER win1,
    sum(c) OVER win2, 
    first_value(c) OVER win2,
    count(a) OVER (ORDER BY b)
  FROM t1
  WINDOW
    win1 AS (ORDER BY a),
    win2 AS (PARTITION BY 6 COLLATE binary ORDER BY a
             RANGE BETWEEN 5 PRECEDING AND 0 PRECEDING );
} {
  1 356 356 4 
  2 399 399 2 
  3 158 158 2 
  4 938 938 4
}

# 2020-05-23
# ticket 7a5279a25c57adf1
#
reset_db
do_execsql_test 53.0 {
  CREATE TABLE a(c UNIQUE);
  INSERT INTO a VALUES(4),(0),(9),(-9);
  SELECT a.c
    FROM a
    JOIN a AS b ON a.c=4
    JOIN a AS e ON a.c=e.c
   WHERE a.c=(SELECT (SELECT coalesce(lead(2) OVER(),0) + sum(d.c))
                FROM a AS d
               WHERE a.c);
} {4 4 4 4}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 54.1 {
  CREATE TABLE t1(a VARCHAR(20), b FLOAT);
  INSERT INTO t1 VALUES('1',10.0);
}

do_catchsql_test 54.2 {
  SELECT * FROM ( 
    SELECT sum(b) OVER() AS c FROM t1 
      UNION
    SELECT b AS c FROM t1
  ) WHERE c>10;
} {0 {}}

do_execsql_test 54.3 {
  INSERT INTO t1 VALUES('2',5.0);
  INSERT INTO t1 VALUES('3',15.0);
}

do_catchsql_test 54.4 {
  SELECT * FROM ( 
    SELECT sum(b) OVER() AS c FROM t1 
      UNION
    SELECT b AS c FROM t1
  ) WHERE c>10;
} {0 {15.0 30.0}}

# 2020-06-05 ticket c8d3b9f0a750a529
reset_db
do_execsql_test 55.1 {
   CREATE TABLE a(b);
   SELECT
      (SELECT b FROM a
        GROUP BY b
        HAVING (SELECT COUNT()OVER() + lead(b)OVER(ORDER BY SUM(DISTINCT b) + b))
      ) 
    FROM a
  UNION
   SELECT 99
    ORDER BY 1;
} {99}

#------------------------------------------------------------------------
reset_db
do_execsql_test 56.1 {
  CREATE TABLE t1(a, b INTEGER); 
  CREATE TABLE t2(c, d); 
}
do_catchsql_test 56.2 {
  SELECT avg(b) FROM t1 
    UNION ALL 
  SELECT min(c) OVER () FROM t2 
  ORDER BY nosuchcolumn;
} {1 {1st ORDER BY term does not match any column in the result set}}

reset_db
do_execsql_test 57.1 {
  CREATE TABLE t4(a, b, c, d, e);
}

do_catchsql_test 57.2  {
  SELECT b FROM t4
  UNION
  SELECT a FROM t4
  ORDER BY (
    SELECT sum(x) OVER() FROM (
      SELECT c AS x FROM t4
      UNION
      SELECT d FROM t4
      ORDER BY (SELECT e FROM t4)
    )
  );
} {1 {1st ORDER BY term does not match any column in the result set}}

# 2020-06-06 various dbsqlfuzz finds and
# ticket 0899cf62f597d7e7
#
reset_db
do_execsql_test 57.1 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(NULL,NULL,NULL);
  SELECT 
    sum(a),
    min(b) OVER (),
    count(c) OVER (ORDER BY b)
  FROM t1;
} {{} {} 0}
do_execsql_test 57.2 {
  CREATE TABLE v0 ( v1 INTEGER PRIMARY KEY ) ; 
  INSERT INTO v0 VALUES ( 10 ) ; 
  SELECT DISTINCT v1, lead(v1) OVER() FROM v0 GROUP BY v1 ORDER BY 2;
} {10 {}}
do_catchsql_test 57.3 {
  DROP TABLE t1;
  CREATE TABLE t1(a);
  INSERT INTO t1(a) VALUES(22);
  CREATE TABLE t3(y);
  INSERT INTO t3(y) VALUES(5),(11),(-9);
  SELECT (
    SELECT max(y) OVER( ORDER BY (SELECT x FROM (SELECT sum(y) AS x FROM t1)))
  )
  FROM t3;
} {1 {misuse of aggregate: sum()}}

# 2020-06-06 ticket 1f6f353b684fc708
reset_db
do_execsql_test 58.1 {
  CREATE TABLE a(a, b, c);
  INSERT INTO a VALUES(1, 2, 3);
  INSERT INTO a VALUES(4, 5, 6);
  SELECT sum(345+b)      OVER (ORDER BY b),
         sum(avg(678)) OVER (ORDER BY c) FROM a;
} {347 678.0}

# 2020-06-06 ticket e5504e987e419fb0
do_catchsql_test 59.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x INTEGER PRIMARY KEY);
  INSERT INTO t1 VALUES (123);
  SELECT
     ntile( (SELECT sum(x)) ) OVER(ORDER BY x),
     min(x) OVER(ORDER BY x)
    FROM t1; 
} {1 {misuse of aggregate: sum()}}

# 2020-06-07 ticket f7d890858f361402
do_execsql_test 60.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1 (x INTEGER PRIMARY KEY);
  INSERT INTO t1 VALUES (99);
  SELECT EXISTS(SELECT count(*) OVER() FROM t1 ORDER BY sum(x) OVER());
} {1}

# 2020-06-07 test case generated by dbsqlfuzz showing how an AggInfo
# object might be referenced after the sqlite3Select() call that created
# it returns.  This proves the need to persist all AggInfo objects until
# the Parse object is destroyed.
#
reset_db
do_execsql_test 61.1 {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(5),(NULL),('seventeen');
SELECT (SELECT max(x)OVER(ORDER BY x) % min(x)OVER(ORDER BY CASE x WHEN 889 THEN x WHEN x THEN x END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST((SELECT (SELECT max(x)OVER(ORDER BY x) / min(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN -true THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x) & sum ( a )OVER(ORDER BY CASE x WHEN -8 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a AS )) FROM t1) AS x FROM t1)) AS t1 )) FROM t1) AS x FROM t1)) AS x )) FROM t1) AS x FROM t1)) AS real)) FROM t1) AS x FROM t1);
} {{} {} {}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 62.1 {
  CREATE TABLE t1(a VARCHAR(20), b FLOAT);
  INSERT INTO t1 VALUES('1',10.0);
}

do_execsql_test 62.2 {
  SELECT * FROM ( 
      SELECT sum(b) OVER() AS c FROM t1 
      UNION
      SELECT b AS c FROM t1
      ) WHERE c>10;
}

do_execsql_test 62.3 {
  INSERT INTO t1 VALUES('2',5.0);
  INSERT INTO t1 VALUES('3',15.0);
}

do_execsql_test 62.4 {
  SELECT * FROM ( 
      SELECT sum(b) OVER() AS c FROM t1 
      UNION
      SELECT b AS c FROM t1
      ) WHERE c>10;
} {15.0 30.0}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 63.1 {
  CREATE TABLE t1(b, x);
  CREATE TABLE t2(c, d);
  CREATE TABLE t3(e, f);
}

do_execsql_test 63.2 {
  SELECT max(b) OVER(
      ORDER BY SUM(
        (SELECT c FROM t2 UNION SELECT x ORDER BY c)
      )
  ) FROM t1;
} {{}}

do_execsql_test 63.3 {
  SELECT sum(b) over(
      ORDER BY (
        SELECT max(b) OVER(
          ORDER BY sum(
            (SELECT x AS c UNION SELECT 1234 ORDER BY c)
          )
        ) AS e
        ORDER BY e
      )
    )
  FROM t1;
} {{}}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 64.1 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  INSERT INTO t1 VALUES(1, 'abcd');
  INSERT INTO t1 VALUES(2, 'BCDE');
  INSERT INTO t1 VALUES(3, 'cdef');
  INSERT INTO t1 VALUES(4, 'DEFG');
}

do_execsql_test 64.2 {
  SELECT rowid, max(b COLLATE nocase)||'' 
  FROM t1 
  GROUP BY rowid
  ORDER BY max(b COLLATE nocase)||'';
} {1 abcd 2 BCDE 3 cdef 4 DEFG}

do_execsql_test 64.3 {
  SELECT count() OVER (), rowid, max(b COLLATE nocase)||'' 
  FROM t1 
  GROUP BY rowid
  ORDER BY max(b COLLATE nocase)||'';
} {4 1 abcd   4 2 BCDE   4 3 cdef   4 4 DEFG}

do_execsql_test 64.4 {
  SELECT count() OVER (), rowid, max(b COLLATE nocase)
  FROM t1 
  GROUP BY rowid
  ORDER BY max(b COLLATE nocase);
} {4 1 abcd   4 2 BCDE   4 3 cdef   4 4 DEFG}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 65.1 {
  CREATE TABLE t1(c1);
  INSERT INTO t1 VALUES('abcd');
}
do_execsql_test 65.2 {
  SELECT max(c1 COLLATE nocase) IN (SELECT 'aBCd') FROM t1;
} {1}

do_execsql_test 65.3 {
  SELECT 
     count() OVER (), 
     group_concat(c1 COLLATE nocase) IN (SELECT 'aBCd') FROM t1;
} {1 1}

do_execsql_test 65.4 {
  SELECT COUNT() OVER () LIKE lead(102030) OVER(
      ORDER BY sum('abcdef' COLLATE nocase) IN (SELECT 54321) 
  )
  FROM t1;
} {{}}

finish_test

Changes to test/window2.tcl.

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
413
414
415
416
417
418
419






420

































































421
422
423
424







-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




execsql_test 4.8.4 {
  SELECT b, sum(b) OVER (
    ORDER BY a
    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  ) FROM t2 ORDER BY 1, 2;
}

execsql_float_test 4.9 {
  SELECT 
    rank() OVER win AS rank,
    cume_dist() OVER win AS cume_dist FROM t1
  WINDOW win AS (ORDER BY 1);
}


execsql_test 4.10 {
  SELECT count(*) OVER (ORDER BY b) FROM t1
}

execsql_test 4.11 {
  SELECT count(distinct a) FILTER (WHERE b='odd') FROM t1
}

==========

execsql_test 5.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x INTEGER, y INTEGER);
  INSERT INTO t1 VALUES(10, 1);
  INSERT INTO t1 VALUES(20, 2);
  INSERT INTO t1 VALUES(3, 3);
  INSERT INTO t1 VALUES(2, 4);
  INSERT INTO t1 VALUES(1, 5);
}

execsql_float_test 5.1 {
  SELECT avg(x) OVER (ORDER BY y) AS z FROM t1 ORDER BY z;
}

==========

execsql_test 6.0 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 INTEGER UNIQUE);
  INSERT INTO t0 VALUES(0);
}
execsql_test 6.1 {
  SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0;
}
execsql_test 6.2 {
  SELECT * FROM t0 WHERE 
      (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0);
} 

==========

execsql_test 7.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER, b INTEGER, c INTEGER);
  INSERT INTO t1 VALUES(1, 1, 1);
  INSERT INTO t1 VALUES(1, 2, 2);
  INSERT INTO t1 VALUES(3, 3, 3);
  INSERT INTO t1 VALUES(3, 4, 4);
}

execsql_test 7.1 {
  SELECT c, sum(c) OVER win1 FROM t1 
  WINDOW win1 AS (ORDER BY b)
}

execsql_test 7.2 {
  SELECT c, sum(c) OVER win1 FROM t1 
  WINDOW win1 AS (PARTITION BY 1 ORDER BY b)
}

execsql_test 7.3 {
  SELECT c, sum(c) OVER win1 FROM t1 
  WINDOW win1 AS (ORDER BY 1)
}

finish_test


Changes to test/window2.test.

322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522

523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590

591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718

719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779

780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848

849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
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







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


} {}

do_execsql_test 4.1 {
  SELECT a, sum(b) OVER (
    PARTITION BY (b%10)
    ORDER BY b
  ) FROM t2 ORDER BY a;
} {1 0   2 754   3 251   4 754   5 101   6 1247   7 132   8 266   9 6   10 950
} {1 0   2 754   3 251   4 754   5 101   6 1247   7 132   8 266   9 6   10 950   11 667   12 1052   13 535   14 128   15 428   16 250   17 336   18 1122   19 368   20 6   21 1247   22 1000   23 92   24 368   25 584   26 320   27 1000   28 24   29 478   30 133   31 1049   32 1090   33 632   34 101   35 54   36 54   37 1049   38 450   39 145   40 354   41 21   42 764   43 754   44 424   45 1122   46 930   47 42   48 930   49 352   50 535   51 42   52 118   53 536   54 6   55 1122   56 86   57 770   58 255   59 50   60 52   61 950   62 75   63 354   64 2   65 536   66 160   67 352   68 536   69 54   70 675   71 276   72 950   73 868   74 678   75 667   76 4   77 1184   78 160   79 120   80 584   81 266   82 133   83 405   84 468   85 6   86 806   87 166   88 500   89 1090   90 552   91 251   92 27   93 424   94 687   95 1215   96 450   97 32   98 360   99 1052   100 868   101 2   102 66   103 754   104 450   105 145   106 5   107 687   108 24   109 302   110 806   111 251   112 42   113 24   114 30   115 128   116 128   117 50   118 1215   119 86   120 687   121 683   122 672   123 178   124 24   125 24   126 299   127 178   128 770   129 535   130 1052   131 270   132 255   133 675   134 632   135 266   136 6   137 21   138 930   139 411   140 754   141 133   142 340   143 535   144 46   145 250   146 132   147 132   148 354   149 500   150 770   151 276   152 360   153 354   154 27   155 552   156 552   157 602   158 266   159 1049   160 675   161 384   162 667   163 27   164 101   165 166   166 32   167 42   168 18   169 336   170 1122   171 276   172 1122   173 266   174 50   175 178   176 276   177 1247   178 6   179 1215   180 604   181 360   182 212   183 120   184 210   185 1090   186 10   187 1090   188 266   189 66   190 250   191 266   192 360   193 120   194 128   195 178   196 770   197 92   198 634   199 38   200 21}
  11 667   12 1052   13 535   14 128   15 428   16 250   17 336   18 1122
  19 368   20 6   21 1247   22 1000   23 92   24 368   25 584   26 320
  27 1000   28 24   29 478   30 133   31 1049   32 1090   33 632   34 101
  35 54   36 54   37 1049   38 450   39 145   40 354   41 21   42 764
  43 754   44 424   45 1122   46 930   47 42   48 930   49 352   50 535
  51 42   52 118   53 536   54 6   55 1122   56 86   57 770   58 255   59 50
  60 52   61 950   62 75   63 354   64 2   65 536   66 160   67 352   68 536
  69 54   70 675   71 276   72 950   73 868   74 678   75 667   76 4
  77 1184   78 160   79 120   80 584   81 266   82 133   83 405   84 468
  85 6   86 806   87 166   88 500   89 1090   90 552   91 251   92 27
  93 424   94 687   95 1215   96 450   97 32   98 360   99 1052   100 868
  101 2   102 66   103 754   104 450   105 145   106 5   107 687   108 24
  109 302   110 806   111 251   112 42   113 24   114 30   115 128   116 128
  117 50   118 1215   119 86   120 687   121 683   122 672   123 178   124 24
  125 24   126 299   127 178   128 770   129 535   130 1052   131 270
  132 255   133 675   134 632   135 266   136 6   137 21   138 930   139 411
  140 754   141 133   142 340   143 535   144 46   145 250   146 132
  147 132   148 354   149 500   150 770   151 276   152 360   153 354
  154 27   155 552   156 552   157 602   158 266   159 1049   160 675
  161 384   162 667   163 27   164 101   165 166   166 32   167 42   168 18
  169 336   170 1122   171 276   172 1122   173 266   174 50   175 178
  176 276   177 1247   178 6   179 1215   180 604   181 360   182 212
  183 120   184 210   185 1090   186 10   187 1090   188 266   189 66
  190 250   191 266   192 360   193 120   194 128   195 178   196 770
  197 92   198 634   199 38   200 21}

do_execsql_test 4.2 {
  SELECT a, sum(b) OVER (
    PARTITION BY (b%10)
    ORDER BY b
    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) FROM t2 ORDER BY a;
} {1 0   2 754   3 251   4 754   5 101   6 1247   7 132   8 266   9 6   10 950
} {1 0   2 754   3 251   4 754   5 101   6 1247   7 132   8 266   9 6   10 950   11 667   12 1052   13 535   14 128   15 428   16 250   17 336   18 1122   19 368   20 6   21 1247   22 1000   23 92   24 368   25 584   26 320   27 1000   28 24   29 478   30 133   31 1049   32 1090   33 632   34 101   35 54   36 54   37 1049   38 450   39 145   40 354   41 21   42 764   43 754   44 424   45 1122   46 930   47 42   48 930   49 352   50 535   51 42   52 118   53 536   54 6   55 1122   56 86   57 770   58 255   59 50   60 52   61 950   62 75   63 354   64 2   65 536   66 160   67 352   68 536   69 54   70 675   71 276   72 950   73 868   74 678   75 667   76 4   77 1184   78 160   79 120   80 584   81 266   82 133   83 405   84 468   85 6   86 806   87 166   88 500   89 1090   90 552   91 251   92 27   93 424   94 687   95 1215   96 450   97 32   98 360   99 1052   100 868   101 2   102 66   103 754   104 450   105 145   106 5   107 687   108 24   109 302   110 806   111 251   112 42   113 24   114 30   115 128   116 128   117 50   118 1215   119 86   120 687   121 683   122 672   123 178   124 24   125 24   126 299   127 178   128 770   129 535   130 1052   131 270   132 255   133 675   134 632   135 266   136 6   137 21   138 930   139 411   140 754   141 133   142 340   143 535   144 46   145 250   146 132   147 132   148 354   149 500   150 770   151 276   152 360   153 354   154 27   155 552   156 552   157 602   158 266   159 1049   160 675   161 384   162 667   163 27   164 101   165 166   166 32   167 42   168 18   169 336   170 1122   171 276   172 1122   173 266   174 50   175 178   176 276   177 1247   178 6   179 1215   180 604   181 360   182 212   183 120   184 210   185 1090   186 10   187 1090   188 266   189 66   190 250   191 266   192 360   193 120   194 128   195 178   196 770   197 92   198 634   199 38   200 21}
  11 667   12 1052   13 535   14 128   15 428   16 250   17 336   18 1122
  19 368   20 6   21 1247   22 1000   23 92   24 368   25 584   26 320
  27 1000   28 24   29 478   30 133   31 1049   32 1090   33 632   34 101
  35 54   36 54   37 1049   38 450   39 145   40 354   41 21   42 764
  43 754   44 424   45 1122   46 930   47 42   48 930   49 352   50 535
  51 42   52 118   53 536   54 6   55 1122   56 86   57 770   58 255   59 50
  60 52   61 950   62 75   63 354   64 2   65 536   66 160   67 352   68 536
  69 54   70 675   71 276   72 950   73 868   74 678   75 667   76 4
  77 1184   78 160   79 120   80 584   81 266   82 133   83 405   84 468
  85 6   86 806   87 166   88 500   89 1090   90 552   91 251   92 27
  93 424   94 687   95 1215   96 450   97 32   98 360   99 1052   100 868
  101 2   102 66   103 754   104 450   105 145   106 5   107 687   108 24
  109 302   110 806   111 251   112 42   113 24   114 30   115 128   116 128
  117 50   118 1215   119 86   120 687   121 683   122 672   123 178   124 24
  125 24   126 299   127 178   128 770   129 535   130 1052   131 270
  132 255   133 675   134 632   135 266   136 6   137 21   138 930   139 411
  140 754   141 133   142 340   143 535   144 46   145 250   146 132
  147 132   148 354   149 500   150 770   151 276   152 360   153 354
  154 27   155 552   156 552   157 602   158 266   159 1049   160 675
  161 384   162 667   163 27   164 101   165 166   166 32   167 42   168 18
  169 336   170 1122   171 276   172 1122   173 266   174 50   175 178
  176 276   177 1247   178 6   179 1215   180 604   181 360   182 212
  183 120   184 210   185 1090   186 10   187 1090   188 266   189 66
  190 250   191 266   192 360   193 120   194 128   195 178   196 770
  197 92   198 634   199 38   200 21}

do_execsql_test 4.3 {
  SELECT b, sum(b) OVER (
    ORDER BY b
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) FROM t2 ORDER BY b;
} {0 0   1 1   1 2   2 4   2 6   2 8   3 11   3 14   4 18   5 23   6 29   7 36
} {0 0   1 1   1 2   2 4   2 6   2 8   3 11   3 14   4 18   5 23   6 29   7 36   7 43   7 50   8 58   8 66   8 74   9 83   9 92   9 101   10 111   11 122   11 133   12 145   12 157   12 169   13 182   13 195   14 209   15 224   15 239   15 254   16 270   16 286   16 302   17 319   19 338   20 358   21 379   21 400   22 422   22 444   23 467   23 490   23 513   24 537   25 562   26 588   26 614   26 640   27 667   27 694   28 722   29 751   29 780   29 809   30 839   30 869   30 899   31 930   31 961   32 993   33 1026   33 1059   33 1092   33 1125   33 1158   34 1192   34 1226   34 1260   34 1294   35 1329   35 1364   36 1400   36 1436   36 1472   36 1508   37 1545   37 1582   38 1620   38 1658   39 1697   39 1736   39 1775   40 1815   41 1856   41 1897   41 1938   42 1980   43 2023   43 2066   44 2110   44 2154   46 2200   46 2246   47 2293   47 2340   47 2387   47 2434   49 2483   50 2533   51 2584   52 2636   53 2689   54 2743   55 2798   55 2853   56 2909   56 2965   56 3021   57 3078   58 3136   58 3194   58 3252   58 3310   59 3369   59 3428   59 3487   59 3546   60 3606   61 3667   61 3728   62 3790   62 3852   63 3915   64 3979   65 4044   65 4109   65 4174   66 4240   67 4307   68 4375   69 4444   70 4514   72 4586   72 4658   72 4730   73 4803   73 4876   73 4949   74 5023   74 5097   74 5171   74 5245   74 5319   75 5394   75 5469   75 5544   76 5620   77 5697   77 5774   78 5852   78 5930   79 6009   80 6089   80 6169   81 6250   81 6331   81 6412   82 6494   83 6577   84 6661   84 6745   84 6829   84 6913   85 6998   85 7083   85 7168   86 7254   87 7341   87 7428   88 7516   89 7605   89 7694   89 7783   90 7873   90 7963   90 8053   91 8144   91 8235   91 8326   91 8417   91 8508   93 8601   93 8694   93 8787   94 8881   95 8976   95 9071   95 9166   96 9262   96 9358   96 9454   97 9551   97 9648   98 9746   98 9844   99 9943   99 10042   99 10141}
  7 43   7 50   8 58   8 66   8 74   9 83   9 92   9 101   10 111   11 122
  11 133   12 145   12 157   12 169   13 182   13 195   14 209   15 224
  15 239   15 254   16 270   16 286   16 302   17 319   19 338   20 358
  21 379   21 400   22 422   22 444   23 467   23 490   23 513   24 537
  25 562   26 588   26 614   26 640   27 667   27 694   28 722   29 751
  29 780   29 809   30 839   30 869   30 899   31 930   31 961   32 993
  33 1026   33 1059   33 1092   33 1125   33 1158   34 1192   34 1226
  34 1260   34 1294   35 1329   35 1364   36 1400   36 1436   36 1472
  36 1508   37 1545   37 1582   38 1620   38 1658   39 1697   39 1736
  39 1775   40 1815   41 1856   41 1897   41 1938   42 1980   43 2023
  43 2066   44 2110   44 2154   46 2200   46 2246   47 2293   47 2340
  47 2387   47 2434   49 2483   50 2533   51 2584   52 2636   53 2689
  54 2743   55 2798   55 2853   56 2909   56 2965   56 3021   57 3078
  58 3136   58 3194   58 3252   58 3310   59 3369   59 3428   59 3487
  59 3546   60 3606   61 3667   61 3728   62 3790   62 3852   63 3915
  64 3979   65 4044   65 4109   65 4174   66 4240   67 4307   68 4375
  69 4444   70 4514   72 4586   72 4658   72 4730   73 4803   73 4876
  73 4949   74 5023   74 5097   74 5171   74 5245   74 5319   75 5394
  75 5469   75 5544   76 5620   77 5697   77 5774   78 5852   78 5930
  79 6009   80 6089   80 6169   81 6250   81 6331   81 6412   82 6494
  83 6577   84 6661   84 6745   84 6829   84 6913   85 6998   85 7083
  85 7168   86 7254   87 7341   87 7428   88 7516   89 7605   89 7694
  89 7783   90 7873   90 7963   90 8053   91 8144   91 8235   91 8326
  91 8417   91 8508   93 8601   93 8694   93 8787   94 8881   95 8976
  95 9071   95 9166   96 9262   96 9358   96 9454   97 9551   97 9648
  98 9746   98 9844   99 9943   99 10042   99 10141}

do_execsql_test 4.4 {
  SELECT b, sum(b) OVER (
    ORDER BY b
    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  ) FROM t2 ORDER BY b;
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
  3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141
  8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141
  11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141
  14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141
  17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141
  23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141
  26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141
  30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141
  33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141
  34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141
  37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141
  40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141
  44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141
  47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141
  55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141
  58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141
  60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141
  65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141
  70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141
  74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141
  75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141
  80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141
  84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141
  86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141
  90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141
  91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141
  95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141
  98 10141   99 10141   99 10141   99 10141}

do_execsql_test 4.5 {
  SELECT b, sum(b) OVER (
    ORDER BY b
    RANGE BETWEEN CURRENT ROW AND CURRENT ROW
  ) FROM t2 ORDER BY b;
} {0 0   1 2   1 2   2 6   2 6   2 6   3 6   3 6   4 4   5 5   6 6   7 21
} {0 0   1 2   1 2   2 6   2 6   2 6   3 6   3 6   4 4   5 5   6 6   7 21   7 21   7 21   8 24   8 24   8 24   9 27   9 27   9 27   10 10   11 22   11 22   12 36   12 36   12 36   13 26   13 26   14 14   15 45   15 45   15 45   16 48   16 48   16 48   17 17   19 19   20 20   21 42   21 42   22 44   22 44   23 69   23 69   23 69   24 24   25 25   26 78   26 78   26 78   27 54   27 54   28 28   29 87   29 87   29 87   30 90   30 90   30 90   31 62   31 62   32 32   33 165   33 165   33 165   33 165   33 165   34 136   34 136   34 136   34 136   35 70   35 70   36 144   36 144   36 144   36 144   37 74   37 74   38 76   38 76   39 117   39 117   39 117   40 40   41 123   41 123   41 123   42 42   43 86   43 86   44 88   44 88   46 92   46 92   47 188   47 188   47 188   47 188   49 49   50 50   51 51   52 52   53 53   54 54   55 110   55 110   56 168   56 168   56 168   57 57   58 232   58 232   58 232   58 232   59 236   59 236   59 236   59 236   60 60   61 122   61 122   62 124   62 124   63 63   64 64   65 195   65 195   65 195   66 66   67 67   68 68   69 69   70 70   72 216   72 216   72 216   73 219   73 219   73 219   74 370   74 370   74 370   74 370   74 370   75 225   75 225   75 225   76 76   77 154   77 154   78 156   78 156   79 79   80 160   80 160   81 243   81 243   81 243   82 82   83 83   84 336   84 336   84 336   84 336   85 255   85 255   85 255   86 86   87 174   87 174   88 88   89 267   89 267   89 267   90 270   90 270   90 270   91 455   91 455   91 455   91 455   91 455   93 279   93 279   93 279   94 94   95 285   95 285   95 285   96 288   96 288   96 288   97 194   97 194   98 196   98 196   99 297   99 297   99 297}
  7 21   7 21   8 24   8 24   8 24   9 27   9 27   9 27   10 10   11 22
  11 22   12 36   12 36   12 36   13 26   13 26   14 14   15 45   15 45
  15 45   16 48   16 48   16 48   17 17   19 19   20 20   21 42   21 42
  22 44   22 44   23 69   23 69   23 69   24 24   25 25   26 78   26 78
  26 78   27 54   27 54   28 28   29 87   29 87   29 87   30 90   30 90
  30 90   31 62   31 62   32 32   33 165   33 165   33 165   33 165   33 165
  34 136   34 136   34 136   34 136   35 70   35 70   36 144   36 144
  36 144   36 144   37 74   37 74   38 76   38 76   39 117   39 117   39 117
  40 40   41 123   41 123   41 123   42 42   43 86   43 86   44 88   44 88
  46 92   46 92   47 188   47 188   47 188   47 188   49 49   50 50   51 51
  52 52   53 53   54 54   55 110   55 110   56 168   56 168   56 168   57 57
  58 232   58 232   58 232   58 232   59 236   59 236   59 236   59 236
  60 60   61 122   61 122   62 124   62 124   63 63   64 64   65 195   65 195
  65 195   66 66   67 67   68 68   69 69   70 70   72 216   72 216   72 216
  73 219   73 219   73 219   74 370   74 370   74 370   74 370   74 370
  75 225   75 225   75 225   76 76   77 154   77 154   78 156   78 156
  79 79   80 160   80 160   81 243   81 243   81 243   82 82   83 83   84 336
  84 336   84 336   84 336   85 255   85 255   85 255   86 86   87 174
  87 174   88 88   89 267   89 267   89 267   90 270   90 270   90 270
  91 455   91 455   91 455   91 455   91 455   93 279   93 279   93 279
  94 94   95 285   95 285   95 285   96 288   96 288   96 288   97 194
  97 194   98 196   98 196   99 297   99 297   99 297}

do_execsql_test 4.6.1 {
  SELECT b, sum(b) OVER (
    RANGE BETWEEN CURRENT ROW AND CURRENT ROW
  ) FROM t2 ORDER BY b;
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
  3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141
  8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141
  11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141
  14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141
  17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141
  23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141
  26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141
  30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141
  33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141
  34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141
  37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141
  40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141
  44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141
  47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141
  55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141
  58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141
  60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141
  65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141
  70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141
  74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141
  75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141
  80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141
  84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141
  86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141
  90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141
  91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141
  95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141
  98 10141   99 10141   99 10141   99 10141}

do_execsql_test 4.6.2 {
  SELECT b, sum(b) OVER () FROM t2 ORDER BY b;
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
  3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141
  8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141
  11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141
  14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141
  17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141
  23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141
  26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141
  30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141
  33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141
  34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141
  37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141
  40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141
  44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141
  47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141
  55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141
  58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141
  60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141
  65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141
  70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141
  74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141
  75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141
  80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141
  84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141
  86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141
  90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141
  91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141
  95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141
  98 10141   99 10141   99 10141   99 10141}

do_execsql_test 4.6.3 {
  SELECT b, sum(b) OVER (
    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  ) FROM t2 ORDER BY b;
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
  3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141
  8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141
  11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141
  14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141
  17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141
  23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141
  26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141
  30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141
  33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141
  34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141
  37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141
  40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141
  44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141
  47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141
  55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141
  58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141
  60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141
  65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141
  70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141
  74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141
  75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141
  80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141
  84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141
  86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141
  90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141
  91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141
  95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141
  98 10141   99 10141   99 10141   99 10141}

do_execsql_test 4.6.4 {
  SELECT b, sum(b) OVER (
    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  ) FROM t2 ORDER BY b;
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
  3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141
  8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141
  11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141
  14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141
  17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141
  23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141
  26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141
  30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141
  33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141
  34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141
  37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141
  40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141
  44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141
  47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141
  55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141
  58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141
  60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141
  65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141
  70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141
  74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141
  75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141
  80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141
  84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141
  86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141
  90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141
  91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141
  95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141
  98 10141   99 10141   99 10141   99 10141}

do_execsql_test 4.7.1 {
  SELECT b, sum(b) OVER (
    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
  ) FROM t2 ORDER BY 1, 2;
} {0 0   1 1   1 1   2 2   2 2   2 2   3 3   3 3   4 4   5 5   6 6   7 7   7 7
} {0 0   1 1   1 1   2 2   2 2   2 2   3 3   3 3   4 4   5 5   6 6   7 7   7 7   7 7   8 8   8 8   8 8   9 9   9 9   9 9   10 10   11 11   11 11   12 12   12 12   12 12   13 13   13 13   14 14   15 15   15 15   15 15   16 16   16 16   16 16   17 17   19 19   20 20   21 21   21 21   22 22   22 22   23 23   23 23   23 23   24 24   25 25   26 26   26 26   26 26   27 27   27 27   28 28   29 29   29 29   29 29   30 30   30 30   30 30   31 31   31 31   32 32   33 33   33 33   33 33   33 33   33 33   34 34   34 34   34 34   34 34   35 35   35 35   36 36   36 36   36 36   36 36   37 37   37 37   38 38   38 38   39 39   39 39   39 39   40 40   41 41   41 41   41 41   42 42   43 43   43 43   44 44   44 44   46 46   46 46   47 47   47 47   47 47   47 47   49 49   50 50   51 51   52 52   53 53   54 54   55 55   55 55   56 56   56 56   56 56   57 57   58 58   58 58   58 58   58 58   59 59   59 59   59 59   59 59   60 60   61 61   61 61   62 62   62 62   63 63   64 64   65 65   65 65   65 65   66 66   67 67   68 68   69 69   70 70   72 72   72 72   72 72   73 73   73 73   73 73   74 74   74 74   74 74   74 74   74 74   75 75   75 75   75 75   76 76   77 77   77 77   78 78   78 78   79 79   80 80   80 80   81 81   81 81   81 81   82 82   83 83   84 84   84 84   84 84   84 84   85 85   85 85   85 85   86 86   87 87   87 87   88 88   89 89   89 89   89 89   90 90   90 90   90 90   91 91   91 91   91 91   91 91   91 91   93 93   93 93   93 93   94 94   95 95   95 95   95 95   96 96   96 96   96 96   97 97   97 97   98 98   98 98   99 99   99 99   99 99}
  7 7   8 8   8 8   8 8   9 9   9 9   9 9   10 10   11 11   11 11   12 12
  12 12   12 12   13 13   13 13   14 14   15 15   15 15   15 15   16 16
  16 16   16 16   17 17   19 19   20 20   21 21   21 21   22 22   22 22
  23 23   23 23   23 23   24 24   25 25   26 26   26 26   26 26   27 27
  27 27   28 28   29 29   29 29   29 29   30 30   30 30   30 30   31 31
  31 31   32 32   33 33   33 33   33 33   33 33   33 33   34 34   34 34
  34 34   34 34   35 35   35 35   36 36   36 36   36 36   36 36   37 37
  37 37   38 38   38 38   39 39   39 39   39 39   40 40   41 41   41 41
  41 41   42 42   43 43   43 43   44 44   44 44   46 46   46 46   47 47
  47 47   47 47   47 47   49 49   50 50   51 51   52 52   53 53   54 54
  55 55   55 55   56 56   56 56   56 56   57 57   58 58   58 58   58 58
  58 58   59 59   59 59   59 59   59 59   60 60   61 61   61 61   62 62
  62 62   63 63   64 64   65 65   65 65   65 65   66 66   67 67   68 68
  69 69   70 70   72 72   72 72   72 72   73 73   73 73   73 73   74 74
  74 74   74 74   74 74   74 74   75 75   75 75   75 75   76 76   77 77
  77 77   78 78   78 78   79 79   80 80   80 80   81 81   81 81   81 81
  82 82   83 83   84 84   84 84   84 84   84 84   85 85   85 85   85 85
  86 86   87 87   87 87   88 88   89 89   89 89   89 89   90 90   90 90
  90 90   91 91   91 91   91 91   91 91   91 91   93 93   93 93   93 93
  94 94   95 95   95 95   95 95   96 96   96 96   96 96   97 97   97 97
  98 98   98 98   99 99   99 99   99 99}

do_execsql_test 4.7.2 {
  SELECT b, sum(b) OVER (
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) FROM t2 ORDER BY 1, 2;
} {0 0   1 3379   1 5443   2 372   2 4473   2 7074   3 2916   3 9096   4 4049
} {0 0   1 3379   1 5443   2 372   2 4473   2 7074   3 2916   3 9096   4 4049   5 5643   6 1047   7 2205   7 7081   7 10141   8 1553   8 5926   8 6422   9 4883   9 7932   9 8497   10 9544   11 5727   11 6433   12 2825   12 5918   12 8582   13 5190   13 8570   14 8596   15 3189   15 6023   15 8924   16 1942   16 1958   16 3590   17 10134   19 7474   20 5946   21 5464   21 9682   22 3029   22 6140   23 212   23 1926   23 8520   24 2626   25 3331   26 337   26 7539   26 7565   27 1270   27 10035   28 3217   29 1649   29 4355   29 7326   30 4215   30 9400   30 9853   31 5977   31 6008   32 2857   33 370   33 4326   33 8175   33 8909   33 9661   34 6414   34 6516   34 8958   34 9925   35 2151   35 5638   36 3701   36 7818   36 8785   36 8994   37 4597   37 8557   38 735   38 9891   39 842   39 7513   39 9721   40 3475   41 115   41 4874   41 5906   42 4185   43 2754   43 3518   44 7072   44 9765   46 1041   46 1316   47 2198   47 3378   47 7612   47 7923   49 6482   50 9450   51 5778   52 9370   53 4408   54 1448   55 3174   55 6876   56 2913   56 3435   56 3574   57 7223   58 5248   58 7876   58 9318   58 9823   59 697   59 2813   59 6665   59 7455   60 6821   61 2426   61 4944   62 904   62 8658   63 4471   64 8407   65 2116   65 5177   65 5603   66 8142   67 1620   68 803   69 9260   70 7396   72 4833   72 8004   72 8076   73 5017   73 5716   73 6213   74 74   74 189   74 2365   74 5538   74 7297   75 3665   75 6951   75 8343   76 3964   77 1903   77 7028   78 1394   78 4293   79 6292   80 4677   80 7692   81 542   81 4045   81 8488   82 10117   83 10008   84 1826   84 4761   84 9534   84 9628   85 2602   85 2711   85 7166   86 2291   87 4560   87 5865   88 6380   89 461   89 3306   89 3790   90 3119   90 6606   90 7782   91 995   91 2517   91 3007   91 8749   91 8876   93 1742   93 2051   93 8268   94 4143   95 5112   95 6118   95 9191   96 638   96 5344   96 6761   97 1243   97 1545   98 3888   98 5442   99 311   99 1146   99 9093}
  5 5643   6 1047   7 2205   7 7081   7 10141   8 1553   8 5926   8 6422
  9 4883   9 7932   9 8497   10 9544   11 5727   11 6433   12 2825   12 5918
  12 8582   13 5190   13 8570   14 8596   15 3189   15 6023   15 8924
  16 1942   16 1958   16 3590   17 10134   19 7474   20 5946   21 5464
  21 9682   22 3029   22 6140   23 212   23 1926   23 8520   24 2626
  25 3331   26 337   26 7539   26 7565   27 1270   27 10035   28 3217
  29 1649   29 4355   29 7326   30 4215   30 9400   30 9853   31 5977
  31 6008   32 2857   33 370   33 4326   33 8175   33 8909   33 9661
  34 6414   34 6516   34 8958   34 9925   35 2151   35 5638   36 3701
  36 7818   36 8785   36 8994   37 4597   37 8557   38 735   38 9891   39 842
  39 7513   39 9721   40 3475   41 115   41 4874   41 5906   42 4185
  43 2754   43 3518   44 7072   44 9765   46 1041   46 1316   47 2198
  47 3378   47 7612   47 7923   49 6482   50 9450   51 5778   52 9370
  53 4408   54 1448   55 3174   55 6876   56 2913   56 3435   56 3574
  57 7223   58 5248   58 7876   58 9318   58 9823   59 697   59 2813
  59 6665   59 7455   60 6821   61 2426   61 4944   62 904   62 8658
  63 4471   64 8407   65 2116   65 5177   65 5603   66 8142   67 1620
  68 803   69 9260   70 7396   72 4833   72 8004   72 8076   73 5017
  73 5716   73 6213   74 74   74 189   74 2365   74 5538   74 7297   75 3665
  75 6951   75 8343   76 3964   77 1903   77 7028   78 1394   78 4293
  79 6292   80 4677   80 7692   81 542   81 4045   81 8488   82 10117
  83 10008   84 1826   84 4761   84 9534   84 9628   85 2602   85 2711
  85 7166   86 2291   87 4560   87 5865   88 6380   89 461   89 3306
  89 3790   90 3119   90 6606   90 7782   91 995   91 2517   91 3007
  91 8749   91 8876   93 1742   93 2051   93 8268   94 4143   95 5112
  95 6118   95 9191   96 638   96 5344   96 6761   97 1243   97 1545
  98 3888   98 5442   99 311   99 1146   99 9093}

do_execsql_test 4.7.3 {
  SELECT b, sum(b) OVER (
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  ) FROM t2 ORDER BY 1, 2;
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
  3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141
  8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141
  11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141
  14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141
  17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141
  23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141
  26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141
  30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141
  33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141
  34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141
  37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141
  40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141
  44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141
  47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141
  55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141
  58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141
  60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141
  65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141
  70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141
  74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141
  75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141
  80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141
  84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141
  86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141
  90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141
  91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141
  95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141
  98 10141   99 10141   99 10141   99 10141}

do_execsql_test 4.7.4 {
  SELECT b, sum(b) OVER (
    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  ) FROM t2 ORDER BY 1, 2;
} {0 10141   1 4699   1 6763   2 3069   2 5670   2 9771   3 1048   3 7228
} {0 10141   1 4699   1 6763   2 3069   2 5670   2 9771   3 1048   3 7228   4 6096   5 4503   6 9100   7 7   7 3067   7 7943   8 3727   8 4223   8 8596   9 1653   9 2218   9 5267   10 607   11 3719   11 4425   12 1571   12 4235   12 7328   13 1584   13 4964   14 1559   15 1232   15 4133   15 6967   16 6567   16 8199   16 8215   17 24   19 2686   20 4215   21 480   21 4698   22 4023   22 7134   23 1644   23 8238   23 9952   24 7539   25 6835   26 2602   26 2628   26 9830   27 133   27 8898   28 6952   29 2844   29 5815   29 8521   30 318   30 771   30 5956   31 4164   31 4195   32 7316   33 513   33 1265   33 1999   33 5848   33 9804   34 250   34 1217   34 3659   34 3761   35 4538   35 8025   36 1183   36 1392   36 2359   36 6476   37 1621   37 5581   38 288   38 9444   39 459   39 2667   39 9338   40 6706   41 4276   41 5308   41 10067   42 5998   43 6666   43 7430   44 420   44 3113   46 8871   46 9146   47 2265   47 2576   47 6810   47 7990   49 3708   50 741   51 4414   52 823   53 5786   54 8747   55 3320   55 7022   56 6623   56 6762   56 7284   57 2975   58 376   58 881   58 2323   58 4951   59 2745   59 3535   59 7387   59 9503   60 3380   61 5258   61 7776   62 1545   62 9299   63 5733   64 1798   65 4603   65 5029   65 8090   66 2065   67 8588   68 9406   69 950   70 2815   72 2137   72 2209   72 5380   73 4001   73 4498   73 5197   74 2918   74 4677   74 7850   74 10026   74 10141   75 1873   75 3265   75 6551   76 6253   77 3190   77 8315   78 5926   78 8825   79 3928   80 2529   80 5544   81 1734   81 6177   81 9680   82 106   83 216   84 597   84 691   84 5464   84 8399   85 3060   85 7515   85 7624   86 7936   87 4363   87 5668   88 3849   89 6440   89 6924   89 9769   90 2449   90 3625   90 7112   91 1356   91 1483   91 7225   91 7715   91 9237   93 1966   93 8183   93 8492   94 6092   95 1045   95 4118   95 5124   96 3476   96 4893   96 9599   97 8693   97 8995   98 4797   98 6351   99 1147   99 9094   99 9929}
  4 6096   5 4503   6 9100   7 7   7 3067   7 7943   8 3727   8 4223   8 8596
  9 1653   9 2218   9 5267   10 607   11 3719   11 4425   12 1571   12 4235
  12 7328   13 1584   13 4964   14 1559   15 1232   15 4133   15 6967
  16 6567   16 8199   16 8215   17 24   19 2686   20 4215   21 480   21 4698
  22 4023   22 7134   23 1644   23 8238   23 9952   24 7539   25 6835
  26 2602   26 2628   26 9830   27 133   27 8898   28 6952   29 2844
  29 5815   29 8521   30 318   30 771   30 5956   31 4164   31 4195   32 7316
  33 513   33 1265   33 1999   33 5848   33 9804   34 250   34 1217   34 3659
  34 3761   35 4538   35 8025   36 1183   36 1392   36 2359   36 6476
  37 1621   37 5581   38 288   38 9444   39 459   39 2667   39 9338   40 6706
  41 4276   41 5308   41 10067   42 5998   43 6666   43 7430   44 420
  44 3113   46 8871   46 9146   47 2265   47 2576   47 6810   47 7990
  49 3708   50 741   51 4414   52 823   53 5786   54 8747   55 3320   55 7022
  56 6623   56 6762   56 7284   57 2975   58 376   58 881   58 2323   58 4951
  59 2745   59 3535   59 7387   59 9503   60 3380   61 5258   61 7776
  62 1545   62 9299   63 5733   64 1798   65 4603   65 5029   65 8090
  66 2065   67 8588   68 9406   69 950   70 2815   72 2137   72 2209
  72 5380   73 4001   73 4498   73 5197   74 2918   74 4677   74 7850
  74 10026   74 10141   75 1873   75 3265   75 6551   76 6253   77 3190
  77 8315   78 5926   78 8825   79 3928   80 2529   80 5544   81 1734
  81 6177   81 9680   82 106   83 216   84 597   84 691   84 5464   84 8399
  85 3060   85 7515   85 7624   86 7936   87 4363   87 5668   88 3849
  89 6440   89 6924   89 9769   90 2449   90 3625   90 7112   91 1356
  91 1483   91 7225   91 7715   91 9237   93 1966   93 8183   93 8492
  94 6092   95 1045   95 4118   95 5124   96 3476   96 4893   96 9599
  97 8693   97 8995   98 4797   98 6351   99 1147   99 9094   99 9929}

do_execsql_test 4.8.1 {
  SELECT b, sum(b) OVER (
    ORDER BY a
    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
  ) FROM t2 ORDER BY 1, 2;
} {0 0   1 1   1 1   2 2   2 2   2 2   3 3   3 3   4 4   5 5   6 6   7 7   7 7
} {0 0   1 1   1 1   2 2   2 2   2 2   3 3   3 3   4 4   5 5   6 6   7 7   7 7   7 7   8 8   8 8   8 8   9 9   9 9   9 9   10 10   11 11   11 11   12 12   12 12   12 12   13 13   13 13   14 14   15 15   15 15   15 15   16 16   16 16   16 16   17 17   19 19   20 20   21 21   21 21   22 22   22 22   23 23   23 23   23 23   24 24   25 25   26 26   26 26   26 26   27 27   27 27   28 28   29 29   29 29   29 29   30 30   30 30   30 30   31 31   31 31   32 32   33 33   33 33   33 33   33 33   33 33   34 34   34 34   34 34   34 34   35 35   35 35   36 36   36 36   36 36   36 36   37 37   37 37   38 38   38 38   39 39   39 39   39 39   40 40   41 41   41 41   41 41   42 42   43 43   43 43   44 44   44 44   46 46   46 46   47 47   47 47   47 47   47 47   49 49   50 50   51 51   52 52   53 53   54 54   55 55   55 55   56 56   56 56   56 56   57 57   58 58   58 58   58 58   58 58   59 59   59 59   59 59   59 59   60 60   61 61   61 61   62 62   62 62   63 63   64 64   65 65   65 65   65 65   66 66   67 67   68 68   69 69   70 70   72 72   72 72   72 72   73 73   73 73   73 73   74 74   74 74   74 74   74 74   74 74   75 75   75 75   75 75   76 76   77 77   77 77   78 78   78 78   79 79   80 80   80 80   81 81   81 81   81 81   82 82   83 83   84 84   84 84   84 84   84 84   85 85   85 85   85 85   86 86   87 87   87 87   88 88   89 89   89 89   89 89   90 90   90 90   90 90   91 91   91 91   91 91   91 91   91 91   93 93   93 93   93 93   94 94   95 95   95 95   95 95   96 96   96 96   96 96   97 97   97 97   98 98   98 98   99 99   99 99   99 99}
  7 7   8 8   8 8   8 8   9 9   9 9   9 9   10 10   11 11   11 11   12 12
  12 12   12 12   13 13   13 13   14 14   15 15   15 15   15 15   16 16
  16 16   16 16   17 17   19 19   20 20   21 21   21 21   22 22   22 22
  23 23   23 23   23 23   24 24   25 25   26 26   26 26   26 26   27 27
  27 27   28 28   29 29   29 29   29 29   30 30   30 30   30 30   31 31
  31 31   32 32   33 33   33 33   33 33   33 33   33 33   34 34   34 34
  34 34   34 34   35 35   35 35   36 36   36 36   36 36   36 36   37 37
  37 37   38 38   38 38   39 39   39 39   39 39   40 40   41 41   41 41
  41 41   42 42   43 43   43 43   44 44   44 44   46 46   46 46   47 47
  47 47   47 47   47 47   49 49   50 50   51 51   52 52   53 53   54 54
  55 55   55 55   56 56   56 56   56 56   57 57   58 58   58 58   58 58
  58 58   59 59   59 59   59 59   59 59   60 60   61 61   61 61   62 62
  62 62   63 63   64 64   65 65   65 65   65 65   66 66   67 67   68 68
  69 69   70 70   72 72   72 72   72 72   73 73   73 73   73 73   74 74
  74 74   74 74   74 74   74 74   75 75   75 75   75 75   76 76   77 77
  77 77   78 78   78 78   79 79   80 80   80 80   81 81   81 81   81 81
  82 82   83 83   84 84   84 84   84 84   84 84   85 85   85 85   85 85
  86 86   87 87   87 87   88 88   89 89   89 89   89 89   90 90   90 90
  90 90   91 91   91 91   91 91   91 91   91 91   93 93   93 93   93 93
  94 94   95 95   95 95   95 95   96 96   96 96   96 96   97 97   97 97
  98 98   98 98   99 99   99 99   99 99}

do_execsql_test 4.8.2 {
  SELECT b, sum(b) OVER (
    ORDER BY a
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) FROM t2 ORDER BY 1, 2;
} {0 0   1 3379   1 5443   2 372   2 4473   2 7074   3 2916   3 9096   4 4049
} {0 0   1 3379   1 5443   2 372   2 4473   2 7074   3 2916   3 9096   4 4049   5 5643   6 1047   7 2205   7 7081   7 10141   8 1553   8 5926   8 6422   9 4883   9 7932   9 8497   10 9544   11 5727   11 6433   12 2825   12 5918   12 8582   13 5190   13 8570   14 8596   15 3189   15 6023   15 8924   16 1942   16 1958   16 3590   17 10134   19 7474   20 5946   21 5464   21 9682   22 3029   22 6140   23 212   23 1926   23 8520   24 2626   25 3331   26 337   26 7539   26 7565   27 1270   27 10035   28 3217   29 1649   29 4355   29 7326   30 4215   30 9400   30 9853   31 5977   31 6008   32 2857   33 370   33 4326   33 8175   33 8909   33 9661   34 6414   34 6516   34 8958   34 9925   35 2151   35 5638   36 3701   36 7818   36 8785   36 8994   37 4597   37 8557   38 735   38 9891   39 842   39 7513   39 9721   40 3475   41 115   41 4874   41 5906   42 4185   43 2754   43 3518   44 7072   44 9765   46 1041   46 1316   47 2198   47 3378   47 7612   47 7923   49 6482   50 9450   51 5778   52 9370   53 4408   54 1448   55 3174   55 6876   56 2913   56 3435   56 3574   57 7223   58 5248   58 7876   58 9318   58 9823   59 697   59 2813   59 6665   59 7455   60 6821   61 2426   61 4944   62 904   62 8658   63 4471   64 8407   65 2116   65 5177   65 5603   66 8142   67 1620   68 803   69 9260   70 7396   72 4833   72 8004   72 8076   73 5017   73 5716   73 6213   74 74   74 189   74 2365   74 5538   74 7297   75 3665   75 6951   75 8343   76 3964   77 1903   77 7028   78 1394   78 4293   79 6292   80 4677   80 7692   81 542   81 4045   81 8488   82 10117   83 10008   84 1826   84 4761   84 9534   84 9628   85 2602   85 2711   85 7166   86 2291   87 4560   87 5865   88 6380   89 461   89 3306   89 3790   90 3119   90 6606   90 7782   91 995   91 2517   91 3007   91 8749   91 8876   93 1742   93 2051   93 8268   94 4143   95 5112   95 6118   95 9191   96 638   96 5344   96 6761   97 1243   97 1545   98 3888   98 5442   99 311   99 1146   99 9093}
  5 5643   6 1047   7 2205   7 7081   7 10141   8 1553   8 5926   8 6422
  9 4883   9 7932   9 8497   10 9544   11 5727   11 6433   12 2825   12 5918
  12 8582   13 5190   13 8570   14 8596   15 3189   15 6023   15 8924
  16 1942   16 1958   16 3590   17 10134   19 7474   20 5946   21 5464
  21 9682   22 3029   22 6140   23 212   23 1926   23 8520   24 2626
  25 3331   26 337   26 7539   26 7565   27 1270   27 10035   28 3217
  29 1649   29 4355   29 7326   30 4215   30 9400   30 9853   31 5977
  31 6008   32 2857   33 370   33 4326   33 8175   33 8909   33 9661
  34 6414   34 6516   34 8958   34 9925   35 2151   35 5638   36 3701
  36 7818   36 8785   36 8994   37 4597   37 8557   38 735   38 9891   39 842
  39 7513   39 9721   40 3475   41 115   41 4874   41 5906   42 4185
  43 2754   43 3518   44 7072   44 9765   46 1041   46 1316   47 2198
  47 3378   47 7612   47 7923   49 6482   50 9450   51 5778   52 9370
  53 4408   54 1448   55 3174   55 6876   56 2913   56 3435   56 3574
  57 7223   58 5248   58 7876   58 9318   58 9823   59 697   59 2813
  59 6665   59 7455   60 6821   61 2426   61 4944   62 904   62 8658
  63 4471   64 8407   65 2116   65 5177   65 5603   66 8142   67 1620
  68 803   69 9260   70 7396   72 4833   72 8004   72 8076   73 5017
  73 5716   73 6213   74 74   74 189   74 2365   74 5538   74 7297   75 3665
  75 6951   75 8343   76 3964   77 1903   77 7028   78 1394   78 4293
  79 6292   80 4677   80 7692   81 542   81 4045   81 8488   82 10117
  83 10008   84 1826   84 4761   84 9534   84 9628   85 2602   85 2711
  85 7166   86 2291   87 4560   87 5865   88 6380   89 461   89 3306
  89 3790   90 3119   90 6606   90 7782   91 995   91 2517   91 3007
  91 8749   91 8876   93 1742   93 2051   93 8268   94 4143   95 5112
  95 6118   95 9191   96 638   96 5344   96 6761   97 1243   97 1545
  98 3888   98 5442   99 311   99 1146   99 9093}

do_execsql_test 4.8.3 {
  SELECT b, sum(b) OVER (
    ORDER BY a
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  ) FROM t2 ORDER BY 1, 2;
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141
} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
  3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141
  8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141
  11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141
  14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141
  17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141
  23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141
  26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141
  30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141
  33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141
  34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141
  37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141
  40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141
  44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141
  47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141
  55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141
  58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141
  60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141
  65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141
  70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141
  74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141
  75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141
  80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141
  84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141
  86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141
  90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141
  91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141
  95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141
  98 10141   99 10141   99 10141   99 10141}

do_execsql_test 4.8.4 {
  SELECT b, sum(b) OVER (
    ORDER BY a
    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  ) FROM t2 ORDER BY 1, 2;
} {0 10141   1 4699   1 6763   2 3069   2 5670   2 9771   3 1048   3 7228
} {0 10141   1 4699   1 6763   2 3069   2 5670   2 9771   3 1048   3 7228   4 6096   5 4503   6 9100   7 7   7 3067   7 7943   8 3727   8 4223   8 8596   9 1653   9 2218   9 5267   10 607   11 3719   11 4425   12 1571   12 4235   12 7328   13 1584   13 4964   14 1559   15 1232   15 4133   15 6967   16 6567   16 8199   16 8215   17 24   19 2686   20 4215   21 480   21 4698   22 4023   22 7134   23 1644   23 8238   23 9952   24 7539   25 6835   26 2602   26 2628   26 9830   27 133   27 8898   28 6952   29 2844   29 5815   29 8521   30 318   30 771   30 5956   31 4164   31 4195   32 7316   33 513   33 1265   33 1999   33 5848   33 9804   34 250   34 1217   34 3659   34 3761   35 4538   35 8025   36 1183   36 1392   36 2359   36 6476   37 1621   37 5581   38 288   38 9444   39 459   39 2667   39 9338   40 6706   41 4276   41 5308   41 10067   42 5998   43 6666   43 7430   44 420   44 3113   46 8871   46 9146   47 2265   47 2576   47 6810   47 7990   49 3708   50 741   51 4414   52 823   53 5786   54 8747   55 3320   55 7022   56 6623   56 6762   56 7284   57 2975   58 376   58 881   58 2323   58 4951   59 2745   59 3535   59 7387   59 9503   60 3380   61 5258   61 7776   62 1545   62 9299   63 5733   64 1798   65 4603   65 5029   65 8090   66 2065   67 8588   68 9406   69 950   70 2815   72 2137   72 2209   72 5380   73 4001   73 4498   73 5197   74 2918   74 4677   74 7850   74 10026   74 10141   75 1873   75 3265   75 6551   76 6253   77 3190   77 8315   78 5926   78 8825   79 3928   80 2529   80 5544   81 1734   81 6177   81 9680   82 106   83 216   84 597   84 691   84 5464   84 8399   85 3060   85 7515   85 7624   86 7936   87 4363   87 5668   88 3849   89 6440   89 6924   89 9769   90 2449   90 3625   90 7112   91 1356   91 1483   91 7225   91 7715   91 9237   93 1966   93 8183   93 8492   94 6092   95 1045   95 4118   95 5124   96 3476   96 4893   96 9599   97 8693   97 8995   98 4797   98 6351   99 1147   99 9094   99 9929}
  4 6096   5 4503   6 9100   7 7   7 3067   7 7943   8 3727   8 4223   8 8596
  9 1653   9 2218   9 5267   10 607   11 3719   11 4425   12 1571   12 4235
  12 7328   13 1584   13 4964   14 1559   15 1232   15 4133   15 6967
  16 6567   16 8199   16 8215   17 24   19 2686   20 4215   21 480   21 4698
  22 4023   22 7134   23 1644   23 8238   23 9952   24 7539   25 6835
  26 2602   26 2628   26 9830   27 133   27 8898   28 6952   29 2844
  29 5815   29 8521   30 318   30 771   30 5956   31 4164   31 4195   32 7316
  33 513   33 1265   33 1999   33 5848   33 9804   34 250   34 1217   34 3659
  34 3761   35 4538   35 8025   36 1183   36 1392   36 2359   36 6476
  37 1621   37 5581   38 288   38 9444   39 459   39 2667   39 9338   40 6706
  41 4276   41 5308   41 10067   42 5998   43 6666   43 7430   44 420
  44 3113   46 8871   46 9146   47 2265   47 2576   47 6810   47 7990
  49 3708   50 741   51 4414   52 823   53 5786   54 8747   55 3320   55 7022
  56 6623   56 6762   56 7284   57 2975   58 376   58 881   58 2323   58 4951
  59 2745   59 3535   59 7387   59 9503   60 3380   61 5258   61 7776
  62 1545   62 9299   63 5733   64 1798   65 4603   65 5029   65 8090
  66 2065   67 8588   68 9406   69 950   70 2815   72 2137   72 2209
  72 5380   73 4001   73 4498   73 5197   74 2918   74 4677   74 7850
  74 10026   74 10141   75 1873   75 3265   75 6551   76 6253   77 3190
  77 8315   78 5926   78 8825   79 3928   80 2529   80 5544   81 1734
  81 6177   81 9680   82 106   83 216   84 597   84 691   84 5464   84 8399
  85 3060   85 7515   85 7624   86 7936   87 4363   87 5668   88 3849
  89 6440   89 6924   89 9769   90 2449   90 3625   90 7112   91 1356
  91 1483   91 7225   91 7715   91 9237   93 1966   93 8183   93 8492
  94 6092   95 1045   95 4118   95 5124   96 3476   96 4893   96 9599
  97 8693   97 8995   98 4797   98 6351   99 1147   99 9094   99 9929}


do_test 4.9 {
  set myres {}
  foreach r [db eval {SELECT 
    rank() OVER win AS rank,
    cume_dist() OVER win AS cume_dist FROM t1
  WINDOW win AS (ORDER BY 1);}] {
    lappend myres [format %.4f [set r]]
  }
  set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000}
  set i 0
  foreach r [set myres] r2 [set res2] {
    if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
      error "list element [set i] does not match: got=[set r] expected=[set r2]"
    }
    incr i
  }
  set {} {}
} {}

do_execsql_test 4.10 {
  SELECT count(*) OVER (ORDER BY b) FROM t1
} {3   3   3   6   6   6}

do_execsql_test 4.11 {
  SELECT count(distinct a) FILTER (WHERE b='odd') FROM t1
} {3}

#==========================================================================

do_execsql_test 5.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x INTEGER, y INTEGER);
  INSERT INTO t1 VALUES(10, 1);
  INSERT INTO t1 VALUES(20, 2);
  INSERT INTO t1 VALUES(3, 3);
  INSERT INTO t1 VALUES(2, 4);
  INSERT INTO t1 VALUES(1, 5);
} {}


do_test 5.1 {
  set myres {}
  foreach r [db eval {SELECT avg(x) OVER (ORDER BY y) AS z FROM t1 ORDER BY z;}] {
    lappend myres [format %.4f [set r]]
  }
  set res2 {7.2000 8.7500 10.0000 11.0000 15.0000}
  set i 0
  foreach r [set myres] r2 [set res2] {
    if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
      error "list element [set i] does not match: got=[set r] expected=[set r2]"
    }
    incr i
  }
  set {} {}
} {}

#==========================================================================

do_execsql_test 6.0 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 INTEGER UNIQUE);
  INSERT INTO t0 VALUES(0);
} {}

do_execsql_test 6.1 {
  SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0;
} {1 {}}

do_execsql_test 6.2 {
  SELECT * FROM t0 WHERE 
      (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0);
} {}

#==========================================================================

do_execsql_test 7.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER, b INTEGER, c INTEGER);
  INSERT INTO t1 VALUES(1, 1, 1);
  INSERT INTO t1 VALUES(1, 2, 2);
  INSERT INTO t1 VALUES(3, 3, 3);
  INSERT INTO t1 VALUES(3, 4, 4);
} {}

do_execsql_test 7.1 {
  SELECT c, sum(c) OVER win1 FROM t1 
  WINDOW win1 AS (ORDER BY b)
} {1 1   2 3   3 6   4 10}

do_execsql_test 7.2 {
  SELECT c, sum(c) OVER win1 FROM t1 
  WINDOW win1 AS (PARTITION BY 1 ORDER BY b)
} {1 1   2 3   3 6   4 10}

do_execsql_test 7.3 {
  SELECT c, sum(c) OVER win1 FROM t1 
  WINDOW win1 AS (ORDER BY 1)
} {1 10   2 10   3 10   4 10}

finish_test

Changes to test/window4.tcl.

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
381
382
383
384
385
386
387


































388
389
390







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




execsql_test 11.4 {
  SELECT * FROM (
    SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8
  ) sub;
}

execsql_test 11.5 {
  SELECT sum( min(t) ) OVER () FROM t8 GROUP BY total;
}
execsql_test 11.5 {
  SELECT sum( max(t) ) OVER () FROM t8 GROUP BY total;
}

execsql_test 11.7 {
  SELECT sum( min(t) ) OVER () FROM t8;
}
execsql_test 11.8 {
  SELECT sum( max(t) ) OVER () FROM t8;
}

execsql_test 12.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER);
  INSERT INTO t2 VALUES(1), (2), (3);
}

execsql_test 12.1 {
  SELECT (SELECT min(a) OVER ()) FROM t2
}

execsql_float_test 12.2 {
  SELECT (SELECT avg(a)) FROM t2 ORDER BY 1
}

execsql_float_test 12.3 {
  SELECT 
    (SELECT avg(a) UNION SELECT min(a) OVER ()) 
  FROM t2 GROUP BY a
  ORDER BY 1
}

finish_test

Changes to test/window4.test.

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
1320
1321
1322
1323
1324
1325
1326































































1327







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


do_execsql_test 11.4 {
  SELECT * FROM (
    SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8
  ) sub;
} {0   1   2}

do_execsql_test 11.5 {
  SELECT sum( min(t) ) OVER () FROM t8 GROUP BY total;
} {5   5}

do_execsql_test 11.5 {
  SELECT sum( max(t) ) OVER () FROM t8 GROUP BY total;
} {10   10}

do_execsql_test 11.7 {
  SELECT sum( min(t) ) OVER () FROM t8;
} {0}

do_execsql_test 11.8 {
  SELECT sum( max(t) ) OVER () FROM t8;
} {10}

do_execsql_test 12.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER);
  INSERT INTO t2 VALUES(1), (2), (3);
} {}

do_execsql_test 12.1 {
  SELECT (SELECT min(a) OVER ()) FROM t2
} {1   2   3}


do_test 12.2 {
  set myres {}
  foreach r [db eval {SELECT (SELECT avg(a)) FROM t2 ORDER BY 1}] {
    lappend myres [format %.4f [set r]]
  }
  set res2 {2.0000}
  set i 0
  foreach r [set myres] r2 [set res2] {
    if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
      error "list element [set i] does not match: got=[set r] expected=[set r2]"
    }
    incr i
  }
  set {} {}
} {}


do_test 12.3 {
  set myres {}
  foreach r [db eval {SELECT 
    (SELECT avg(a) UNION SELECT min(a) OVER ()) 
  FROM t2 GROUP BY a
  ORDER BY 1}] {
    lappend myres [format %.4f [set r]]
  }
  set res2 {1.0000 2.0000 3.0000}
  set i 0
  foreach r [set myres] r2 [set res2] {
    if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
      error "list element [set i] does not match: got=[set r] expected=[set r2]"
    }
    incr i
  }
  set {} {}
} {}

finish_test

Changes to test/window6.test.

364
365
366
367
368
369
370

364
365
366
367
368
369
370
371







+
} {
  fifteen fifteen 
  ten     fifteen.ten 
  thirty  fifteen.ten.thirty
}

finish_test

Changes to test/window7.test.

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
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







-
+
-





-
+
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-





-
+
-
-
-
-
-
-
-
-
-
-
-


    (1, 81), (2, 82), (3, 83), (4, 84), (5, 85), (6, 86), (7, 87), (8, 88), 
    (9, 89), (0, 90), (1, 91), (2, 92), (3, 93), (4, 94), (5, 95), (6, 96), 
    (7, 97), (8, 98), (9, 99), (0, 100);
} {}

do_execsql_test 1.1 {
  SELECT a, sum(b) FROM t3 GROUP BY a ORDER BY 1;
} {0 550   1 460   2 470   3 480   4 490   5 500   6 510   7 520   8 530
} {0 550   1 460   2 470   3 480   4 490   5 500   6 510   7 520   8 530   9 540}
  9 540}

do_execsql_test 1.2 {
  SELECT a, sum(b) OVER (
    ORDER BY a GROUPS BETWEEN CURRENT ROW AND CURRENT ROW
  ) FROM t3 ORDER BY 1;
} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550
} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540}
  0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460
  1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470
  2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480
  3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490
  4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500
  5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510
  6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520
  7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530
  8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530
  9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540
  9 540}

do_execsql_test 1.3 {
  SELECT a, sum(b) OVER (
    ORDER BY a GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING
  ) FROM t3 ORDER BY 1;
} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550
} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540}
  0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460
  1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470
  2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480
  3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490
  4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500
  5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510
  6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520
  7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530
  8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530
  9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540
  9 540}

do_execsql_test 1.4 {
  SELECT a, sum(b) OVER (
    ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING
  ) FROM t3 ORDER BY 1;
} {0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480
} {0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590}
  0 1480   0 1480   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960
  1 1960   1 1960   1 1960   1 1960   2 2450   2 2450   2 2450   2 2450
  2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   3 2400   3 2400
  3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400
  4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450
  4 2450   4 2450   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500
  5 2500   5 2500   5 2500   5 2500   6 2550   6 2550   6 2550   6 2550
  6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   7 2600   7 2600
  7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600
  8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100
  8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590
  9 1590   9 1590   9 1590   9 1590}

do_execsql_test 1.5 {
  SELECT a, sum(b) OVER (
    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING
  ) FROM t3 ORDER BY 1;
} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550
} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540}
  0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460
  1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470
  2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480
  3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490
  4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500
  5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510
  6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520
  7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530
  8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530
  9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540
  9 540}

do_execsql_test 1.6 {
  SELECT a, sum(b) OVER (
    ORDER BY a RANGE BETWEEN 2 PRECEDING AND 2 FOLLOWING
  ) FROM t3 ORDER BY 1;
} {0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480
} {0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590}
  0 1480   0 1480   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960
  1 1960   1 1960   1 1960   1 1960   2 2450   2 2450   2 2450   2 2450
  2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   3 2400   3 2400
  3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400
  4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450
  4 2450   4 2450   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500
  5 2500   5 2500   5 2500   5 2500   6 2550   6 2550   6 2550   6 2550
  6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   7 2600   7 2600
  7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600
  8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100
  8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590
  9 1590   9 1590   9 1590   9 1590}

do_execsql_test 1.7 {
  SELECT a, sum(b) OVER (
    ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
  ) FROM t3 ORDER BY 1;
} {0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010
} {0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590}
  0 1010   0 1010   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480
  1 1480   1 1480   1 1480   1 1480   2 1960   2 1960   2 1960   2 1960
  2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   3 1900   3 1900
  3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900
  4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940
  4 1940   4 1940   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980
  5 1980   5 1980   5 1980   5 1980   6 2020   6 2020   6 2020   6 2020
  6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   7 2060   7 2060
  7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060
  8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100
  8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590
  9 1590   9 1590   9 1590   9 1590}

do_execsql_test 1.8.1 {
  SELECT a, sum(b) OVER (
    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
  ) FROM t3 ORDER BY 1;
} {0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010
} {0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   1 930   1 930   1 930   1 930   1 930   1 930   1 930   1 930   1 930   1 930   2 950   2 950   2 950   2 950   2 950   2 950   2 950   2 950   2 950   2 950   3 970   3 970   3 970   3 970   3 970   3 970   3 970   3 970   3 970   3 970   4 990   4 990   4 990   4 990   4 990   4 990   4 990   4 990   4 990   4 990   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540}
  0 1010   0 1010   1 930   1 930   1 930   1 930   1 930   1 930   1 930
  1 930   1 930   1 930   2 950   2 950   2 950   2 950   2 950   2 950
  2 950   2 950   2 950   2 950   3 970   3 970   3 970   3 970   3 970
  3 970   3 970   3 970   3 970   3 970   4 990   4 990   4 990   4 990
  4 990   4 990   4 990   4 990   4 990   4 990   5 1010   5 1010   5 1010
  5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   6 1030
  6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030
  6 1030   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050
  7 1050   7 1050   7 1050   8 1070   8 1070   8 1070   8 1070   8 1070
  8 1070   8 1070   8 1070   8 1070   8 1070   9 540   9 540   9 540   9 540
  9 540   9 540   9 540   9 540   9 540   9 540}

do_execsql_test 1.8.2 {
  SELECT a, sum(b) OVER (
    ORDER BY a DESC RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
  ) FROM t3 ORDER BY 1;
} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550
} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   2 930   2 930   2 930   2 930   2 930   2 930   2 930   2 930   2 930   2 930   3 950   3 950   3 950   3 950   3 950   3 950   3 950   3 950   3 950   3 950   4 970   4 970   4 970   4 970   4 970   4 970   4 970   4 970   4 970   4 970   5 990   5 990   5 990   5 990   5 990   5 990   5 990   5 990   5 990   5 990   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070}
  0 550   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010
  1 1010   1 1010   1 1010   2 930   2 930   2 930   2 930   2 930   2 930
  2 930   2 930   2 930   2 930   3 950   3 950   3 950   3 950   3 950
  3 950   3 950   3 950   3 950   3 950   4 970   4 970   4 970   4 970
  4 970   4 970   4 970   4 970   4 970   4 970   5 990   5 990   5 990
  5 990   5 990   5 990   5 990   5 990   5 990   5 990   6 1010   6 1010
  6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010
  7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030
  7 1030   7 1030   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050
  8 1050   8 1050   8 1050   8 1050   9 1070   9 1070   9 1070   9 1070
  9 1070   9 1070   9 1070   9 1070   9 1070   9 1070}

finish_test

Changes to test/window8.tcl.

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
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







-
-
-
-
-
+
-
-
+




-
-
-
-
-






-
-
-
-
-






-
-
-
-
-
+
-
-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







}

execsql_test 4.2.1 {
  SELECT sum(b) OVER (
    ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
}
execsql_test 4.2.2 {
  SELECT sum(b) OVER (
    ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
}


execsql_test 4.2.3 {
execsql_test 4.2.2 {
  SELECT sum(b) OVER (
    ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
}
execsql_test 4.2.4 {
  SELECT sum(b) OVER (
    ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
}

execsql_test 4.3.1 {
  SELECT sum(b) OVER (
    ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
}
execsql_test 4.3.2 {
  SELECT sum(b) OVER (
    ORDER BY a NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
}

execsql_test 4.4.1 {
  SELECT sum(b) OVER (
    ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
}
execsql_test 4.4.2 {
  SELECT sum(b) OVER (
    ORDER BY a NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
}


execsql_test 4.4.3 {
execsql_test 4.4.2 {
  SELECT sum(b) OVER (
    ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
}
execsql_test 4.4.4 {
  SELECT sum(b) OVER (
    ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
}

execsql_test 4.5.1 {
  SELECT sum(b) OVER (
    ORDER BY a ASC  NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
}
execsql_test 4.5.2 {
  SELECT sum(b) OVER (
    ORDER BY a DESC NULLS FIRST RANGE 
    BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
}

==========

execsql_test 5.0 {
  INSERT INTO t3 VALUES
    (NULL, 'bb', 355), (NULL, 'cc', 158), (NULL, 'aa', 399), 
    ('JJ', NULL, 839), ('FF', NULL, 618), ('BB', NULL, 393), 
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
243
244
245
246
247
248
249











250
251
252
253
254
255
256







-
-
-
-
-
-
-
-
-
-
-







        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
    3 { PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
    4 { ORDER BY a NULLS FIRST GROUPS 6 PRECEDING }
    5 { ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING }
    6 { ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING }
    7 { ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING }

    8 { RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
    9 { ORDER BY a NULLS LAST 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
   10 { PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
   11 { ORDER BY a NULLS LAST GROUPS 6 PRECEDING }
   12 { ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING }
   13 { ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING }
   14 { ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING }
  } {
    execsql_test 5.$tn.$tn2.1 "
      SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
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
288
289
290
291
292
293
294
295

296













































































297
298
299








-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




execsql_test 6.2 {
  SELECT string_agg(a, '.') OVER (
    ORDER BY b DESC NULLS LAST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING
  )
  FROM t2
}

==========

execsql_test 7.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER, b INTEGER);

  INSERT INTO t2 VALUES(1, 65);
  INSERT INTO t2 VALUES(2, NULL);
  INSERT INTO t2 VALUES(3, NULL);
  INSERT INTO t2 VALUES(4, NULL);
  INSERT INTO t2 VALUES(5, 66);
  INSERT INTO t2 VALUES(6, 67);
}

foreach {tn f ex} {
  1 sum ""
  2 min ""
  3 sum "EXCLUDE CURRENT ROW"
  4 max "EXCLUDE CURRENT ROW"
} {
execsql_test 7.$tn.1 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING
  );
"
execsql_test 7.$tn.2 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
"
execsql_test 7.$tn.3 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
"
execsql_test 7.$tn.4 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
"
execsql_test 7.$tn.5 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
"

execsql_test 7.$tn.6 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING
  );
"
execsql_test 7.$tn.7 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
"
execsql_test 7.$tn.8 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING
  );
"
execsql_test 7.$tn.9 "
  SELECT $f (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
"
}



finish_test


Changes to test/window8.test.

3518
3519
3520
3521
3522
3523
3524
3525

3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537

3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549


3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561


3562
3563
3564
3565
3566
3567


3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610

3611
3612
3613
3614
3615
3616
3617
3518
3519
3520
3521
3522
3523
3524

3525
3526
3527
3528
3529






3530

3531
3532






3533
3534
3535


3536
3537
3538
3539






3540
3541


3542
3543
3544
3545
3546
3547


3548
3549
3550

























3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566

3567
3568
3569
3570
3571
3572
3573
3574







-
+




-
-
-
-
-
-

-
+

-
-
-
-
-
-



-
-
+
+


-
-
-
-
-
-


-
-
+
+




-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
















-
+







    ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1;
} {6   6   6   9   9}

do_execsql_test 4.2.1 {
  SELECT sum(b) OVER (
    ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
  ) FROM t1 ORDER BY 1 ;
} {{}   {}   6   6   6}

do_execsql_test 4.2.2 {
  SELECT sum(b) OVER (
    ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
} {6   6   6   {}   {}}

do_execsql_test 4.2.3 {
  SELECT sum(b) OVER (
    ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
  ) FROM t1 ORDER BY 1 ;
} {{}   {}   6   6   6}

do_execsql_test 4.2.4 {
  SELECT sum(b) OVER (
    ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
} {6   6   6   {}   {}}

do_execsql_test 4.3.1 {
  SELECT sum(b) OVER (
    ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
    ORDER BY a  RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 ;
} {6   6   6   15   15}

do_execsql_test 4.3.2 {
  SELECT sum(b) OVER (
    ORDER BY a NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
} {9   9   15   15   15}

do_execsql_test 4.4.1 {
  SELECT sum(b) OVER (
    ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
    ORDER BY a  ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 ;
} {3   6   9   9   12}

do_execsql_test 4.4.2 {
  SELECT sum(b) OVER (
    ORDER BY a NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
    ORDER BY a DESC  ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 ;
} {5   6   8   9   10}

do_execsql_test 4.4.3 {
  SELECT sum(b) OVER (
    ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS FIRST;
} {5   6   8   9   10}

do_execsql_test 4.4.4 {
  SELECT sum(b) OVER (
    ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
} {5   6   8   9   10}

do_execsql_test 4.5.1 {
  SELECT sum(b) OVER (
    ORDER BY a ASC  NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
} {9   9   15   15   15}

do_execsql_test 4.5.2 {
  SELECT sum(b) OVER (
    ORDER BY a DESC NULLS FIRST RANGE 
    BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
  ) FROM t1 ORDER BY 1 NULLS LAST;
} {6   6   6   15   15}

#==========================================================================

do_execsql_test 5.0 {
  INSERT INTO t3 VALUES
    (NULL, 'bb', 355), (NULL, 'cc', 158), (NULL, 'aa', 399), 
    ('JJ', NULL, 839), ('FF', NULL, 618), ('BB', NULL, 393), 
    (NULL, 'bb', 629), (NULL, NULL, 667), (NULL, NULL, 870);
} {}

do_execsql_test 5.1.1.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
3626
3627
3628
3629
3630
3631
3632
3633

3634
3635
3636
3637
3638
3639
3640
3583
3584
3585
3586
3587
3588
3589

3590
3591
3592
3593
3594
3595
3596
3597







-
+








do_execsql_test 5.1.1.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
3648
3649
3650
3651
3652
3653
3654
3655

3656
3657

3658
3659
3660
3661
3662
3663
3664
3605
3606
3607
3608
3609
3610
3611

3612
3613

3614
3615
3616
3617
3618
3619
3620
3621







-
+

-
+







  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1}

do_execsql_test 5.1.2.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST 
      WINDOW win AS (  ORDER BY a  
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {899 113 9   899 113 9   899 113 9   899 113 9   899 113 9   899 113 9
  899 113 9   899 113 9   899 113 9   899 113 16   899 113 16   899 113 16
  899 113 16   899 113 16   899 113 16   899 113 16   979 102 44   979 102 44
  979 102 44   979 102 44   979 102 44   979 102 44   979 102 44   979 102 44
  979 102 44   979 102 44   979 102 44   979 102 49   979 102 49   979 102 49
  979 102 49   979 102 49   979 102 56   979 102 56   979 102 56   979 102 56
  979 102 56   979 102 56   979 102 56   979 102 62   979 102 62   979 102 62
3672
3673
3674
3675
3676
3677
3678
3679

3680
3681

3682
3683
3684
3685
3686
3687
3688
3629
3630
3631
3632
3633
3634
3635

3636
3637

3638
3639
3640
3641
3642
3643
3644
3645







-
+

-
+







  979 113 33   979 113 33   979 113 33   979 113 33   979 113 33}

do_execsql_test 5.1.2.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST 
      WINDOW win AS (  ORDER BY a  
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {2947 81 11   2947 81 11   2947 81 11   2947 81 11   2947 81 11   2947 81 11
  2947 81 11   2947 81 11   2947 81 11   5287 74 10   5287 74 10   5287 74 10
  5287 74 10   5287 74 10   5287 74 10   5287 74 10   8400 65 9   8400 65 9
  8400 65 9   8400 65 9   8400 65 9   8400 65 9   8400 65 9   8400 65 9
  8400 65 9   9664 57 8   9664 57 8   9664 57 8   9664 57 8   9664 57 8
  9664 57 8   9664 57 8   9664 57 8   10626 46 7   10626 46 7   10626 46 7
  10626 46 7   10626 46 7   10626 46 7   10626 46 7   10626 46 7   10626 46 7
3698
3699
3700
3701
3702
3703
3704
3705

3706
3707
3708
3709
3710
3711
3712
3655
3656
3657
3658
3659
3660
3661

3662
3663
3664
3665
3666
3667
3668
3669







-
+







do_execsql_test 5.1.3.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {777 113 5   777 113 5   777 113 5   777 113 5   777 113 5   805 250 7
  805 250 7   805 250 7   805 250 7   805 250 7   805 250 7   805 250 7
  822 158 6   822 158 6   822 158 6   822 158 6   822 158 6   822 158 6
  840 247 13   840 247 13   840 247 13   840 247 13   840 247 13   840 247 13
  840 247 13   840 247 13   840 247 13   840 247 13   840 247 13   840 247 13
  840 247 13   870 158 0   870 158 0   870 158 0   870 158 0   870 158 0
  870 158 0   899 113 9   899 113 9   899 113 9   899 113 9   899 113 9
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
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







-
+



















-
-
+
+







do_execsql_test 5.1.3.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {962 1 1   962 1 1   962 1 1   962 1 1   962 1 1   962 1 1   962 1 1
  962 1 1   962 1 1   962 1 1   962 1 1   1264 1 1   1264 1 1   1264 1 1
  1264 1 1   1264 1 1   1264 1 1   1264 1 1   1264 1 1   1366 1 1   1366 1 1
  1366 1 1   1366 1 1   1366 1 1   1366 1 1   1519 1 1   1519 1 1   1519 1 1
  1519 1 1   1519 1 1   1804 1 1   1804 1 1   1804 1 1   1804 1 1   1804 1 1
  1804 1 1   1804 1 1   2050 1 1   2050 1 1   2050 1 1   2050 1 1   2050 1 1
  2050 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1
  2309 1 1   2309 1 1   2340 1 1   2340 1 1   2340 1 1   2340 1 1   2340 1 1
  2340 1 1   2340 1 1   2947 1 1   2947 1 1   2947 1 1   2947 1 1   2947 1 1
  2947 1 1   2947 1 1   2947 1 1   2947 1 1   3113 1 1   3113 1 1   3113 1 1
  3113 1 1   3113 1 1   3113 1 1   3113 1 1   3113 1 1   3113 1 1   3481 1 1
  3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1
  3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1}

do_execsql_test 5.1.4.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST GROUPS 6 PRECEDING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY a  GROUPS 6 PRECEDING   EXCLUDE NO OTHERS  )
      ORDER BY 1 , 2 , 3
} {870 158 0   870 158 0   870 158 0   870 158 0   870 158 0   870 158 0
  934 158 8   934 158 8   934 158 8   934 158 8   934 158 8   934 158 8
  934 158 8   934 158 8   934 158 21   934 158 21   934 158 21   934 158 21
  934 158 21   934 158 21   934 158 21   934 158 21   934 158 21   934 158 21
  934 158 21   934 158 21   934 158 21   934 158 27   934 158 27   934 158 27
  934 158 27   934 158 27   934 158 27   959 102 50   959 102 50   959 102 50
  959 102 50   959 102 50   959 102 50   959 102 50   959 102 50   959 102 50
3765
3766
3767
3768
3769
3770
3771
3772
3773


3774
3775
3776
3777
3778
3779
3780
3722
3723
3724
3725
3726
3727
3728


3729
3730
3731
3732
3733
3734
3735
3736
3737







-
-
+
+







  979 102 59   979 102 59   979 102 59   979 102 59   979 102 59}

do_execsql_test 5.1.4.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST GROUPS 6 PRECEDING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY a  GROUPS 6 PRECEDING   EXCLUDE NO OTHERS  )
      ORDER BY 1 , 2 , 3
} {2050 1 1   2050 1 1   2050 1 1   2050 1 1   2050 1 1   2050 1 1   4359 7 2
  4359 7 2   4359 7 2   4359 7 2   4359 7 2   4359 7 2   4359 7 2   4359 7 2
  7840 15 3   7840 15 3   7840 15 3   7840 15 3   7840 15 3   7840 15 3
  7840 15 3   7840 15 3   7840 15 3   7840 15 3   7840 15 3   7840 15 3
  7840 15 3   9206 28 4   9206 28 4   9206 28 4   9206 28 4   9206 28 4
  9206 28 4   11010 34 5   11010 34 5   11010 34 5   11010 34 5   11010 34 5
  11010 34 5   11010 34 5   12368 74 10   12368 74 10   12368 74 10
3789
3790
3791
3792
3793
3794
3795
3796
3797


3798
3799
3800
3801
3802
3803
3804
3746
3747
3748
3749
3750
3751
3752


3753
3754
3755
3756
3757
3758
3759
3760
3761







-
-
+
+







  13949 81 11}

do_execsql_test 5.1.5.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 , 2 , 3
} {102 102 1   113 113 2   113 113 2   133 133 1   148 148 1   160 158 2
  160 158 2   160 158 2   208 208 1   224 223 2   224 223 2   239 234 3
  239 234 3   239 234 3   252 247 3   257 247 5   257 247 5   257 250 4
  257 252 3   295 295 1   309 309 1   336 330 3   336 330 3   336 330 3
  346 346 1   355 354 2   355 354 2   355 354 2   399 393 4   399 393 4
  399 393 4   399 393 4   399 393 4   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 2   480 480 2   574 572 2   574 572 2   607 607 1
3812
3813
3814
3815
3816
3817
3818
3819
3820


3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842


3843
3844
3845
3846
3847
3848
3849
3769
3770
3771
3772
3773
3774
3775


3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797


3798
3799
3800
3801
3802
3803
3804
3805
3806







-
-
+
+




















-
-
+
+







  938 934 3   938 934 3   963 959 2   963 959 2   979 979 1}

do_execsql_test 5.1.5.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 25 23   {} 34 29
  {} 36 31   {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 43 37   {} 43 37
  {} 50 42   {} 60 51   {} 61 52   {} 64 55   {} 64 55   {} 67 57   {} 68 58
  {} 69 59   {} 70 60   {} 72 62   {} 78 67   {} 78 67   {} 78 67   {} 85 72
  {} 85 72   133 4 3   223 10 8   223 11 9   226 2 2   226 2 2   239 12 10
  239 13 11   239 14 12   247 15 13   257 18 16   257 19 17   295 20 18
  309 21 19   335 22 20   335 23 21   335 24 22   421 35 30   443 37 32
  504 16 14   504 17 15   607 42 36   683 56 47   710 26 24   710 27 25
  710 27 25   711 59 50   759 62 53   759 63 54   777 66 56   805 71 61
  899 81 68   911 82 69   929 83 70   929 84 71   979 89 75   1334 51 43
  1416 57 48   1416 58 49   1584 29 26   1584 29 26   1584 31 27   1584 32 28
  1584 32 28   1891 49 41   1922 87 73   1922 88 74   2005 52 44   2005 52 44
  2005 54 45   2005 55 46   2518 45 38   2518 46 39   2518 46 39   2518 48 40
  2523 73 63   2523 73 63   2523 75 64   2523 76 65   2523 77 66}

do_execsql_test 5.1.6.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 , 2 , 3
} {102 102 1   113 113 2   113 113 2   133 133 1   148 148 1   158 158 1
  158 158 1   160 160 1   208 208 1   223 223 1   224 224 1   234 234 1
  238 238 1   239 239 1   247 247 1   250 250 1   252 252 1   256 256 1
  257 257 1   295 295 1   309 309 1   330 330 1   335 335 1   336 336 1
  346 346 1   354 354 1   355 355 1   355 355 1   393 393 2   393 393 2
  398 398 1   399 399 1   399 399 1   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 2   480 480 2   572 572 1   574 574 1   607 607 1
3857
3858
3859
3860
3861
3862
3863
3864
3865


3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886

3887
3888

3889
3890
3891
3892
3893
3894
3895
3814
3815
3816
3817
3818
3819
3820


3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842

3843
3844

3845
3846
3847
3848
3849
3850
3851
3852







-
-
+
+




















-
+

-
+







  938 938 2   938 938 2   959 959 1   963 963 1   979 979 1}

do_execsql_test 5.1.6.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 11 9   {} 12 10
  {} 13 11   {} 16 14   {} 17 15   {} 18 16   {} 22 20   {} 24 22   {} 25 23
  {} 26 24   {} 31 27   {} 34 29   {} 36 31   {} 38 33   {} 38 33   {} 40 34
  {} 41 35   {} 43 37   {} 43 37   {} 49 41   {} 50 42   {} 51 43   {} 54 45
  {} 59 50   {} 60 51   {} 61 52   {} 63 54   {} 64 55   {} 64 55   {} 67 57
  {} 68 58   {} 69 59   {} 70 60   {} 72 62   {} 75 64   {} 76 65   {} 78 67
  {} 78 67   {} 78 67   {} 84 71   {} 85 72   {} 85 72   133 4 3   223 10 8
  226 2 2   226 2 2   239 14 12   247 15 13   257 19 17   295 20 18
  309 21 19   335 23 21   421 35 30   443 37 32   607 42 36   627 45 38
  633 48 40   671 55 46   683 56 47   705 57 48   710 27 25   710 27 25
  711 58 49   759 62 53   777 66 56   786 29 26   786 29 26   798 32 28
  798 32 28   805 71 61   845 77 66   899 81 68   911 82 69   929 83 70
  959 87 73   963 88 74   979 89 75   1258 46 39   1258 46 39   1334 52 44
  1334 52 44   1678 73 63   1678 73 63}

do_execsql_test 5.1.7.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
      WINDOW win AS (  ORDER BY c , b , a 
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 113 81   979 113 82   979 133 80   979 148 79   979 158 77
  979 158 78   979 160 77   979 208 76   979 223 75   979 224 74   979 234 73
  979 238 72   979 239 71   979 247 70   979 250 69   979 252 68   979 256 67
  979 257 66   979 295 65   979 309 64   979 330 63   979 335 62   979 336 61
  979 346 60   979 354 59   979 355 58   979 355 58   979 393 56   979 393 57
  979 398 55   979 399 54   979 399 54   979 412 53   979 421 52   979 430 51
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982

3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
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
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
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214

4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
3860
3861
3862
3863
3864
3865
3866









































































3867






































































































































































































































3868

3869
























3870
3871
3872
3873
3874
3875
3876







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  979 870 11   979 870 11   979 899 9   979 911 8   979 929 7}

do_execsql_test 5.1.7.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {3830 89 89   4741 88 88   5640 84 84   5640 85 85   5640 86 86   5640 87 87
  6485 81 81   6485 82 82   6485 83 83   7324 80 80   8163 78 78   8163 79 79
  8968 73 73   8968 74 74   8968 75 75   8968 76 76   8968 77 77   9745 69 69
  9745 70 70   9745 71 71   9745 72 72   10504 65 65   10504 66 66
  10504 67 67   10504 68 68   11215 64 64   11920 63 63   12603 62 62
  13274 60 60   13274 61 61   13941 59 59   14608 55 55   14608 56 56
  14608 57 57   14608 58 58   15241 54 54   15870 53 53   16499 52 52
  17126 49 49   17126 50 50   17126 51 51   17733 44 44   17733 45 45
  17733 46 46   17733 47 47   17733 48 48   18176 42 42   18176 43 43
  18597 40 40   18597 41 41   18996 39 39   19395 37 37   19395 38 38
  19788 36 36   20181 35 35   20536 34 34   20891 30 30   20891 31 31
  20891 32 32   20891 33 33   21226 28 28   21226 29 29   21535 27 27
  21830 26 26   22087 22 22   22087 23 23   22087 24 24   22087 25 25
  22334 21 21   22573 17 17   22573 18 18   22573 19 19   22573 20 20
  22796 11 11   22796 12 12   22796 13 13   22796 14 14   22796 15 15
  22796 16 16   22929 10 10   23042 9 9   23155 1 1   23155 2 2   23155 3 3
  23155 4 4   23155 5 5   23155 6 6   23155 7 7   23155 8 8}

do_execsql_test 5.1.8.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83}

do_execsql_test 5.1.8.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1}

do_execsql_test 5.1.9.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST 
      WINDOW win AS (  ORDER BY c , b , a 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {870 158 0   870 158 0   870 158 0   870 158 0   870 158 0   870 158 0
  899 113 9   899 113 9   899 113 9   899 113 9   899 113 9   899 113 9
  899 113 9   899 113 9   899 113 9   899 113 16   899 113 16   899 113 16
  899 113 16   899 113 16   899 113 16   899 113 16   979 102 44   979 102 44
  979 102 44   979 102 44   979 102 44   979 102 44   979 102 44   979 102 44
  979 102 44   979 102 44   979 102 44   979 102 49   979 102 49   979 102 49
  979 102 49   979 102 49   979 102 56   979 102 56   979 102 56   979 102 56
  979 102 56   979 102 56   979 102 56   979 102 62   979 102 62   979 102 62
  979 102 62   979 102 62   979 102 62   979 102 75   979 102 75   979 102 75
  979 102 75   979 102 75   979 102 75   979 102 75   979 102 75   979 102 75
  979 102 75   979 102 75   979 102 75   979 102 75   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 113 25   979 113 25   979 113 25   979 113 25   979 113 25   979 113 25
  979 113 25   979 113 25   979 113 25   979 113 33   979 113 33   979 113 33
  979 113 33   979 113 33   979 113 33   979 113 33   979 113 33}

do_execsql_test 5.1.9.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {2050 84 11   2050 84 11   2050 84 11   2050 84 11   2050 84 11   2050 84 11
  4997 75 10   4997 75 10   4997 75 10   4997 75 10   4997 75 10   4997 75 10
  4997 75 10   4997 75 10   4997 75 10   7337 68 9   7337 68 9   7337 68 9
  7337 68 9   7337 68 9   7337 68 9   7337 68 9   10450 59 8   10450 59 8
  10450 59 8   10450 59 8   10450 59 8   10450 59 8   10450 59 8   10450 59 8
  10450 59 8   11714 51 7   11714 51 7   11714 51 7   11714 51 7   11714 51 7
  11714 51 7   11714 51 7   11714 51 7   12676 40 6   12676 40 6   12676 40 6
  12676 40 6   12676 40 6   12676 40 6   12676 40 6   12676 40 6   12676 40 6
  12676 40 6   12676 40 6   14195 35 5   14195 35 5   14195 35 5   14195 35 5
  14195 35 5   15999 28 4   15999 28 4   15999 28 4   15999 28 4   15999 28 4
  15999 28 4   15999 28 4   17365 22 3   17365 22 3   17365 22 3   17365 22 3
  17365 22 3   17365 22 3   20846 9 2   20846 9 2   20846 9 2   20846 9 2
  20846 9 2   20846 9 2   20846 9 2   20846 9 2   20846 9 2   20846 9 2
  20846 9 2   20846 9 2   20846 9 2   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1}

do_execsql_test 5.1.10.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {777 113 5   777 113 5   777 113 5   777 113 5   777 113 5   805 250 7
  805 250 7   805 250 7   805 250 7   805 250 7   805 250 7   805 250 7
  822 158 6   822 158 6   822 158 6   822 158 6   822 158 6   822 158 6
  840 247 13   840 247 13   840 247 13   840 247 13   840 247 13   840 247 13
  840 247 13   840 247 13   840 247 13   840 247 13   840 247 13   840 247 13
  840 247 13   870 158 0   870 158 0   870 158 0   870 158 0   870 158 0
  870 158 0   899 113 9   899 113 9   899 113 9   899 113 9   899 113 9
  899 113 9   899 113 9   899 113 9   899 113 9   934 223 8   934 223 8
  934 223 8   934 223 8   934 223 8   934 223 8   934 223 8   934 223 8
  938 102 11   938 102 11   938 102 11   938 102 11   938 102 11   938 102 11
  938 102 11   938 102 11   938 102 11   938 102 11   938 102 11   938 148 8
  938 148 8   938 148 8   938 148 8   938 148 8   938 148 8   938 148 8
  938 148 8   959 224 7   959 224 7   959 224 7   959 224 7   959 224 7
  959 224 7   959 224 7   979 133 9   979 133 9   979 133 9   979 133 9
  979 133 9   979 133 9   979 133 9   979 133 9   979 133 9}

do_execsql_test 5.1.10.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {962 1 1   962 1 1   962 1 1   962 1 1   962 1 1   962 1 1   962 1 1
  962 1 1   962 1 1   962 1 1   962 1 1   1264 1 1   1264 1 1   1264 1 1
  1264 1 1   1264 1 1   1264 1 1   1264 1 1   1264 1 1   1366 1 1   1366 1 1
  1366 1 1   1366 1 1   1366 1 1   1366 1 1   1519 1 1   1519 1 1   1519 1 1
  1519 1 1   1519 1 1   1804 1 1   1804 1 1   1804 1 1   1804 1 1   1804 1 1
  1804 1 1   1804 1 1   2050 1 1   2050 1 1   2050 1 1   2050 1 1   2050 1 1
  2050 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1
  2309 1 1   2309 1 1   2340 1 1   2340 1 1   2340 1 1   2340 1 1   2340 1 1
  2340 1 1   2340 1 1   2947 1 1   2947 1 1   2947 1 1   2947 1 1   2947 1 1
  2947 1 1   2947 1 1   2947 1 1   2947 1 1   3113 1 1   3113 1 1   3113 1 1
  3113 1 1   3113 1 1   3113 1 1   3113 1 1   3113 1 1   3113 1 1   3481 1 1
  3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1
  3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1}

do_execsql_test 5.1.11.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST GROUPS 6 PRECEDING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {934 158 27   934 158 27   934 158 27   934 158 27   934 158 27   934 158 27
  934 223 8   934 223 8   934 223 8   934 223 8   934 223 8   934 223 8
  934 223 8   934 223 8   934 223 21   934 223 21   934 223 21   934 223 21
  934 223 21   934 223 21   934 223 21   934 223 21   934 223 21   934 223 21
  934 223 21   934 223 21   934 223 21   959 102 50   959 102 50   959 102 50
  959 102 50   959 102 50   959 102 50   959 102 50   959 102 50   959 102 50
  959 102 50   959 102 50   959 102 58   959 102 58   959 102 58   959 102 58
  959 102 58   959 102 58   959 102 58   959 102 58   959 113 39   959 113 39
  959 113 39   959 113 39   959 113 39   959 158 34   959 158 34   959 158 34
  959 158 34   959 158 34   959 158 34   959 158 34   979 102 49   979 102 49
  979 102 49   979 102 49   979 102 49   979 102 49   979 102 53   979 102 53
  979 102 53   979 102 53   979 102 53   979 102 53   979 102 53   979 102 56
  979 102 56   979 102 56   979 102 56   979 102 56   979 102 56   979 102 56
  979 102 56   979 102 56   979 102 59   979 102 59   979 102 59   979 102 59
  979 102 59   979 102 59   979 102 59   979 102 59   979 102 59}

do_execsql_test 5.1.11.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST GROUPS 6 PRECEDING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {2309 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1   2309 1 1
  2309 1 1   5790 9 2   5790 9 2   5790 9 2   5790 9 2   5790 9 2   5790 9 2
  5790 9 2   5790 9 2   5790 9 2   5790 9 2   5790 9 2   5790 9 2   5790 9 2
  7156 22 3   7156 22 3   7156 22 3   7156 22 3   7156 22 3   7156 22 3
  8960 28 4   8960 28 4   8960 28 4   8960 28 4   8960 28 4   8960 28 4
  8960 28 4   10479 35 5   10479 35 5   10479 35 5   10479 35 5   10479 35 5
  11441 40 6   11441 40 6   11441 40 6   11441 40 6   11441 40 6   11441 40 6
  11441 40 6   11441 40 6   11441 40 6   11441 40 6   11441 40 6   12368 68 9
  12368 68 9   12368 68 9   12368 68 9   12368 68 9   12368 68 9   12368 68 9
  12705 51 7   12705 51 7   12705 51 7   12705 51 7   12705 51 7   12705 51 7
  12705 51 7   12705 51 7   13509 59 8   13509 59 8   13509 59 8   13509 59 8
  13509 59 8   13509 59 8   13509 59 8   13509 59 8   13509 59 8
  13949 75 10   13949 75 10   13949 75 10   13949 75 10   13949 75 10
  13949 75 10   13949 75 10   13949 75 10   13949 75 10   14195 84 11
  14195 84 11   14195 84 11   14195 84 11   14195 84 11   14195 84 11}

do_execsql_test 5.1.12.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {102 102 1   113 113 2   113 113 2   133 133 1   148 148 1   160 158 2
  160 158 2   160 158 2   208 208 1   224 223 2   224 223 2   239 234 3
  239 234 3   239 234 3   252 247 3   257 247 5   257 247 5   257 250 4
  257 252 3   295 295 1   309 309 1   336 330 3   336 330 3   336 330 3
  346 346 1   355 354 2   355 354 2   355 354 2   399 393 4   399 393 4
  399 393 4   399 393 4   399 393 4   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 2   480 480 2   574 572 2   574 572 2   607 607 1
  618 618 2   618 618 2   634 627 4   634 627 4   634 627 4   634 627 4
  634 629 3   652 652 1   667 660 2   671 667 3   671 667 3   671 667 3
  671 667 3   683 683 1   711 705 2   716 705 3   716 711 2   730 726 2
  730 726 2   762 759 2   768 759 4   768 762 3   768 762 3   777 777 1
  792 786 3   794 786 4   794 786 4   794 790 3   805 805 1   822 822 1
  845 839 5   845 839 5   845 839 5   845 839 5   845 839 5   870 870 2
  870 870 2   870 870 2   899 899 1   911 911 1   934 929 2   938 929 4
  938 934 3   938 934 3   963 959 2   963 959 2   979 979 1}

do_execsql_test 5.1.12.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 25 23   {} 34 29
  {} 36 31   {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 43 37   {} 43 37
  {} 50 42   {} 60 51   {} 61 52   {} 64 55   {} 64 55   {} 67 57   {} 68 58
  {} 69 59   {} 70 60   {} 72 62   {} 78 67   {} 78 67   {} 78 67   {} 85 72
  {} 85 72   133 4 3   223 10 8   223 11 9   226 2 2   226 2 2   239 12 10
  239 13 11   239 14 12   247 15 13   257 18 16   257 19 17   295 20 18
  309 21 19   335 22 20   335 23 21   335 24 22   421 35 30   443 37 32
  504 16 14   504 17 15   607 42 36   683 56 47   710 26 24   710 27 25
  710 27 25   711 59 50   759 62 53   759 63 54   777 66 56   805 71 61
  899 81 68   911 82 69   929 83 70   929 84 71   979 89 75   1334 51 43
  1416 57 48   1416 58 49   1584 29 26   1584 29 26   1584 31 27   1584 32 28
  1584 32 28   1891 49 41   1922 87 73   1922 88 74   2005 52 44   2005 52 44
  2005 54 45   2005 55 46   2518 45 38   2518 46 39   2518 46 39   2518 48 40
  2523 73 63   2523 73 63   2523 75 64   2523 76 65   2523 77 66}

do_execsql_test 5.1.13.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {102 102 1   113 113 2   113 113 2   133 133 1   148 148 1   158 158 1
  158 158 1   160 160 1   208 208 1   223 223 1   224 224 1   234 234 1
  238 238 1   239 239 1   247 247 1   250 250 1   252 252 1   256 256 1
  257 257 1   295 295 1   309 309 1   330 330 1   335 335 1   336 336 1
  346 346 1   354 354 1   355 355 1   355 355 1   393 393 2   393 393 2
  398 398 1   399 399 1   399 399 1   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 2   480 480 2   572 572 1   574 574 1   607 607 1
  618 618 2   618 618 2   627 627 1   629 629 1   629 629 1   633 633 1
  634 634 1   652 652 1   660 660 1   667 667 1   667 667 1   670 670 1
  671 671 1   683 683 1   705 705 1   711 711 1   716 716 1   726 726 1
  730 730 1   759 759 1   762 762 1   768 768 2   768 768 2   777 777 1
  786 786 1   790 790 1   792 792 1   794 794 1   805 805 1   822 822 1
  839 839 2   839 839 2   840 840 1   844 844 1   845 845 1   870 870 2
  870 870 2   870 870 2   899 899 1   911 911 1   929 929 1   934 934 1
  938 938 2   938 938 2   959 959 1   963 963 1   979 979 1}

do_execsql_test 5.1.13.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 11 9   {} 12 10
  {} 13 11   {} 16 14   {} 17 15   {} 18 16   {} 22 20   {} 24 22   {} 25 23
  {} 26 24   {} 31 27   {} 34 29   {} 36 31   {} 38 33   {} 38 33   {} 40 34
  {} 41 35   {} 43 37   {} 43 37   {} 49 41   {} 50 42   {} 51 43   {} 54 45
  {} 59 50   {} 60 51   {} 61 52   {} 63 54   {} 64 55   {} 64 55   {} 67 57
  {} 68 58   {} 69 59   {} 70 60   {} 72 62   {} 75 64   {} 76 65   {} 78 67
  {} 78 67   {} 78 67   {} 84 71   {} 85 72   {} 85 72   133 4 3   223 10 8
  226 2 2   226 2 2   239 14 12   247 15 13   257 19 17   295 20 18
  309 21 19   335 23 21   421 35 30   443 37 32   607 42 36   627 45 38
  633 48 40   671 55 46   683 56 47   705 57 48   710 27 25   710 27 25
  711 58 49   759 62 53   777 66 56   786 29 26   786 29 26   798 32 28
  798 32 28   805 71 61   845 77 66   899 81 68   911 82 69   929 83 70
  959 87 73   963 88 74   979 89 75   1258 46 39   1258 46 39   1334 52 44
  1334 52 44   1678 73 63   1678 73 63}

do_execsql_test 5.1.14.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 113 81   979 113 82   979 133 80   979 148 79   979 158 77
  979 158 78   979 160 77   979 208 76   979 223 75   979 224 74   979 234 73
  979 238 72   979 239 71   979 247 70   979 250 69   979 252 68   979 256 67
  979 257 66   979 295 65   979 309 64   979 330 63   979 335 62   979 336 61
  979 346 60   979 354 59   979 355 57   979 355 58   979 393 56   979 393 57
  979 398 55   979 399 53   979 399 54   979 412 53   979 421 52   979 430 51
  979 443 50   979 480 48   979 480 49   979 572 47   979 574 46   979 607 45
  979 618 43   979 618 44   979 627 42   979 629 40   979 629 41   979 633 40
  979 634 39   979 652 38   979 660 37   979 667 35   979 667 36   979 670 35
  979 671 34   979 683 33   979 705 32   979 711 31   979 716 30   979 726 29
  979 730 28   979 759 27   979 762 26   979 768 24   979 768 25   979 777 23
  979 786 22   979 790 21   979 792 20   979 794 19   979 805 18   979 822 17
  979 839 15   979 839 16   979 840 14   979 844 13   979 845 12   979 870 9
  979 870 10   979 870 11   979 899 9   979 911 8   979 929 7}

do_execsql_test 5.1.14.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE NO OTHERS  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {3830 89 89   4741 88 88   5640 84 84   5640 85 85   5640 86 86   5640 87 87
  6485 81 81   6485 82 82   6485 83 83   7324 80 80   8163 78 78   8163 79 79
  8968 73 73   8968 74 74   8968 75 75   8968 76 76   8968 77 77   9745 69 69
  9745 70 70   9745 71 71   9745 72 72   10504 65 65   10504 66 66
  10504 67 67   10504 68 68   11215 64 64   11920 63 63   12603 62 62
  13274 60 60   13274 61 61   13941 59 59   14608 55 55   14608 56 56
  14608 57 57   14608 58 58   15241 54 54   15870 53 53   16499 52 52
4256
4257
4258
4259
4260
4261
4262
4263

4264
4265
4266
4267
4268
4269
4270
3887
3888
3889
3890
3891
3892
3893

3894
3895
3896
3897
3898
3899
3900
3901







-
+








do_execsql_test 5.2.1.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {963 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
4279
4280
4281
4282
4283
4284
4285
4286

4287
4288
4289
4290
4291
4292
4293
3910
3911
3912
3913
3914
3915
3916

3917
3918
3919
3920
3921
3922
3923
3924







-
+








do_execsql_test 5.2.1.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {22176 1 1   22192 1 1   22196 1 1   22226 1 1   22244 1 1   22256 1 1
  22310 1 1   22316 1 1   22316 1 1   22350 1 1   22378 1 1   22396 1 1
  22444 1 1   22450 1 1   22472 1 1   22484 1 1   22488 1 1   22488 1 1
  22522 1 1   22526 1 1   22526 1 1   22528 1 1   22548 1 1   22712 1 1
  22734 1 1   22756 1 1   22756 1 1   22762 1 1   22762 1 1   22800 1 1
  22800 1 1   22820 1 1   22846 1 1   22860 1 1   22898 1 1   22908 1 1
  22916 1 1   22932 1 1   23022 1 1   23042 1 1   23042 1 1   23155 1 1
4301
4302
4303
4304
4305
4306
4307
4308

4309
4310

4311
4312
4313
4314
4315
4316
4317
3932
3933
3934
3935
3936
3937
3938

3939
3940

3941
3942
3943
3944
3945
3946
3947
3948







-
+

-
+







  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1}

do_execsql_test 5.2.2.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST 
      WINDOW win AS (  ORDER BY a  
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {839 113 8   899 113 8   899 113 8   899 113 8   899 113 8   899 113 8
  899 113 8   899 113 8   899 113 15   899 113 15   899 113 15   899 113 15
  899 113 15   899 113 15   899 113 15   899 234 8   963 113 24   979 102 43
  979 102 43   979 102 43   979 102 43   979 102 43   979 102 43   979 102 43
  979 102 43   979 102 43   979 102 43   979 102 48   979 102 48   979 102 48
  979 102 48   979 102 48   979 102 55   979 102 55   979 102 55   979 102 55
  979 102 55   979 102 55   979 102 55   979 102 61   979 102 61   979 102 61
4325
4326
4327
4328
4329
4330
4331
4332

4333
4334

4335
4336
4337
4338
4339
4340
4341
3956
3957
3958
3959
3960
3961
3962

3963
3964

3965
3966
3967
3968
3969
3970
3971
3972







-
+

-
+







  979 113 32   979 113 32   979 113 32   979 113 32   979 113 43}

do_execsql_test 5.2.2.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST 
      WINDOW win AS (  ORDER BY a  
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {2048 81 11   2108 81 11   2108 81 11   2690 81 11   2834 81 11   2947 81 11
  2947 81 11   2947 81 11   2947 81 11   4482 74 10   4616 74 10   4844 74 10
  4866 74 10   5287 74 10   5287 74 10   5287 74 10   7421 65 9   7437 65 9
  7717 65 9   8045 65 9   8267 65 9   8400 65 9   8400 65 9   8400 65 9
  8400 65 9   8735 57 8   9329 57 8   9664 57 8   9664 57 8   9664 57 8
  9664 57 8   9664 57 8   9664 57 8   9959 46 7   10331 46 7   10626 46 7
  10626 46 7   10626 46 7   10626 46 7   10626 46 7   10626 46 7   10626 46 7
4351
4352
4353
4354
4355
4356
4357
4358

4359
4360
4361
4362
4363
4364
4365
3982
3983
3984
3985
3986
3987
3988

3989
3990
3991
3992
3993
3994
3995
3996







-
+







do_execsql_test 5.2.3.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {667 158 0   671 250 6   759 158 5   768 113 4   777 113 4   777 113 4
  777 113 4   777 252 4   792 247 12   805 250 6   805 250 6   805 250 6
  805 250 6   805 250 6   805 398 6   822 158 5   822 158 5   822 158 5
  822 158 5   822 346 5   839 113 8   840 247 12   840 247 12   840 247 12
  840 247 12   840 247 12   840 247 12   840 247 12   840 247 12   840 247 12
  840 247 12   840 247 12   840 393 12   845 224 6   870 102 10   870 158 0
  870 158 0   870 158 0   870 158 0   870 355 0   899 113 8   899 113 8
4375
4376
4377
4378
4379
4380
4381
4382

4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403


4404
4405
4406
4407
4408
4409
4410
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







-
+



















-
-
+
+







do_execsql_test 5.2.3.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {295 1 1   335 1 1   607 1 1   667 1 1   742 1 1   759 1 1   845 1 1
  890 1 1   929 1 1   959 1 1   962 1 1   962 1 1   962 1 1   962 1 1
  962 1 1   962 1 1   962 1 1   962 1 1   962 1 1   1264 1 1   1264 1 1
  1264 1 1   1264 1 1   1264 1 1   1264 1 1   1366 1 1   1366 1 1   1366 1 1
  1366 1 1   1383 1 1   1398 1 1   1406 1 1   1421 1 1   1519 1 1   1519 1 1
  1535 1 1   1651 1 1   1669 1 1   1682 1 1   1695 1 1   1804 1 1   1804 1 1
  1804 1 1   1804 1 1   1804 1 1   1897 1 1   1919 1 1   2000 1 1   2048 1 1
  2050 1 1   2050 1 1   2070 1 1   2086 1 1   2108 1 1   2108 1 1   2134 1 1
  2150 1 1   2309 1 1   2309 1 1   2309 1 1   2340 1 1   2340 1 1   2340 1 1
  2430 1 1   2690 1 1   2758 1 1   2770 1 1   2776 1 1   2834 1 1   2848 1 1
  2947 1 1   2947 1 1   2947 1 1   2947 1 1   2980 1 1   3082 1 1   3088 1 1
  3088 1 1   3113 1 1   3113 1 1   3113 1 1   3113 1 1   3234 1 1   3481 1 1
  3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1}

do_execsql_test 5.2.4.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST GROUPS 6 PRECEDING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY a  GROUPS 6 PRECEDING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 , 2 , 3
} {667 158 0   870 158 0   870 158 0   870 158 0   870 158 0   870 355 0
  911 158 7   934 158 7   934 158 7   934 158 7   934 158 7   934 158 7
  934 158 7   934 158 7   934 158 20   934 158 20   934 158 20   934 158 20
  934 158 20   934 158 20   934 158 20   934 158 20   934 158 20   934 158 20
  934 158 20   934 158 20   934 158 20   934 158 26   934 158 26   934 158 26
  934 158 26   934 158 26   934 158 26   934 158 33   959 102 49   959 102 49
  959 102 49   959 102 49   959 102 49   959 102 49   959 102 49   959 102 49
4418
4419
4420
4421
4422
4423
4424
4425
4426


4427
4428
4429
4430
4431
4432
4433
4049
4050
4051
4052
4053
4054
4055


4056
4057
4058
4059
4060
4061
4062
4063
4064







-
-
+
+







  979 102 58   979 102 58   979 102 58   979 102 58   979 102 58}

do_execsql_test 5.2.4.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST GROUPS 6 PRECEDING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY a  GROUPS 6 PRECEDING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 , 2 , 3
} {1383 1 1   1421 1 1   1651 1 1   1695 1 1   2050 1 1   2050 1 1   3448 7 2
  3732 7 2   4050 7 2   4120 7 2   4136 7 2   4359 7 2   4359 7 2   4359 7 2
  7129 15 3   7135 15 3   7207 15 3   7441 15 3   7447 15 3   7447 15 3
  7593 15 3   7840 15 3   7840 15 3   7840 15 3   7840 15 3   7840 15 3
  7840 15 3   8447 28 4   8599 28 4   9206 28 4   9206 28 4   9206 28 4
  9206 28 4   10051 34 5   10165 34 5   11010 34 5   11010 34 5   11010 34 5
  11010 34 5   11010 34 5   11563 74 10   11697 74 10   11752 41 6
4442
4443
4444
4445
4446
4447
4448
4449
4450


4451
4452
4453
4454
4455
4456
4457
4073
4074
4075
4076
4077
4078
4079


4080
4081
4082
4083
4084
4085
4086
4087
4088







-
-
+
+







  13949 81 11   13949 81 11   13949 81 11}

do_execsql_test 5.2.5.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 , 2 , 3
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   113 113 1
  113 113 1   158 158 1   160 158 1   160 158 2   223 223 1   224 224 1
  238 234 2   239 234 2   239 238 2   252 250 2   256 252 2   257 247 4
  257 247 4   257 250 3   335 330 2   336 330 2   336 335 2   355 354 1
  355 354 2   355 355 1   399 393 3   399 393 3   399 393 3   399 393 3
4465
4466
4467
4468
4469
4470
4471
4472
4473


4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495


4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517


4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537

4538
4539

4540
4541
4542
4543
4544
4545
4546
4096
4097
4098
4099
4100
4101
4102


4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124


4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146


4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167

4168
4169

4170
4171
4172
4173
4174
4175
4176
4177







-
-
+
+




















-
-
+
+




















-
-
+
+



















-
+

-
+







  959 959 1   963 963 1}

do_execsql_test 5.2.5.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 4 3   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 10 8
  {} 14 12   {} 15 13   {} 19 17   {} 20 18   {} 21 19   {} 23 21   {} 25 23
  {} 34 29   {} 35 30   {} 36 31   {} 37 32   {} 38 33   {} 38 33   {} 40 34
  {} 41 35   {} 42 36   {} 43 37   {} 43 37   {} 50 42   {} 56 47   {} 60 51
  {} 61 52   {} 62 53   {} 64 55   {} 64 55   {} 66 56   {} 67 57   {} 68 58
  {} 69 59   {} 70 60   {} 71 61   {} 72 62   {} 78 67   {} 78 67   {} 78 67
  {} 81 68   {} 82 69   {} 83 70   {} 85 72   {} 85 72   {} 89 75   113 2 2
  113 2 2   223 11 9   239 12 10   239 13 11   257 18 16   335 22 20
  335 24 22   355 27 25   355 27 25   504 16 14   504 17 15   705 58 49
  710 26 24   711 57 48   711 59 50   759 63 54   929 84 71   959 88 74
  963 87 73   1185 32 28   1185 32 28   1191 29 26   1191 29 26   1334 51 43
  1334 55 46   1338 52 44   1338 52 44   1584 31 27   1678 77 66   1684 73 63
  1684 73 63   1885 48 40   1889 46 39   1889 46 39   1891 45 38   1891 49 41
  2005 54 45   2523 75 64   2523 76 65}

do_execsql_test 5.2.6.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 , 2 , 3
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   113 113 1
  113 113 1   158 158 0   158 158 1   355 355 0   355 355 1   393 393 1
  393 393 1   399 399 0   399 399 1   480 480 1   480 480 1   618 618 1
  618 618 1   629 629 0   629 629 1   667 667 0   667 667 1   768 768 1
  768 768 1   839 839 1   839 839 1   870 870 1   870 870 1   870 870 2
  938 938 1   938 938 1}

do_execsql_test 5.2.6.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 4 3   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 10 8
  {} 11 9   {} 12 10   {} 13 11   {} 14 12   {} 15 13   {} 16 14   {} 17 15
  {} 18 16   {} 19 17   {} 20 18   {} 21 19   {} 22 20   {} 23 21   {} 24 22
  {} 25 23   {} 26 24   {} 31 27   {} 34 29   {} 35 30   {} 36 31   {} 37 32
  {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 42 36   {} 43 37   {} 43 37
  {} 45 38   {} 48 40   {} 49 41   {} 50 42   {} 51 43   {} 54 45   {} 55 46
  {} 56 47   {} 57 48   {} 58 49   {} 59 50   {} 60 51   {} 61 52   {} 62 53
  {} 63 54   {} 64 55   {} 64 55   {} 66 56   {} 67 57   {} 68 58   {} 69 59
  {} 70 60   {} 71 61   {} 72 62   {} 75 64   {} 76 65   {} 77 66   {} 78 67
  {} 78 67   {} 78 67   {} 81 68   {} 82 69   {} 83 70   {} 84 71   {} 85 72
  {} 85 72   {} 87 73   {} 88 74   {} 89 75   113 2 2   113 2 2   355 27 25
  355 27 25   393 29 26   393 29 26   399 32 28   399 32 28   629 46 39
  629 46 39   667 52 44   667 52 44   839 73 63   839 73 63}

do_execsql_test 5.2.7.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
      WINDOW win AS (  ORDER BY c , b , a 
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {963 929 6   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 83   979 113 80   979 113 81   979 113 82   979 133 79   979 148 78
  979 158 76   979 158 77   979 160 76   979 208 75   979 223 74   979 224 73
  979 234 72   979 238 71   979 239 70   979 247 69   979 250 68   979 252 67
  979 256 66   979 257 65   979 295 64   979 309 64   979 330 62   979 335 61
  979 336 60   979 346 59   979 354 59   979 355 57   979 355 57   979 393 55
  979 393 56   979 398 54   979 399 53   979 399 53   979 412 52   979 421 51
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
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
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
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
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
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
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4185
4186
4187
4188
4189
4190
4191









































































4192





































































































































































































































4193

4194
























4195
4196
4197
4198
4199
4200
4201







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  979 870 9   979 870 10   979 870 10   979 899 8   979 911 7}

do_execsql_test 5.2.7.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {2851 89 89   3778 88 88   4681 87 87   5556 83 83   5574 82 82   5586 81 81
  5640 84 84   5640 85 85   5640 86 86   7324 80 80   8123 77 77   8129 73 73
  8129 74 74   8163 78 78   8163 79 79   8940 71 71   8968 75 75   8968 76 76
  9727 66 66   9745 69 69   9745 70 70   9745 72 72   10504 65 65
  10504 67 67   10504 68 68   11215 64 64   11844 62 62   11920 63 63
  13274 60 60   13274 61 61   13897 58 58   13903 57 57   13925 56 56
  13937 55 55   13941 59 59   15203 53 53   15241 54 54   15832 52 52
  17100 48 48   17104 46 46   17104 47 47   17106 45 45   17126 49 49
  17126 50 50   17126 51 51   17569 42 42   17733 44 44   18176 43 43
  18597 40 40   18597 41 41   18952 37 37   18996 39 39   19395 38 38
  19760 35 35   19788 36 36   20492 32 32   20492 33 33   20498 30 30
  20536 34 34   20833 29 29   20871 28 28   20891 31 31   21180 27 27
  21752 23 23   21830 26 26   22025 21 21   22087 22 22   22087 24 24
  22087 25 25   22278 20 20   22316 19 19   22549 15 15   22557 14 14
  22573 17 17   22573 18 18   22706 10 10   22796 11 11   22796 12 12
  22796 13 13   22796 16 16   23022 4 4   23042 2 2   23042 3 3   23042 9 9
  23155 1 1   23155 5 5   23155 6 6   23155 7 7   23155 8 8}

do_execsql_test 5.2.8.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {963 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 83   979 102 83
  979 102 83   979 102 83   979 102 83   979 102 83   979 113 82}

do_execsql_test 5.2.8.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {22176 1 1   22192 1 1   22196 1 1   22226 1 1   22244 1 1   22256 1 1
  22310 1 1   22316 1 1   22316 1 1   22350 1 1   22378 1 1   22396 1 1
  22444 1 1   22450 1 1   22472 1 1   22484 1 1   22488 1 1   22488 1 1
  22522 1 1   22526 1 1   22526 1 1   22528 1 1   22548 1 1   22712 1 1
  22734 1 1   22756 1 1   22756 1 1   22762 1 1   22762 1 1   22800 1 1
  22800 1 1   22820 1 1   22846 1 1   22860 1 1   22898 1 1   22908 1 1
  22916 1 1   22932 1 1   23022 1 1   23042 1 1   23042 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1
  23155 1 1   23155 1 1   23155 1 1   23155 1 1   23155 1 1}

do_execsql_test 5.2.9.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST 
      WINDOW win AS (  ORDER BY c , b , a 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {667 158 0   870 113 8   870 158 0   870 158 0   870 158 0   870 158 0
  870 355 0   899 113 8   899 113 8   899 113 8   899 113 8   899 113 8
  899 113 8   899 113 8   899 113 15   899 113 15   899 113 15   899 113 15
  899 113 15   899 113 15   899 113 15   899 158 8   963 113 24   979 102 43
  979 102 43   979 102 43   979 102 43   979 102 43   979 102 43   979 102 43
  979 102 43   979 102 43   979 102 43   979 102 48   979 102 48   979 102 48
  979 102 48   979 102 48   979 102 55   979 102 55   979 102 55   979 102 55
  979 102 55   979 102 55   979 102 55   979 102 61   979 102 61   979 102 61
  979 102 61   979 102 61   979 102 61   979 102 74   979 102 74   979 102 74
  979 102 74   979 102 74   979 102 74   979 102 74   979 102 74   979 102 74
  979 102 74   979 102 74   979 102 74   979 102 74   979 102 82   979 102 82
  979 102 82   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 113 24   979 113 24   979 113 24   979 113 24   979 113 24   979 113 24
  979 113 24   979 113 24   979 113 32   979 113 32   979 113 32   979 113 32
  979 113 32   979 113 32   979 113 32   979 113 32   979 113 43}

do_execsql_test 5.2.9.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {1383 84 11   1421 84 11   1651 84 11   1695 84 11   2050 84 11   2050 84 11
  4098 75 10   4158 75 10   4158 75 10   4740 75 10   4884 75 10   4997 75 10
  4997 75 10   4997 75 10   4997 75 10   6532 68 9   6666 68 9   6894 68 9
  6916 68 9   7337 68 9   7337 68 9   7337 68 9   9471 59 8   9487 59 8
  9767 59 8   10095 59 8   10317 59 8   10450 59 8   10450 59 8   10450 59 8
  10450 59 8   10785 51 7   11379 51 7   11714 51 7   11714 51 7   11714 51 7
  11714 51 7   11714 51 7   11714 51 7   12009 40 6   12381 40 6   12676 40 6
  12676 40 6   12676 40 6   12676 40 6   12676 40 6   12676 40 6   12676 40 6
  12676 40 6   12676 40 6   13418 35 5   13566 35 5   14082 35 5   14195 35 5
  14195 35 5   15040 28 4   15154 28 4   15999 28 4   15999 28 4   15999 28 4
  15999 28 4   15999 28 4   16606 22 3   16758 22 3   17365 22 3   17365 22 3
  17365 22 3   17365 22 3   20135 9 2   20141 9 2   20213 9 2   20447 9 2
  20453 9 2   20453 9 2   20599 9 2   20846 9 2   20846 9 2   20846 9 2
  20846 9 2   20846 9 2   20846 9 2   22244 1 1   22528 1 1   22846 1 1
  22916 1 1   22932 1 1   23155 1 1   23155 1 1   23155 1 1}

do_execsql_test 5.2.10.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {667 158 0   671 250 6   759 158 5   768 113 4   777 113 4   777 113 4
  777 113 4   777 252 4   792 247 12   805 250 6   805 250 6   805 250 6
  805 250 6   805 250 6   805 398 6   822 158 5   822 158 5   822 158 5
  822 158 5   822 346 5   839 113 8   840 247 12   840 247 12   840 247 12
  840 247 12   840 247 12   840 247 12   840 247 12   840 247 12   840 247 12
  840 247 12   840 247 12   840 393 12   845 224 6   870 102 10   870 158 0
  870 158 0   870 158 0   870 158 0   870 355 0   899 113 8   899 113 8
  899 113 8   899 113 8   899 113 8   899 113 8   899 113 8   899 234 8
  911 223 7   929 148 7   934 223 7   934 223 7   934 223 7   934 223 7
  934 223 7   934 223 7   934 239 7   938 102 10   938 102 10   938 102 10
  938 102 10   938 102 10   938 102 10   938 102 10   938 102 10   938 102 10
  938 148 7   938 148 7   938 148 7   938 148 7   938 148 7   938 148 7
  938 160 7   938 208 10   959 224 6   959 224 6   959 224 6   959 224 6
  959 224 6   959 238 6   963 133 8   979 133 8   979 133 8   979 133 8
  979 133 8   979 133 8   979 133 8   979 133 8   979 330 8}

do_execsql_test 5.2.10.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {295 1 1   335 1 1   607 1 1   667 1 1   742 1 1   759 1 1   845 1 1
  890 1 1   929 1 1   959 1 1   962 1 1   962 1 1   962 1 1   962 1 1
  962 1 1   962 1 1   962 1 1   962 1 1   962 1 1   1264 1 1   1264 1 1
  1264 1 1   1264 1 1   1264 1 1   1264 1 1   1366 1 1   1366 1 1   1366 1 1
  1366 1 1   1383 1 1   1398 1 1   1406 1 1   1421 1 1   1519 1 1   1519 1 1
  1535 1 1   1651 1 1   1669 1 1   1682 1 1   1695 1 1   1804 1 1   1804 1 1
  1804 1 1   1804 1 1   1804 1 1   1897 1 1   1919 1 1   2000 1 1   2048 1 1
  2050 1 1   2050 1 1   2070 1 1   2086 1 1   2108 1 1   2108 1 1   2134 1 1
  2150 1 1   2309 1 1   2309 1 1   2309 1 1   2340 1 1   2340 1 1   2340 1 1
  2430 1 1   2690 1 1   2758 1 1   2770 1 1   2776 1 1   2834 1 1   2848 1 1
  2947 1 1   2947 1 1   2947 1 1   2947 1 1   2980 1 1   3082 1 1   3088 1 1
  3088 1 1   3113 1 1   3113 1 1   3113 1 1   3113 1 1   3234 1 1   3481 1 1
  3481 1 1   3481 1 1   3481 1 1   3481 1 1   3481 1 1}

do_execsql_test 5.2.11.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST GROUPS 6 PRECEDING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {911 223 7   934 158 26   934 158 26   934 158 26   934 158 26   934 158 26
  934 158 33   934 223 7   934 223 7   934 223 7   934 223 7   934 223 7
  934 223 7   934 223 20   934 223 20   934 223 20   934 223 20   934 223 20
  934 223 20   934 223 20   934 223 20   934 223 20   934 223 20   934 223 20
  934 223 20   934 223 20   934 223 26   934 239 7   959 102 49   959 102 49
  959 102 49   959 102 49   959 102 49   959 102 49   959 102 49   959 102 49
  959 102 49   959 102 49   959 102 57   959 102 57   959 102 57   959 102 57
  959 102 57   959 102 57   959 102 57   959 102 57   959 113 38   959 113 38
  959 113 38   959 113 38   959 113 49   959 158 33   959 158 33   959 158 33
  959 158 33   959 158 33   959 158 33   959 158 38   963 102 58   979 102 49
  979 102 49   979 102 49   979 102 49   979 102 49   979 102 49   979 102 52
  979 102 52   979 102 52   979 102 52   979 102 52   979 102 52   979 102 52
  979 102 55   979 102 55   979 102 55   979 102 55   979 102 55   979 102 55
  979 102 55   979 102 55   979 102 55   979 102 58   979 102 58   979 102 58
  979 102 58   979 102 58   979 102 58   979 102 58   979 102 58}

do_execsql_test 5.2.11.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST GROUPS 6 PRECEDING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {1398 1 1   1682 1 1   2000 1 1   2070 1 1   2086 1 1   2309 1 1   2309 1 1
  2309 1 1   5079 9 2   5085 9 2   5157 9 2   5391 9 2   5397 9 2   5397 9 2
  5543 9 2   5790 9 2   5790 9 2   5790 9 2   5790 9 2   5790 9 2   5790 9 2
  6397 22 3   6549 22 3   7156 22 3   7156 22 3   7156 22 3   7156 22 3
  8001 28 4   8115 28 4   8960 28 4   8960 28 4   8960 28 4   8960 28 4
  8960 28 4   9702 35 5   9850 35 5   10366 35 5   10479 35 5   10479 35 5
  10774 40 6   11146 40 6   11441 40 6   11441 40 6   11441 40 6   11441 40 6
  11441 40 6   11441 40 6   11441 40 6   11441 40 6   11441 40 6   11563 68 9
  11697 68 9   11776 51 7   11925 68 9   11947 68 9   12368 68 9   12368 68 9
  12368 68 9   12370 51 7   12530 59 8   12546 59 8   12705 51 7   12705 51 7
  12705 51 7   12705 51 7   12705 51 7   12705 51 7   12826 59 8
  13050 75 10   13110 75 10   13110 75 10   13154 59 8   13376 59 8
  13509 59 8   13509 59 8   13509 59 8   13509 59 8   13528 84 11
  13566 84 11   13692 75 10   13796 84 11   13836 75 10   13840 84 11
  13949 75 10   13949 75 10   13949 75 10   13949 75 10   14195 84 11
  14195 84 11}

do_execsql_test 5.2.12.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   113 113 1
  113 113 1   158 158 1   160 158 1   160 158 2   223 223 1   224 224 1
  238 234 2   239 234 2   239 238 2   252 250 2   256 252 2   257 247 4
  257 247 4   257 250 3   335 330 2   336 330 2   336 335 2   355 354 1
  355 354 2   355 355 1   399 393 3   399 393 3   399 393 3   399 393 3
  399 393 4   480 480 1   480 480 1   572 572 1   574 574 1   618 618 1
  618 618 1   633 629 2   634 627 3   634 627 3   634 627 4   634 629 3
  667 667 1   670 667 2   671 667 2   671 667 2   671 667 3   711 711 1
  711 711 1   716 705 2   726 726 1   730 730 1   762 762 1   768 759 3
  768 762 2   768 762 2   792 790 2   792 790 2   794 786 3   794 786 3
  844 839 4   845 839 4   845 839 4   845 839 4   845 839 4   870 870 1
  870 870 1   870 870 2   934 934 1   938 929 3   938 934 2   938 934 2
  959 959 1   963 963 1}

do_execsql_test 5.2.12.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 4 3   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 10 8
  {} 14 12   {} 15 13   {} 19 17   {} 20 18   {} 21 19   {} 23 21   {} 25 23
  {} 34 29   {} 35 30   {} 36 31   {} 37 32   {} 38 33   {} 38 33   {} 40 34
  {} 41 35   {} 42 36   {} 43 37   {} 43 37   {} 50 42   {} 56 47   {} 60 51
  {} 61 52   {} 62 53   {} 64 55   {} 64 55   {} 66 56   {} 67 57   {} 68 58
  {} 69 59   {} 70 60   {} 71 61   {} 72 62   {} 78 67   {} 78 67   {} 78 67
  {} 81 68   {} 82 69   {} 83 70   {} 85 72   {} 85 72   {} 89 75   113 2 2
  113 2 2   223 11 9   239 12 10   239 13 11   257 18 16   335 22 20
  335 24 22   355 27 25   355 27 25   504 16 14   504 17 15   705 58 49
  710 26 24   711 57 48   711 59 50   759 63 54   929 84 71   959 88 74
  963 87 73   1185 32 28   1185 32 28   1191 29 26   1191 29 26   1334 51 43
  1334 55 46   1338 52 44   1338 52 44   1584 31 27   1678 77 66   1684 73 63
  1684 73 63   1885 48 40   1889 46 39   1889 46 39   1891 45 38   1891 49 41
  2005 54 45   2523 75 64   2523 76 65}

do_execsql_test 5.2.13.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   113 113 1
  113 113 1   158 158 0   158 158 1   355 355 0   355 355 1   393 393 1
  393 393 1   399 399 0   399 399 1   480 480 1   480 480 1   618 618 1
  618 618 1   629 629 0   629 629 1   667 667 0   667 667 1   768 768 1
  768 768 1   839 839 1   839 839 1   870 870 1   870 870 1   870 870 2
  938 938 1   938 938 1}

do_execsql_test 5.2.13.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 4 3   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 10 8
  {} 11 9   {} 12 10   {} 13 11   {} 14 12   {} 15 13   {} 16 14   {} 17 15
  {} 18 16   {} 19 17   {} 20 18   {} 21 19   {} 22 20   {} 23 21   {} 24 22
  {} 25 23   {} 26 24   {} 31 27   {} 34 29   {} 35 30   {} 36 31   {} 37 32
  {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 42 36   {} 43 37   {} 43 37
  {} 45 38   {} 48 40   {} 49 41   {} 50 42   {} 51 43   {} 54 45   {} 55 46
  {} 56 47   {} 57 48   {} 58 49   {} 59 50   {} 60 51   {} 61 52   {} 62 53
  {} 63 54   {} 64 55   {} 64 55   {} 66 56   {} 67 57   {} 68 58   {} 69 59
  {} 70 60   {} 71 61   {} 72 62   {} 75 64   {} 76 65   {} 77 66   {} 78 67
  {} 78 67   {} 78 67   {} 81 68   {} 82 69   {} 83 70   {} 84 71   {} 85 72
  {} 85 72   {} 87 73   {} 88 74   {} 89 75   113 2 2   113 2 2   355 27 25
  355 27 25   393 29 26   393 29 26   399 32 28   399 32 28   629 46 39
  629 46 39   667 52 44   667 52 44   839 73 63   839 73 63}

do_execsql_test 5.2.14.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {963 929 6   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 83   979 113 80   979 113 81   979 113 82   979 133 79   979 148 78
  979 158 76   979 158 77   979 160 76   979 208 75   979 223 74   979 224 73
  979 234 72   979 238 71   979 239 70   979 247 69   979 250 68   979 252 67
  979 256 66   979 257 65   979 295 64   979 309 63   979 330 63   979 335 61
  979 336 60   979 346 59   979 354 58   979 355 56   979 355 58   979 393 55
  979 393 56   979 398 54   979 399 52   979 399 53   979 412 52   979 421 51
  979 430 50   979 443 49   979 480 47   979 480 48   979 572 46   979 574 46
  979 607 44   979 618 42   979 618 43   979 627 41   979 629 40   979 629 40
  979 633 39   979 634 38   979 652 37   979 660 36   979 667 34   979 667 35
  979 670 34   979 671 33   979 683 32   979 705 31   979 711 30   979 716 29
  979 726 28   979 730 27   979 759 26   979 762 25   979 768 23   979 768 24
  979 777 22   979 786 21   979 790 20   979 792 19   979 794 18   979 805 17
  979 822 16   979 839 15   979 839 15   979 840 13   979 844 12   979 845 11
  979 870 8   979 870 9   979 870 10   979 899 8   979 911 7}

do_execsql_test 5.2.14.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE CURRENT ROW  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {2851 89 89   3778 88 88   4681 87 87   5556 83 83   5574 82 82   5586 81 81
  5640 84 84   5640 85 85   5640 86 86   7324 80 80   8123 77 77   8129 73 73
  8129 74 74   8163 78 78   8163 79 79   8940 71 71   8968 75 75   8968 76 76
  9727 66 66   9745 69 69   9745 70 70   9745 72 72   10504 65 65
  10504 67 67   10504 68 68   11215 64 64   11844 62 62   11920 63 63
  13274 60 60   13274 61 61   13897 58 58   13903 57 57   13925 56 56
  13937 55 55   13941 59 59   15203 53 53   15241 54 54   15832 52 52
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
4212
4213
4214
4215
4216
4217
4218

4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239

4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258

4259
4260

4261
4262
4263
4264
4265
4266
4267
4268







-
+




















-
+


















-
+

-
+








do_execsql_test 5.3.1.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0}

do_execsql_test 5.3.1.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1}

do_execsql_test 5.3.2.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST 
      WINDOW win AS (  ORDER BY a  
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   899 113 9   899 113 9   899 113 9   899 113 9
  899 113 9   899 113 9   899 113 9   899 113 16   899 113 16   899 113 16
  899 113 16   899 113 16   899 113 16   899 113 16   899 113 16   899 113 16
  979 102 44   979 102 44   979 102 44   979 102 44   979 102 44   979 102 49
  979 102 49   979 102 49   979 102 49   979 102 49   979 102 49   979 102 49
  979 102 56   979 102 56   979 102 56   979 102 56   979 102 56   979 102 56
4970
4971
4972
4973
4974
4975
4976
4977

4978
4979

4980
4981
4982
4983
4984
4985
4986
4276
4277
4278
4279
4280
4281
4282

4283
4284

4285
4286
4287
4288
4289
4290
4291
4292







-
+

-
+







  979 113 33   979 113 33   979 113 33   979 113 33}

do_execsql_test 5.3.2.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST 
      WINDOW win AS (  ORDER BY a  
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} 81 11   {} 81 11   {} 81 11   {} 81 11   {} 81 11   {} 81 11   {} 81 11
  {} 81 11   {} 81 11   2947 74 10   2947 74 10   2947 74 10   2947 74 10
  2947 74 10   2947 74 10   2947 74 10   5287 65 9   5287 65 9   5287 65 9
  5287 65 9   5287 65 9   5287 65 9   5287 65 9   5287 65 9   5287 65 9
  8400 57 8   8400 57 8   8400 57 8   8400 57 8   8400 57 8   8400 57 8
  8400 57 8   8400 57 8   9664 46 7   9664 46 7   9664 46 7   9664 46 7
  9664 46 7   9664 46 7   9664 46 7   9664 46 7   9664 46 7   9664 46 7
4996
4997
4998
4999
5000
5001
5002
5003

5004
5005
5006
5007
5008
5009
5010
4302
4303
4304
4305
4306
4307
4308

4309
4310
4311
4312
4313
4314
4315
4316







-
+







do_execsql_test 5.3.3.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
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
4324
4325
4326
4327
4328
4329
4330

4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349


4350
4351
4352
4353
4354
4355
4356
4357
4358







-
+


















-
-
+
+







do_execsql_test 5.3.3.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1}

do_execsql_test 5.3.4.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST GROUPS 6 PRECEDING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY a  GROUPS 6 PRECEDING   EXCLUDE GROUP  )
      ORDER BY 1 , 2 , 3
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   870 158 0
  870 158 0   870 158 0   870 158 0   870 158 0   870 158 0   870 158 0
  870 158 0   934 158 8   934 158 8   934 158 8   934 158 8   934 158 8
  934 158 8   934 158 8   934 158 8   934 158 8   934 158 8   934 158 8
  934 158 8   934 158 8   934 158 21   934 158 21   934 158 21   934 158 21
  934 158 21   934 158 21   934 158 27   934 158 27   934 158 27   934 158 27
  934 158 27   934 158 27   934 158 27   959 102 50   959 102 50   959 102 50
5060
5061
5062
5063
5064
5065
5066
5067
5068


5069
5070
5071
5072
5073
5074
5075
4366
4367
4368
4369
4370
4371
4372


4373
4374
4375
4376
4377
4378
4379
4380
4381







-
-
+
+







  979 102 47   979 102 47   979 102 47   979 102 47}

do_execsql_test 5.3.4.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST GROUPS 6 PRECEDING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY a  GROUPS 6 PRECEDING   EXCLUDE GROUP  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   2050 7 2   2050 7 2
  2050 7 2   2050 7 2   2050 7 2   2050 7 2   2050 7 2   2050 7 2   4359 15 3
  4359 15 3   4359 15 3   4359 15 3   4359 15 3   4359 15 3   4359 15 3
  4359 15 3   4359 15 3   4359 15 3   4359 15 3   4359 15 3   4359 15 3
  7840 28 4   7840 28 4   7840 28 4   7840 28 4   7840 28 4   7840 28 4
  9206 34 5   9206 34 5   9206 34 5   9206 34 5   9206 34 5   9206 34 5
  9206 34 5   10028 74 10   10028 74 10   10028 74 10   10028 74 10
5083
5084
5085
5086
5087
5088
5089
5090
5091


5092
5093
5094
5095
5096
5097
5098
4389
4390
4391
4392
4393
4394
4395


4396
4397
4398
4399
4400
4401
4402
4403
4404







-
-
+
+







  12529 46 7   12529 46 7   12529 46 7   12529 46 7   12529 46 7   12529 46 7}

do_execsql_test 5.3.5.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 , 2 , 3
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   158 158 1   160 160 1   160 160 1   223 223 1   224 224 1
  238 234 2   239 234 2   239 238 2   252 250 2   256 252 2   257 247 4
  257 247 4   257 250 3   335 330 2   336 330 2   336 335 2   354 354 1
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
4412
4413
4414
4415
4416
4417
4418


4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440


4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461


4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482

4483
4484

4485
4486
4487
4488
4489
4490
4491
4492







-
-
+
+




















-
-
+
+



















-
-
+
+



















-
+

-
+







  963 963 1}

do_execsql_test 5.3.5.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 2 2   {} 2 2   {} 4 3   {} 5 4   {} 6 5   {} 6 5   {} 8 6
  {} 9 7   {} 10 8   {} 14 12   {} 15 13   {} 19 17   {} 20 18   {} 21 19
  {} 23 21   {} 25 23   {} 27 25   {} 27 25   {} 34 29   {} 35 30   {} 36 31
  {} 37 32   {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 42 36   {} 43 37
  {} 43 37   {} 50 42   {} 56 47   {} 60 51   {} 61 52   {} 62 53   {} 64 55
  {} 64 55   {} 66 56   {} 67 57   {} 68 58   {} 69 59   {} 70 60   {} 71 61
  {} 72 62   {} 78 67   {} 78 67   {} 78 67   {} 81 68   {} 82 69   {} 83 70
  {} 85 72   {} 85 72   {} 89 75   223 11 9   239 12 10   239 13 11
  257 18 16   335 22 20   335 24 22   504 16 14   504 17 15   671 52 44
  671 52 44   705 58 49   710 26 24   711 57 48   711 59 50   759 63 54
  786 32 28   786 32 28   798 29 26   798 29 26   845 73 63   845 73 63
  929 84 71   959 88 74   963 87 73   1260 46 39   1260 46 39   1334 51 43
  1334 55 46   1584 31 27   1678 77 66   1885 48 40   1891 45 38   1891 49 41
  2005 54 45   2523 75 64   2523 76 65}

do_execsql_test 5.3.6.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 , 2 , 3
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0}

do_execsql_test 5.3.6.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 2 2   {} 2 2   {} 4 3   {} 5 4   {} 6 5   {} 6 5   {} 8 6
  {} 9 7   {} 10 8   {} 11 9   {} 12 10   {} 13 11   {} 14 12   {} 15 13
  {} 16 14   {} 17 15   {} 18 16   {} 19 17   {} 20 18   {} 21 19   {} 22 20
  {} 23 21   {} 24 22   {} 25 23   {} 26 24   {} 27 25   {} 27 25   {} 29 26
  {} 29 26   {} 31 27   {} 32 28   {} 32 28   {} 34 29   {} 35 30   {} 36 31
  {} 37 32   {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 42 36   {} 43 37
  {} 43 37   {} 45 38   {} 46 39   {} 46 39   {} 48 40   {} 49 41   {} 50 42
  {} 51 43   {} 52 44   {} 52 44   {} 54 45   {} 55 46   {} 56 47   {} 57 48
  {} 58 49   {} 59 50   {} 60 51   {} 61 52   {} 62 53   {} 63 54   {} 64 55
  {} 64 55   {} 66 56   {} 67 57   {} 68 58   {} 69 59   {} 70 60   {} 71 61
  {} 72 62   {} 73 63   {} 73 63   {} 75 64   {} 76 65   {} 77 66   {} 78 67
  {} 78 67   {} 78 67   {} 81 68   {} 82 69   {} 83 70   {} 84 71   {} 85 72
  {} 85 72   {} 87 73   {} 88 74   {} 89 75}

do_execsql_test 5.3.7.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
      WINDOW win AS (  ORDER BY c , b , a 
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {963 929 6   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 83   979 113 80   979 113 81   979 113 82   979 133 79   979 148 78
  979 158 76   979 158 77   979 160 76   979 208 75   979 223 74   979 224 73
  979 234 72   979 238 71   979 239 70   979 247 69   979 250 68   979 252 67
  979 256 66   979 257 65   979 295 64   979 309 64   979 330 62   979 335 61
  979 336 60   979 346 59   979 354 59   979 355 57   979 355 57   979 393 55
  979 393 56   979 398 54   979 399 53   979 399 53   979 412 52   979 421 51
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
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
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
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
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494

5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
4500
4501
4502
4503
4504
4505
4506




































































4507
































































































































































































































4508

4509
























4510
4511
4512
4513
4514
4515
4516







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  979 870 9   979 870 10   979 870 10   979 899 8   979 911 7}

do_execsql_test 5.3.7.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {2851 89 89   3778 88 88   4681 87 87   5556 83 83   5574 82 82   5586 81 81
  5640 84 84   5640 85 85   5640 86 86   7324 80 80   8123 77 77   8129 73 73
  8129 74 74   8163 78 78   8163 79 79   8940 71 71   8968 75 75   8968 76 76
  9727 66 66   9745 69 69   9745 70 70   9745 72 72   10504 65 65
  10504 67 67   10504 68 68   11215 64 64   11844 62 62   11920 63 63
  13274 60 60   13274 61 61   13897 58 58   13903 57 57   13925 56 56
  13937 55 55   13941 59 59   15203 53 53   15241 54 54   15832 52 52
  17100 48 48   17104 46 46   17104 47 47   17106 45 45   17126 49 49
  17126 50 50   17126 51 51   17569 42 42   17733 44 44   18176 43 43
  18597 40 40   18597 41 41   18952 37 37   18996 39 39   19395 38 38
  19760 35 35   19788 36 36   20492 32 32   20492 33 33   20498 30 30
  20536 34 34   20833 29 29   20871 28 28   20891 31 31   21180 27 27
  21752 23 23   21830 26 26   22025 21 21   22087 22 22   22087 24 24
  22087 25 25   22278 20 20   22316 19 19   22549 15 15   22557 14 14
  22573 17 17   22573 18 18   22706 10 10   22796 11 11   22796 12 12
  22796 13 13   22796 16 16   23022 4 4   23042 2 2   23042 3 3   23042 9 9
  23155 1 1   23155 5 5   23155 6 6   23155 7 7   23155 8 8}

do_execsql_test 5.3.8.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0}

do_execsql_test 5.3.8.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1}

do_execsql_test 5.3.9.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST 
      WINDOW win AS (  ORDER BY c , b , a 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   870 158 0
  870 158 0   870 158 0   870 158 0   870 158 0   870 158 0   870 158 0
  870 158 0   870 158 0   899 113 9   899 113 9   899 113 9   899 113 9
  899 113 9   899 113 9   899 113 9   899 113 16   899 113 16   899 113 16
  899 113 16   899 113 16   899 113 16   899 113 16   899 113 16   899 113 16
  979 102 44   979 102 44   979 102 44   979 102 44   979 102 44   979 102 49
  979 102 49   979 102 49   979 102 49   979 102 49   979 102 49   979 102 49
  979 102 56   979 102 56   979 102 56   979 102 56   979 102 56   979 102 56
  979 102 62   979 102 62   979 102 62   979 102 62   979 102 62   979 102 62
  979 102 62   979 102 62   979 102 62   979 102 62   979 102 62   979 102 62
  979 102 62   979 102 75   979 102 75   979 102 75   979 102 75   979 102 75
  979 102 75   979 102 75   979 102 75   979 113 25   979 113 25   979 113 25
  979 113 25   979 113 25   979 113 25   979 113 25   979 113 25   979 113 33
  979 113 33   979 113 33   979 113 33   979 113 33   979 113 33   979 113 33
  979 113 33   979 113 33   979 113 33   979 113 33}

do_execsql_test 5.3.9.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 84 11   {} 84 11   {} 84 11   {} 84 11   {} 84 11   {} 84 11
  2050 75 10   2050 75 10   2050 75 10   2050 75 10   2050 75 10   2050 75 10
  2050 75 10   2050 75 10   2050 75 10   4997 68 9   4997 68 9   4997 68 9
  4997 68 9   4997 68 9   4997 68 9   4997 68 9   7337 59 8   7337 59 8
  7337 59 8   7337 59 8   7337 59 8   7337 59 8   7337 59 8   7337 59 8
  7337 59 8   10450 51 7   10450 51 7   10450 51 7   10450 51 7   10450 51 7
  10450 51 7   10450 51 7   10450 51 7   11714 40 6   11714 40 6   11714 40 6
  11714 40 6   11714 40 6   11714 40 6   11714 40 6   11714 40 6   11714 40 6
  11714 40 6   11714 40 6   12676 35 5   12676 35 5   12676 35 5   12676 35 5
  12676 35 5   14195 28 4   14195 28 4   14195 28 4   14195 28 4   14195 28 4
  14195 28 4   14195 28 4   15999 22 3   15999 22 3   15999 22 3   15999 22 3
  15999 22 3   15999 22 3   17365 9 2   17365 9 2   17365 9 2   17365 9 2
  17365 9 2   17365 9 2   17365 9 2   17365 9 2   17365 9 2   17365 9 2
  17365 9 2   17365 9 2   17365 9 2   20846 1 1   20846 1 1   20846 1 1
  20846 1 1   20846 1 1   20846 1 1   20846 1 1   20846 1 1}

do_execsql_test 5.3.10.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0}

do_execsql_test 5.3.10.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1}

do_execsql_test 5.3.11.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST GROUPS 6 PRECEDING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   934 158 27   934 158 27   934 158 27   934 158 27   934 158 27
  934 158 27   934 158 27   934 223 8   934 223 8   934 223 8   934 223 8
  934 223 8   934 223 8   934 223 8   934 223 8   934 223 8   934 223 8
  934 223 8   934 223 8   934 223 8   934 223 21   934 223 21   934 223 21
  934 223 21   934 223 21   934 223 21   959 102 50   959 102 50   959 102 50
  959 102 50   959 102 50   959 102 50   959 102 50   959 102 50   959 102 50
  959 102 50   959 102 50   959 102 50   959 102 50   959 102 50   959 102 50
  959 102 50   959 102 50   959 113 39   959 113 39   959 113 39   959 113 39
  959 113 39   959 113 39   959 113 39   959 113 39   959 113 39   959 113 39
  959 113 39   959 158 34   959 158 34   959 158 34   959 158 34   959 158 34
  979 102 46   979 102 46   979 102 46   979 102 46   979 102 46   979 102 46
  979 102 46   979 102 47   979 102 47   979 102 47   979 102 47   979 102 47
  979 102 47   979 102 47   979 102 47   979 102 47   979 102 49   979 102 49
  979 102 49   979 102 49   979 102 49   979 102 49}

do_execsql_test 5.3.11.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST GROUPS 6 PRECEDING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  2309 9 2   2309 9 2   2309 9 2   2309 9 2   2309 9 2   2309 9 2   2309 9 2
  2309 9 2   2309 9 2   2309 9 2   2309 9 2   2309 9 2   2309 9 2   5790 22 3
  5790 22 3   5790 22 3   5790 22 3   5790 22 3   5790 22 3   7156 28 4
  7156 28 4   7156 28 4   7156 28 4   7156 28 4   7156 28 4   7156 28 4
  8960 35 5   8960 35 5   8960 35 5   8960 35 5   8960 35 5   10028 68 9
  10028 68 9   10028 68 9   10028 68 9   10028 68 9   10028 68 9   10028 68 9
  10396 59 8   10396 59 8   10396 59 8   10396 59 8   10396 59 8   10396 59 8
  10396 59 8   10396 59 8   10396 59 8   10479 40 6   10479 40 6   10479 40 6
  10479 40 6   10479 40 6   10479 40 6   10479 40 6   10479 40 6   10479 40 6
  10479 40 6   10479 40 6   11002 75 10   11002 75 10   11002 75 10
  11002 75 10   11002 75 10   11002 75 10   11002 75 10   11002 75 10
  11002 75 10   11441 51 7   11441 51 7   11441 51 7   11441 51 7
  11441 51 7   11441 51 7   11441 51 7   11441 51 7   12145 84 11
  12145 84 11   12145 84 11   12145 84 11   12145 84 11   12145 84 11}

do_execsql_test 5.3.12.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   158 158 1   160 160 1   160 160 1   223 223 1   224 224 1
  238 234 2   239 234 2   239 238 2   252 250 2   256 252 2   257 247 4
  257 247 4   257 250 3   335 330 2   336 330 2   336 335 2   354 354 1
  354 354 1   355 355 1   398 393 3   398 393 3   399 393 3   399 398 2
  399 398 2   572 572 1   574 574 1   633 629 2   634 627 3   634 627 3
  634 627 3   634 629 3   667 667 1   670 667 2   671 667 2   671 670 2
  671 670 2   711 711 1   711 711 1   716 705 2   726 726 1   730 730 1
  762 762 1   762 762 1   762 762 1   768 759 3   792 790 2   792 790 2
  794 786 3   794 786 3   844 839 4   845 839 4   845 839 4   845 840 3
  845 840 3   934 934 1   934 934 1   934 934 1   938 929 3   959 959 1
  963 963 1}

do_execsql_test 5.3.12.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 2 2   {} 2 2   {} 4 3   {} 5 4   {} 6 5   {} 6 5   {} 8 6
  {} 9 7   {} 10 8   {} 14 12   {} 15 13   {} 19 17   {} 20 18   {} 21 19
  {} 23 21   {} 25 23   {} 27 25   {} 27 25   {} 34 29   {} 35 30   {} 36 31
  {} 37 32   {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 42 36   {} 43 37
  {} 43 37   {} 50 42   {} 56 47   {} 60 51   {} 61 52   {} 62 53   {} 64 55
  {} 64 55   {} 66 56   {} 67 57   {} 68 58   {} 69 59   {} 70 60   {} 71 61
  {} 72 62   {} 78 67   {} 78 67   {} 78 67   {} 81 68   {} 82 69   {} 83 70
  {} 85 72   {} 85 72   {} 89 75   223 11 9   239 12 10   239 13 11
  257 18 16   335 22 20   335 24 22   504 16 14   504 17 15   671 52 44
  671 52 44   705 58 49   710 26 24   711 57 48   711 59 50   759 63 54
  786 32 28   786 32 28   798 29 26   798 29 26   845 73 63   845 73 63
  929 84 71   959 88 74   963 87 73   1260 46 39   1260 46 39   1334 51 43
  1334 55 46   1584 31 27   1678 77 66   1885 48 40   1891 45 38   1891 49 41
  2005 54 45   2523 75 64   2523 76 65}

do_execsql_test 5.3.13.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0
  {} {} 0   {} {} 0   {} {} 0   {} {} 0   {} {} 0}

do_execsql_test 5.3.13.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 2 2   {} 2 2   {} 4 3   {} 5 4   {} 6 5   {} 6 5   {} 8 6
  {} 9 7   {} 10 8   {} 11 9   {} 12 10   {} 13 11   {} 14 12   {} 15 13
  {} 16 14   {} 17 15   {} 18 16   {} 19 17   {} 20 18   {} 21 19   {} 22 20
  {} 23 21   {} 24 22   {} 25 23   {} 26 24   {} 27 25   {} 27 25   {} 29 26
  {} 29 26   {} 31 27   {} 32 28   {} 32 28   {} 34 29   {} 35 30   {} 36 31
  {} 37 32   {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 42 36   {} 43 37
  {} 43 37   {} 45 38   {} 46 39   {} 46 39   {} 48 40   {} 49 41   {} 50 42
  {} 51 43   {} 52 44   {} 52 44   {} 54 45   {} 55 46   {} 56 47   {} 57 48
  {} 58 49   {} 59 50   {} 60 51   {} 61 52   {} 62 53   {} 63 54   {} 64 55
  {} 64 55   {} 66 56   {} 67 57   {} 68 58   {} 69 59   {} 70 60   {} 71 61
  {} 72 62   {} 73 63   {} 73 63   {} 75 64   {} 76 65   {} 77 66   {} 78 67
  {} 78 67   {} 78 67   {} 81 68   {} 82 69   {} 83 70   {} 84 71   {} 85 72
  {} 85 72   {} 87 73   {} 88 74   {} 89 75}

do_execsql_test 5.3.14.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {963 929 6   979 102 82   979 102 82   979 102 82   979 102 82   979 102 82
  979 102 83   979 113 80   979 113 81   979 113 82   979 133 79   979 148 78
  979 158 76   979 158 77   979 160 76   979 208 75   979 223 74   979 224 73
  979 234 72   979 238 71   979 239 70   979 247 69   979 250 68   979 252 67
  979 256 66   979 257 65   979 295 64   979 309 63   979 330 63   979 335 61
  979 336 60   979 346 59   979 354 58   979 355 56   979 355 58   979 393 55
  979 393 56   979 398 54   979 399 52   979 399 53   979 412 52   979 421 51
  979 430 50   979 443 49   979 480 47   979 480 48   979 572 46   979 574 46
  979 607 44   979 618 42   979 618 43   979 627 41   979 629 40   979 629 40
  979 633 39   979 634 38   979 652 37   979 660 36   979 667 34   979 667 35
  979 670 34   979 671 33   979 683 32   979 705 31   979 711 30   979 716 29
  979 726 28   979 730 27   979 759 26   979 762 25   979 768 23   979 768 24
  979 777 22   979 786 21   979 790 20   979 792 19   979 794 18   979 805 17
  979 822 16   979 839 15   979 839 15   979 840 13   979 844 12   979 845 11
  979 870 8   979 870 9   979 870 10   979 899 8   979 911 7}

do_execsql_test 5.3.14.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE GROUP  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {2851 89 89   3778 88 88   4681 87 87   5556 83 83   5574 82 82   5586 81 81
  5640 84 84   5640 85 85   5640 86 86   7324 80 80   8123 77 77   8129 73 73
  8129 74 74   8163 78 78   8163 79 79   8940 71 71   8968 75 75   8968 76 76
  9727 66 66   9745 69 69   9745 70 70   9745 72 72   10504 65 65
  10504 67 67   10504 68 68   11215 64 64   11844 62 62   11920 63 63
  13274 60 60   13274 61 61   13897 58 58   13903 57 57   13925 56 56
  13937 55 55   13941 59 59   15203 53 53   15241 54 54   15832 52 52
5536
5537
5538
5539
5540
5541
5542
5543

5544
5545
5546
5547
5548
5549
5550
4527
4528
4529
4530
4531
4532
4533

4534
4535
4536
4537
4538
4539
4540
4541







-
+








do_execsql_test 5.4.1.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {102 102 1   113 113 1   113 113 1   133 133 1   148 148 1   158 158 0
  158 158 1   160 160 1   208 208 1   223 223 1   224 224 1   234 234 1
  238 238 1   239 239 1   247 247 1   250 250 1   252 252 1   256 256 1
  257 257 1   295 295 1   309 309 1   330 330 1   335 335 1   336 336 1
  346 346 1   354 354 1   355 355 0   355 355 1   393 393 1   393 393 1
  398 398 1   399 399 0   399 399 1   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 1   480 480 1   572 572 1   574 574 1   607 607 1
5559
5560
5561
5562
5563
5564
5565
5566

5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585

5586
5587

5588
5589
5590
5591
5592
5593
5594
4550
4551
4552
4553
4554
4555
4556

4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575

4576
4577

4578
4579
4580
4581
4582
4583
4584
4585







-
+


















-
+

-
+








do_execsql_test 5.4.1.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  113 1 1   113 1 1   133 1 1   223 1 1   239 1 1   247 1 1   257 1 1
  295 1 1   309 1 1   335 1 1   355 1 1   355 1 1   393 1 1   393 1 1
  399 1 1   399 1 1   421 1 1   443 1 1   607 1 1   627 1 1   629 1 1
  629 1 1   633 1 1   667 1 1   667 1 1   671 1 1   683 1 1   705 1 1
  711 1 1   759 1 1   777 1 1   805 1 1   839 1 1   839 1 1   845 1 1
  899 1 1   911 1 1   929 1 1   959 1 1   963 1 1   979 1 1}

do_execsql_test 5.4.2.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST 
      WINDOW win AS (  ORDER BY a  
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {113 113 1   234 234 1   257 257 1   336 336 1   354 354 1   768 768 1
  839 839 1   839 839 1   899 113 10   899 113 10   899 113 10   899 113 10
  899 113 10   899 113 10   899 113 10   899 113 17   899 113 17   899 113 17
  899 113 17   899 113 17   899 113 17   899 113 17   899 899 1   963 113 17
  979 102 34   979 102 45   979 102 45   979 102 45   979 102 45   979 102 45
  979 102 50   979 102 50   979 102 50   979 102 50   979 102 50   979 102 50
  979 102 50   979 102 57   979 102 57   979 102 57   979 102 57   979 102 57
5602
5603
5604
5605
5606
5607
5608
5609

5610
5611

5612
5613
5614
5615
5616
5617
5618
4593
4594
4595
4596
4597
4598
4599

4600
4601

4602
4603
4604
4605
4606
4607
4608
4609







-
+

-
+







  979 113 34   979 113 34   979 113 34   979 113 34   979 113 34}

do_execsql_test 5.4.2.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST 
      WINDOW win AS (  ORDER BY a  
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} 81 11   {} 81 11   {} 81 11   {} 81 11   113 81 11   257 81 11
  839 81 11   839 81 11   899 81 11   2947 74 10   2947 74 10   2947 74 10
  3368 74 10   3390 74 10   3618 74 10   3752 74 10   5287 65 9   5287 65 9
  5287 65 9   5287 65 9   5420 65 9   5642 65 9   5970 65 9   6250 65 9
  6266 65 9   8400 57 8   8400 57 8   8400 57 8   8400 57 8   8400 57 8
  8400 57 8   8735 57 8   9329 57 8   9664 46 7   9664 46 7   9664 46 7
  9664 46 7   9664 46 7   9664 46 7   9664 46 7   9664 46 7   9664 46 7
5628
5629
5630
5631
5632
5633
5634
5635

5636
5637
5638
5639
5640
5641
5642
4619
4620
4621
4622
4623
4624
4625

4626
4627
4628
4629
4630
4631
4632
4633







-
+







do_execsql_test 5.4.3.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {102 102 1   113 113 1   113 113 1   133 133 1   148 148 1   158 158 0
  158 158 1   160 160 1   208 208 1   223 223 1   224 224 1   234 234 1
  238 238 1   239 239 1   247 247 1   250 250 1   252 252 1   256 256 1
  257 257 1   295 295 1   309 309 1   330 330 1   335 335 1   336 336 1
  346 346 1   354 354 1   355 355 0   355 355 1   393 393 1   393 393 1
  398 398 1   399 399 0   399 399 1   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 1   480 480 1   572 572 1   574 574 1   607 607 1
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
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
4673
4674
4675
4676
4677







-
+


















-
-
+
+







do_execsql_test 5.4.3.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  113 1 1   113 1 1   133 1 1   223 1 1   239 1 1   247 1 1   257 1 1
  295 1 1   309 1 1   335 1 1   355 1 1   355 1 1   393 1 1   393 1 1
  399 1 1   399 1 1   421 1 1   443 1 1   607 1 1   627 1 1   629 1 1
  629 1 1   633 1 1   667 1 1   667 1 1   671 1 1   683 1 1   705 1 1
  711 1 1   759 1 1   777 1 1   805 1 1   839 1 1   839 1 1   845 1 1
  899 1 1   911 1 1   929 1 1   959 1 1   963 1 1   979 1 1}

do_execsql_test 5.4.4.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST GROUPS 6 PRECEDING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY a  GROUPS 6 PRECEDING   EXCLUDE TIES  )
      ORDER BY 1 , 2 , 3
} {158 158 0   355 355 0   399 399 0   629 629 0   667 667 0   870 158 1
  870 158 1   870 158 1   870 158 1   870 158 1   870 158 1   870 870 0
  911 158 1   934 158 1   934 158 9   934 158 9   934 158 9   934 158 9
  934 158 9   934 158 9   934 158 9   934 158 9   934 158 9   934 158 9
  934 158 9   934 158 9   934 158 9   934 158 22   934 158 22   934 158 22
  934 158 22   934 158 22   934 158 22   934 158 28   934 158 28   934 158 28
  934 158 28   934 158 28   934 158 28   959 102 40   959 102 51   959 102 51
5694
5695
5696
5697
5698
5699
5700
5701
5702


5703
5704
5705
5706
5707
5708
5709
4685
4686
4687
4688
4689
4690
4691


4692
4693
4694
4695
4696
4697
4698
4699
4700







-
-
+
+







  979 102 48   979 102 48   979 102 48   979 102 48   979 102 51}

do_execsql_test 5.4.4.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS FIRST GROUPS 6 PRECEDING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY a  GROUPS 6 PRECEDING   EXCLUDE TIES  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 1 1   355 1 1   399 1 1   629 1 1   667 1 1   2050 7 2
  2050 7 2   2050 7 2   2273 7 2   2289 7 2   2359 7 2   2677 7 2   2961 7 2
  4359 15 3   4359 15 3   4359 15 3   4359 15 3   4359 15 3   4359 15 3
  4606 15 3   4752 15 3   4752 15 3   4758 15 3   4992 15 3   5064 15 3
  5070 15 3   7840 28 4   7840 28 4   7840 28 4   7840 28 4   8447 28 4
  8599 28 4   9206 34 5   9206 34 5   9206 34 5   9206 34 5   9206 34 5
  10028 74 10   10028 74 10   10028 74 10   10051 34 5   10165 34 5
5718
5719
5720
5721
5722
5723
5724
5725
5726


5727
5728
5729
5730
5731
5732
5733
4709
4710
4711
4712
4713
4714
4715


4716
4717
4718
4719
4720
4721
4722
4723
4724







-
-
+
+







  12529 46 7   12529 46 7   12824 46 7   13196 46 7}

do_execsql_test 5.4.5.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 , 2 , 3
} {102 102 1   113 113 1   113 113 1   133 133 1   148 148 1   160 158 1
  160 158 2   160 158 2   208 208 1   224 223 2   224 223 2   239 234 3
  239 234 3   239 234 3   252 247 3   257 247 5   257 247 5   257 250 4
  257 252 3   295 295 1   309 309 1   336 330 3   336 330 3   336 330 3
  346 346 1   355 354 1   355 354 2   355 354 2   399 393 3   399 393 3
  399 393 3   399 393 4   399 393 4   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 1   480 480 1   574 572 2   574 572 2   607 607 1
5741
5742
5743
5744
5745
5746
5747
5748
5749


5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771


5772
5773
5774
5775
5776
5777
5778
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







-
-
+
+




















-
-
+
+







  938 934 2   938 934 2   963 959 2   963 959 2   979 979 1}

do_execsql_test 5.4.5.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 25 23   {} 34 29
  {} 36 31   {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 43 37   {} 43 37
  {} 50 42   {} 60 51   {} 61 52   {} 64 55   {} 64 55   {} 67 57   {} 68 58
  {} 69 59   {} 70 60   {} 72 62   {} 78 67   {} 78 67   {} 78 67   {} 85 72
  {} 85 72   113 2 2   113 2 2   133 4 3   223 10 8   223 11 9   239 12 10
  239 13 11   239 14 12   247 15 13   257 18 16   257 19 17   295 20 18
  309 21 19   335 22 20   335 23 21   335 24 22   355 27 25   355 27 25
  421 35 30   443 37 32   504 16 14   504 17 15   607 42 36   683 56 47
  710 26 24   711 59 50   759 62 53   759 63 54   777 66 56   805 71 61
  899 81 68   911 82 69   929 83 70   929 84 71   979 89 75   1185 32 28
  1185 32 28   1191 29 26   1191 29 26   1334 51 43   1338 52 44   1338 52 44
  1416 57 48   1416 58 49   1584 31 27   1684 73 63   1684 73 63   1889 46 39
  1889 46 39   1891 49 41   1922 87 73   1922 88 74   2005 54 45   2005 55 46
  2518 45 38   2518 48 40   2523 75 64   2523 76 65   2523 77 66}

do_execsql_test 5.4.6.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 , 2 , 3
} {102 102 1   113 113 1   113 113 1   133 133 1   148 148 1   158 158 0
  158 158 1   160 160 1   208 208 1   223 223 1   224 224 1   234 234 1
  238 238 1   239 239 1   247 247 1   250 250 1   252 252 1   256 256 1
  257 257 1   295 295 1   309 309 1   330 330 1   335 335 1   336 336 1
  346 346 1   354 354 1   355 355 0   355 355 1   393 393 1   393 393 1
  398 398 1   399 399 0   399 399 1   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 1   480 480 1   572 572 1   574 574 1   607 607 1
5786
5787
5788
5789
5790
5791
5792
5793
5794


5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815

5816
5817

5818
5819
5820
5821
5822
5823
5824
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







-
-
+
+




















-
+

-
+







  938 938 1   938 938 1   959 959 1   963 963 1   979 979 1}

do_execsql_test 5.4.6.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      WINDOW win AS (  ORDER BY c  RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 , 2 , 3
} {{} 1 1   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 11 9   {} 12 10
  {} 13 11   {} 16 14   {} 17 15   {} 18 16   {} 22 20   {} 24 22   {} 25 23
  {} 26 24   {} 31 27   {} 34 29   {} 36 31   {} 38 33   {} 38 33   {} 40 34
  {} 41 35   {} 43 37   {} 43 37   {} 49 41   {} 50 42   {} 51 43   {} 54 45
  {} 59 50   {} 60 51   {} 61 52   {} 63 54   {} 64 55   {} 64 55   {} 67 57
  {} 68 58   {} 69 59   {} 70 60   {} 72 62   {} 75 64   {} 76 65   {} 78 67
  {} 78 67   {} 78 67   {} 84 71   {} 85 72   {} 85 72   113 2 2   113 2 2
  133 4 3   223 10 8   239 14 12   247 15 13   257 19 17   295 20 18
  309 21 19   335 23 21   355 27 25   355 27 25   393 29 26   393 29 26
  399 32 28   399 32 28   421 35 30   443 37 32   607 42 36   627 45 38
  629 46 39   629 46 39   633 48 40   667 52 44   667 52 44   671 55 46
  683 56 47   705 57 48   711 58 49   759 62 53   777 66 56   805 71 61
  839 73 63   839 73 63   845 77 66   899 81 68   911 82 69   929 83 70
  959 87 73   963 88 74   979 89 75}

do_execsql_test 5.4.7.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
      WINDOW win AS (  ORDER BY c , b , a 
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 113 81   979 113 82   979 133 80   979 148 79   979 158 77
  979 158 78   979 160 77   979 208 76   979 223 75   979 224 74   979 234 73
  979 238 72   979 239 71   979 247 70   979 250 69   979 252 68   979 256 67
  979 257 66   979 295 65   979 309 64   979 330 63   979 335 62   979 336 61
  979 346 60   979 354 59   979 355 58   979 355 58   979 393 56   979 393 57
  979 398 55   979 399 54   979 399 54   979 412 53   979 421 52   979 430 51
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
5878
5879
5880
5881
5882
5883
5884
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
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
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
6082
6083
6084
6085
6086
6087
6088
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
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
4823
4824
4825
4826
4827
4828
4829






































































4830





































































































































































































































4831

4832
























4833
4834
4835
4836
4837
4838
4839







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  979 870 11   979 870 11   979 899 9   979 911 8   979 929 7}

do_execsql_test 5.4.7.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {3830 89 89   4741 88 88   5640 84 84   5640 85 85   5640 86 86   5640 87 87
  6485 81 81   6485 82 82   6485 83 83   7324 80 80   8163 78 78   8163 79 79
  8968 73 73   8968 74 74   8968 75 75   8968 76 76   8968 77 77   9745 69 69
  9745 70 70   9745 71 71   9745 72 72   10504 65 65   10504 66 66
  10504 67 67   10504 68 68   11215 64 64   11920 63 63   12603 62 62
  13274 60 60   13274 61 61   13941 59 59   14608 55 55   14608 56 56
  14608 57 57   14608 58 58   15241 54 54   15870 53 53   16499 52 52
  17126 49 49   17126 50 50   17126 51 51   17733 44 44   17733 45 45
  17733 46 46   17733 47 47   17733 48 48   18176 42 42   18176 43 43
  18597 40 40   18597 41 41   18996 39 39   19395 37 37   19395 38 38
  19788 36 36   20181 35 35   20536 34 34   20891 30 30   20891 31 31
  20891 32 32   20891 33 33   21226 28 28   21226 29 29   21535 27 27
  21830 26 26   22087 22 22   22087 23 23   22087 24 24   22087 25 25
  22334 21 21   22573 17 17   22573 18 18   22573 19 19   22573 20 20
  22796 11 11   22796 12 12   22796 13 13   22796 14 14   22796 15 15
  22796 16 16   22929 10 10   23042 9 9   23155 1 1   23155 2 2   23155 3 3
  23155 4 4   23155 5 5   23155 6 6   23155 7 7   23155 8 8}

do_execsql_test 5.4.8.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {102 102 1   113 113 1   113 113 1   133 133 1   148 148 1   158 158 0
  158 158 1   160 160 1   208 208 1   223 223 1   224 224 1   234 234 1
  238 238 1   239 239 1   247 247 1   250 250 1   252 252 1   256 256 1
  257 257 1   295 295 1   309 309 1   330 330 1   335 335 1   336 336 1
  346 346 1   354 354 1   355 355 0   355 355 1   393 393 1   393 393 1
  398 398 1   399 399 0   399 399 1   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 1   480 480 1   572 572 1   574 574 1   607 607 1
  618 618 1   618 618 1   627 627 1   629 629 0   629 629 1   633 633 1
  634 634 1   652 652 1   660 660 1   667 667 0   667 667 1   670 670 1
  671 671 1   683 683 1   705 705 1   711 711 1   716 716 1   726 726 1
  730 730 1   759 759 1   762 762 1   768 768 1   768 768 1   777 777 1
  786 786 1   790 790 1   792 792 1   794 794 1   805 805 1   822 822 1
  839 839 1   839 839 1   840 840 1   844 844 1   845 845 1   870 870 0
  870 870 1   870 870 1   899 899 1   911 911 1   929 929 1   934 934 1
  938 938 1   938 938 1   959 959 1   963 963 1   979 979 1}

do_execsql_test 5.4.8.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  113 1 1   113 1 1   133 1 1   223 1 1   239 1 1   247 1 1   257 1 1
  295 1 1   309 1 1   335 1 1   355 1 1   355 1 1   393 1 1   393 1 1
  399 1 1   399 1 1   421 1 1   443 1 1   607 1 1   627 1 1   629 1 1
  629 1 1   633 1 1   667 1 1   667 1 1   671 1 1   683 1 1   705 1 1
  711 1 1   759 1 1   777 1 1   805 1 1   839 1 1   839 1 1   845 1 1
  899 1 1   911 1 1   929 1 1   959 1 1   963 1 1   979 1 1}

do_execsql_test 5.4.9.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST 
      WINDOW win AS (  ORDER BY c , b , a 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {158 158 0   355 355 0   399 399 0   629 629 0   667 667 0   870 113 1
  870 158 1   870 158 1   870 158 1   870 158 1   870 158 1   870 158 1
  870 158 1   870 870 0   899 113 10   899 113 10   899 113 10   899 113 10
  899 113 10   899 113 10   899 113 10   899 113 17   899 113 17   899 113 17
  899 113 17   899 113 17   899 113 17   899 113 17   899 158 1   963 113 17
  979 102 34   979 102 45   979 102 45   979 102 45   979 102 45   979 102 45
  979 102 50   979 102 50   979 102 50   979 102 50   979 102 50   979 102 50
  979 102 50   979 102 57   979 102 57   979 102 57   979 102 57   979 102 57
  979 102 57   979 102 63   979 102 63   979 102 63   979 102 63   979 102 63
  979 102 63   979 102 63   979 102 63   979 102 63   979 102 63   979 102 63
  979 102 63   979 102 63   979 102 76   979 102 76   979 102 76   979 102 76
  979 102 76   979 102 76   979 102 76   979 102 76   979 113 17   979 113 26
  979 113 26   979 113 26   979 113 26   979 113 26   979 113 26   979 113 26
  979 113 26   979 113 34   979 113 34   979 113 34   979 113 34   979 113 34
  979 113 34   979 113 34   979 113 34   979 113 34   979 113 34}

do_execsql_test 5.4.9.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 84 11   {} 84 11   355 84 11   399 84 11   629 84 11   667 84 11
  2050 75 10   2050 75 10   2050 75 10   2050 75 10   2163 75 10   2307 75 10
  2889 75 10   2889 75 10   2949 75 10   4997 68 9   4997 68 9   4997 68 9
  5418 68 9   5440 68 9   5668 68 9   5802 68 9   7337 59 8   7337 59 8
  7337 59 8   7337 59 8   7470 59 8   7692 59 8   8020 59 8   8300 59 8
  8316 59 8   10450 51 7   10450 51 7   10450 51 7   10450 51 7   10450 51 7
  10450 51 7   10785 51 7   11379 51 7   11714 40 6   11714 40 6   11714 40 6
  11714 40 6   11714 40 6   11714 40 6   11714 40 6   11714 40 6   11714 40 6
  12009 40 6   12381 40 6   12676 35 5   12676 35 5   12789 35 5   13305 35 5
  13453 35 5   14195 28 4   14195 28 4   14195 28 4   14195 28 4   14195 28 4
  15040 28 4   15154 28 4   15999 22 3   15999 22 3   15999 22 3   15999 22 3
  16606 22 3   16758 22 3   17365 9 2   17365 9 2   17365 9 2   17365 9 2
  17365 9 2   17365 9 2   17612 9 2   17758 9 2   17758 9 2   17764 9 2
  17998 9 2   18070 9 2   18076 9 2   20846 1 1   20846 1 1   20846 1 1
  21069 1 1   21085 1 1   21155 1 1   21473 1 1   21757 1 1}

do_execsql_test 5.4.10.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {102 102 1   113 113 1   113 113 1   133 133 1   148 148 1   158 158 0
  158 158 1   160 160 1   208 208 1   223 223 1   224 224 1   234 234 1
  238 238 1   239 239 1   247 247 1   250 250 1   252 252 1   256 256 1
  257 257 1   295 295 1   309 309 1   330 330 1   335 335 1   336 336 1
  346 346 1   354 354 1   355 355 0   355 355 1   393 393 1   393 393 1
  398 398 1   399 399 0   399 399 1   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 1   480 480 1   572 572 1   574 574 1   607 607 1
  618 618 1   618 618 1   627 627 1   629 629 0   629 629 1   633 633 1
  634 634 1   652 652 1   660 660 1   667 667 0   667 667 1   670 670 1
  671 671 1   683 683 1   705 705 1   711 711 1   716 716 1   726 726 1
  730 730 1   759 759 1   762 762 1   768 768 1   768 768 1   777 777 1
  786 786 1   790 790 1   792 792 1   794 794 1   805 805 1   822 822 1
  839 839 1   839 839 1   840 840 1   844 844 1   845 845 1   870 870 0
  870 870 1   870 870 1   899 899 1   911 911 1   929 929 1   934 934 1
  938 938 1   938 938 1   959 959 1   963 963 1   979 979 1}

do_execsql_test 5.4.10.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  PARTITION BY coalesce(a, '') 
        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1   {} 1 1
  113 1 1   113 1 1   133 1 1   223 1 1   239 1 1   247 1 1   257 1 1
  295 1 1   309 1 1   335 1 1   355 1 1   355 1 1   393 1 1   393 1 1
  399 1 1   399 1 1   421 1 1   443 1 1   607 1 1   627 1 1   629 1 1
  629 1 1   633 1 1   667 1 1   667 1 1   671 1 1   683 1 1   705 1 1
  711 1 1   759 1 1   777 1 1   805 1 1   839 1 1   839 1 1   845 1 1
  899 1 1   911 1 1   929 1 1   959 1 1   963 1 1   979 1 1}

do_execsql_test 5.4.11.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST GROUPS 6 PRECEDING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {223 223 1   239 239 1   309 309 1   572 572 1   627 627 1   870 870 1
  911 911 1   934 158 22   934 158 28   934 158 28   934 158 28   934 158 28
  934 158 28   934 158 28   934 223 9   934 223 9   934 223 9   934 223 9
  934 223 9   934 223 9   934 223 9   934 223 9   934 223 9   934 223 9
  934 223 9   934 223 9   934 223 9   934 223 22   934 223 22   934 223 22
  934 223 22   934 223 22   934 934 1   959 102 40   959 102 51   959 102 51
  959 102 51   959 102 51   959 102 51   959 102 51   959 102 51   959 102 51
  959 102 51   959 102 51   959 102 51   959 102 51   959 102 51   959 102 51
  959 102 51   959 113 35   959 113 40   959 113 40   959 113 40   959 113 40
  959 113 40   959 113 40   959 113 40   959 113 40   959 113 40   959 113 40
  959 158 28   959 158 35   959 158 35   959 158 35   959 158 35   963 102 51
  979 102 47   979 102 47   979 102 47   979 102 47   979 102 47   979 102 47
  979 102 47   979 102 48   979 102 48   979 102 48   979 102 48   979 102 48
  979 102 48   979 102 48   979 102 48   979 102 48   979 102 49   979 102 49
  979 102 49   979 102 49   979 102 49   979 102 49   979 102 51}

do_execsql_test 5.4.11.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY a NULLS LAST GROUPS 6 PRECEDING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 1 1   {} 1 1   223 1 1   239 1 1   309 1 1   627 1 1   911 1 1
  2309 9 2   2309 9 2   2309 9 2   2309 9 2   2309 9 2   2309 9 2   2556 9 2
  2702 9 2   2702 9 2   2708 9 2   2942 9 2   3014 9 2   3020 9 2   5790 22 3
  5790 22 3   5790 22 3   5790 22 3   6397 22 3   6549 22 3   7156 28 4
  7156 28 4   7156 28 4   7156 28 4   7156 28 4   8001 28 4   8115 28 4
  8960 35 5   8960 35 5   9073 35 5   9589 35 5   9737 35 5   10028 68 9
  10028 68 9   10028 68 9   10396 59 8   10396 59 8   10396 59 8   10396 59 8
  10449 68 9   10471 68 9   10479 40 6   10479 40 6   10479 40 6   10479 40 6
  10479 40 6   10479 40 6   10479 40 6   10479 40 6   10479 40 6   10529 59 8
  10699 68 9   10751 59 8   10774 40 6   10833 68 9   11002 75 10
  11002 75 10   11002 75 10   11002 75 10   11079 59 8   11115 75 10
  11146 40 6   11259 75 10   11359 59 8   11375 59 8   11441 51 7
  11441 51 7   11441 51 7   11441 51 7   11441 51 7   11441 51 7   11776 51 7
  11841 75 10   11841 75 10   11901 75 10   12145 84 11   12145 84 11
  12370 51 7   12500 84 11   12544 84 11   12774 84 11   12812 84 11}

do_execsql_test 5.4.12.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {102 102 1   113 113 1   113 113 1   133 133 1   148 148 1   160 158 1
  160 158 2   160 158 2   208 208 1   224 223 2   224 223 2   239 234 3
  239 234 3   239 234 3   252 247 3   257 247 5   257 247 5   257 250 4
  257 252 3   295 295 1   309 309 1   336 330 3   336 330 3   336 330 3
  346 346 1   355 354 1   355 354 2   355 354 2   399 393 3   399 393 3
  399 393 3   399 393 4   399 393 4   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 1   480 480 1   574 572 2   574 572 2   607 607 1
  618 618 1   618 618 1   634 627 3   634 627 4   634 627 4   634 627 4
  634 629 3   652 652 1   667 660 2   671 667 2   671 667 3   671 667 3
  671 667 3   683 683 1   711 705 2   716 705 3   716 711 2   730 726 2
  730 726 2   762 759 2   768 759 4   768 762 2   768 762 2   777 777 1
  792 786 3   794 786 4   794 786 4   794 790 3   805 805 1   822 822 1
  845 839 4   845 839 4   845 839 5   845 839 5   845 839 5   870 870 0
  870 870 1   870 870 1   899 899 1   911 911 1   934 929 2   938 929 4
  938 934 2   938 934 2   963 959 2   963 959 2   979 979 1}

do_execsql_test 5.4.12.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 25 23   {} 34 29
  {} 36 31   {} 38 33   {} 38 33   {} 40 34   {} 41 35   {} 43 37   {} 43 37
  {} 50 42   {} 60 51   {} 61 52   {} 64 55   {} 64 55   {} 67 57   {} 68 58
  {} 69 59   {} 70 60   {} 72 62   {} 78 67   {} 78 67   {} 78 67   {} 85 72
  {} 85 72   113 2 2   113 2 2   133 4 3   223 10 8   223 11 9   239 12 10
  239 13 11   239 14 12   247 15 13   257 18 16   257 19 17   295 20 18
  309 21 19   335 22 20   335 23 21   335 24 22   355 27 25   355 27 25
  421 35 30   443 37 32   504 16 14   504 17 15   607 42 36   683 56 47
  710 26 24   711 59 50   759 62 53   759 63 54   777 66 56   805 71 61
  899 81 68   911 82 69   929 83 70   929 84 71   979 89 75   1185 32 28
  1185 32 28   1191 29 26   1191 29 26   1334 51 43   1338 52 44   1338 52 44
  1416 57 48   1416 58 49   1584 31 27   1684 73 63   1684 73 63   1889 46 39
  1889 46 39   1891 49 41   1922 87 73   1922 88 74   2005 54 45   2005 55 46
  2518 45 38   2518 48 40   2523 75 64   2523 76 65   2523 77 66}

do_execsql_test 5.4.13.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {102 102 1   113 113 1   113 113 1   133 133 1   148 148 1   158 158 0
  158 158 1   160 160 1   208 208 1   223 223 1   224 224 1   234 234 1
  238 238 1   239 239 1   247 247 1   250 250 1   252 252 1   256 256 1
  257 257 1   295 295 1   309 309 1   330 330 1   335 335 1   336 336 1
  346 346 1   354 354 1   355 355 0   355 355 1   393 393 1   393 393 1
  398 398 1   399 399 0   399 399 1   412 412 1   421 421 1   430 430 1
  443 443 1   480 480 1   480 480 1   572 572 1   574 574 1   607 607 1
  618 618 1   618 618 1   627 627 1   629 629 0   629 629 1   633 633 1
  634 634 1   652 652 1   660 660 1   667 667 0   667 667 1   670 670 1
  671 671 1   683 683 1   705 705 1   711 711 1   716 716 1   726 726 1
  730 730 1   759 759 1   762 762 1   768 768 1   768 768 1   777 777 1
  786 786 1   790 790 1   792 792 1   794 794 1   805 805 1   822 822 1
  839 839 1   839 839 1   840 840 1   844 844 1   845 845 1   870 870 0
  870 870 1   870 870 1   899 899 1   911 911 1   929 929 1   934 934 1
  938 938 1   938 938 1   959 959 1   963 963 1   979 979 1}

do_execsql_test 5.4.13.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {{} 1 1   {} 5 4   {} 6 5   {} 6 5   {} 8 6   {} 9 7   {} 11 9   {} 12 10
  {} 13 11   {} 16 14   {} 17 15   {} 18 16   {} 22 20   {} 24 22   {} 25 23
  {} 26 24   {} 31 27   {} 34 29   {} 36 31   {} 38 33   {} 38 33   {} 40 34
  {} 41 35   {} 43 37   {} 43 37   {} 49 41   {} 50 42   {} 51 43   {} 54 45
  {} 59 50   {} 60 51   {} 61 52   {} 63 54   {} 64 55   {} 64 55   {} 67 57
  {} 68 58   {} 69 59   {} 70 60   {} 72 62   {} 75 64   {} 76 65   {} 78 67
  {} 78 67   {} 78 67   {} 84 71   {} 85 72   {} 85 72   113 2 2   113 2 2
  133 4 3   223 10 8   239 14 12   247 15 13   257 19 17   295 20 18
  309 21 19   335 23 21   355 27 25   355 27 25   393 29 26   393 29 26
  399 32 28   399 32 28   421 35 30   443 37 32   607 42 36   627 45 38
  629 46 39   629 46 39   633 48 40   667 52 44   667 52 44   671 55 46
  683 56 47   705 57 48   711 58 49   759 62 53   777 66 56   805 71 61
  839 73 63   839 73 63   845 77 66   899 81 68   911 82 69   929 83 70
  959 87 73   963 88 74   979 89 75}

do_execsql_test 5.4.14.1 {
  SELECT max(c) OVER win,
             min(c) OVER win,
             count(a) OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
      ORDER BY 1 , 2 , 3
} {979 102 83   979 102 83   979 102 83   979 102 83   979 102 83   979 102 83
  979 102 83   979 113 81   979 113 82   979 133 80   979 148 79   979 158 77
  979 158 78   979 160 77   979 208 76   979 223 75   979 224 74   979 234 73
  979 238 72   979 239 71   979 247 70   979 250 69   979 252 68   979 256 67
  979 257 66   979 295 65   979 309 64   979 330 63   979 335 62   979 336 61
  979 346 60   979 354 59   979 355 57   979 355 58   979 393 56   979 393 57
  979 398 55   979 399 53   979 399 54   979 412 53   979 421 52   979 430 51
  979 443 50   979 480 48   979 480 49   979 572 47   979 574 46   979 607 45
  979 618 43   979 618 44   979 627 42   979 629 40   979 629 41   979 633 40
  979 634 39   979 652 38   979 660 37   979 667 35   979 667 36   979 670 35
  979 671 34   979 683 33   979 705 32   979 711 31   979 716 30   979 726 29
  979 730 28   979 759 27   979 762 26   979 768 24   979 768 25   979 777 23
  979 786 22   979 790 21   979 792 20   979 794 19   979 805 18   979 822 17
  979 839 15   979 839 16   979 840 14   979 844 13   979 845 12   979 870 9
  979 870 10   979 870 11   979 899 9   979 911 8   979 929 7}

do_execsql_test 5.4.14.2 {
  SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
             rank() OVER win,
             dense_rank() OVER win
      FROM t3
      WINDOW win AS (  ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST
        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING   EXCLUDE TIES  )
      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
} {3830 89 89   4741 88 88   5640 84 84   5640 85 85   5640 86 86   5640 87 87
  6485 81 81   6485 82 82   6485 83 83   7324 80 80   8163 78 78   8163 79 79
  8968 73 73   8968 74 74   8968 75 75   8968 76 76   8968 77 77   9745 69 69
  9745 70 70   9745 71 71   9745 72 72   10504 65 65   10504 66 66
  10504 67 67   10504 68 68   11215 64 64   11920 63 63   12603 62 62
  13274 60 60   13274 61 61   13941 59 59   14608 55 55   14608 56 56
  14608 57 57   14608 58 58   15241 54 54   15870 53 53   16499 52 52
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
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
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
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
4856
4857
4858
4859
4860
4861
4862

4863
4864
4865
4866
4867
4868
4869

4870
4871
4872
4873
4874










































































































































































































































































4875







-
+






-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  INSERT INTO t2 VALUES('A', NULL);
  INSERT INTO t2 VALUES('B', NULL);
  INSERT INTO t2 VALUES('C', 1);
} {}

do_execsql_test 6.1 {
  SELECT group_concat(a, '.') OVER (
    ORDER BY b NULLS FIRST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING
    ORDER BY b  RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING
  )
  FROM t2
} {A.B   A.B   {}}

do_execsql_test 6.2 {
  SELECT group_concat(a, '.') OVER (
    ORDER BY b DESC NULLS LAST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING
    ORDER BY b DESC  RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING
  )
  FROM t2
} {{}   A.B   A.B}

#==========================================================================

do_execsql_test 7.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER, b INTEGER);

  INSERT INTO t2 VALUES(1, 65);
  INSERT INTO t2 VALUES(2, NULL);
  INSERT INTO t2 VALUES(3, NULL);
  INSERT INTO t2 VALUES(4, NULL);
  INSERT INTO t2 VALUES(5, 66);
  INSERT INTO t2 VALUES(6, 67);
} {}

do_execsql_test 7.1.1 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING
  );
} {9   9   9   9   9   9}

do_execsql_test 7.1.2 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
} {{}   {}   {}   9   9   9}

do_execsql_test 7.1.3 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
} {{}   {}   {}   9   9   9}

do_execsql_test 7.1.4 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
} {9   9   9   {}   {}   {}}

do_execsql_test 7.1.5 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
} {9   9   9   {}   {}   {}}

do_execsql_test 7.1.6 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING
  );
} {{}   {}   1   9   9   9}

do_execsql_test 7.1.7 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
} {{}   {}   {}   9   9   9}

do_execsql_test 7.1.8 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING
  );
} {9   9   9   {}   {}   {}}

do_execsql_test 7.1.9 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
} {9   9   9   {}   {}   {}}

do_execsql_test 7.2.1 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING
  );
} {2   2   2   2   2   2}

do_execsql_test 7.2.2 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
} {{}   {}   {}   2   2   2}

do_execsql_test 7.2.3 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
} {{}   {}   {}   2   2   2}

do_execsql_test 7.2.4 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
} {2   2   2   {}   {}   {}}

do_execsql_test 7.2.5 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
} {2   2   2   {}   {}   {}}

do_execsql_test 7.2.6 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING
  );
} {{}   {}   1   2   2   2}

do_execsql_test 7.2.7 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
} {{}   {}   {}   2   2   2}

do_execsql_test 7.2.8 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING
  );
} {2   2   2   {}   {}   {}}

do_execsql_test 7.2.9 {
  SELECT min (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
} {2   2   2   {}   {}   {}}

do_execsql_test 7.3.1 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING
  );
} {9   9   9   9   9   9}

do_execsql_test 7.3.2 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
} {{}   {}   {}   9   9   9}

do_execsql_test 7.3.3 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
} {{}   {}   {}   9   9   9}

do_execsql_test 7.3.4 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
} {9   9   9   {}   {}   {}}

do_execsql_test 7.3.5 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
} {9   9   9   {}   {}   {}}

do_execsql_test 7.3.6 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING
  );
} {{}   {}   1   9   9   9}

do_execsql_test 7.3.7 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
} {{}   {}   {}   9   9   9}

do_execsql_test 7.3.8 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING
  );
} {9   9   9   {}   {}   {}}

do_execsql_test 7.3.9 {
  SELECT sum (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
} {9   9   9   {}   {}   {}}

do_execsql_test 7.4.1 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING
  );
} {4   4   4   4   4   4}

do_execsql_test 7.4.2 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
} {{}   {}   {}   4   4   4}

do_execsql_test 7.4.3 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
} {{}   {}   {}   4   4   4}

do_execsql_test 7.4.4 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING
  );
} {4   4   4   {}   {}   {}}

do_execsql_test 7.4.5 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING
  );
} {4   4   4   {}   {}   {}}

do_execsql_test 7.4.6 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING
  );
} {{}   {}   1   4   4   4}

do_execsql_test 7.4.7 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
} {{}   {}   {}   4   4   4}

do_execsql_test 7.4.8 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING
  );
} {4   4   4   {}   {}   {}}

do_execsql_test 7.4.9 {
  SELECT max (a) OVER win FROM t2
  WINDOW win AS (
      ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING
  );
} {4   4   4   {}   {}   {}}

finish_test

Deleted test/window9.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





























































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 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.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window9

ifcapable !windowfunc {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE fruits(
     name TEXT COLLATE NOCASE,
     color TEXT COLLATE NOCASE
  );
}

do_execsql_test 1.1 {
  INSERT INTO fruits (name, color) VALUES ('apple', 'RED');
  INSERT INTO fruits (name, color) VALUES ('APPLE', 'yellow');
  INSERT INTO fruits (name, color) VALUES ('pear', 'YELLOW');
  INSERT INTO fruits (name, color) VALUES ('PEAR', 'green');
}

do_execsql_test 1.2 {
  SELECT name, color, dense_rank() OVER (ORDER BY name) FROM fruits;
} {
  apple RED    1
  APPLE yellow 1
  pear  YELLOW 2
  PEAR  green  2
}

do_execsql_test 1.3 {
  SELECT name, color,
    dense_rank() OVER (PARTITION BY name ORDER BY color)
  FROM fruits;
} {
  apple RED    1 
  APPLE yellow 2 
  PEAR green   1 
  pear YELLOW  2
}

do_execsql_test 1.4 {
  SELECT name, color,
    dense_rank() OVER (ORDER BY name),
    dense_rank() OVER (PARTITION BY name ORDER BY color)
  FROM fruits;
} {
  apple RED    1 1 
  APPLE yellow 1 2 
  PEAR  green  2 1 
  pear  YELLOW 2 2
}

do_execsql_test 1.5 {
  SELECT name, color,
    dense_rank() OVER (ORDER BY name),
    dense_rank() OVER (PARTITION BY name ORDER BY color)
  FROM fruits ORDER BY color;
} {
  PEAR  green  2 1 
  apple RED    1 1 
  APPLE yellow 1 2 
  pear  YELLOW 2 2
}

do_execsql_test 2.0 {
  CREATE TABLE t1(a BLOB, b INTEGER, c COLLATE nocase);
  INSERT INTO t1 VALUES(1, 2, 'abc');
  INSERT INTO t1 VALUES(3, 4, 'ABC');
}

do_execsql_test 2.1.1 {
  SELECT c=='Abc' FROM t1
} {1     1}
do_execsql_test 2.1.2 {
  SELECT c=='Abc', rank() OVER (ORDER BY b) FROM t1
} {1 1   1 2}

do_execsql_test 2.2.1 {
  SELECT b=='2' FROM t1
} {1     0}
do_execsql_test 2.2.2 {
  SELECT b=='2', rank() OVER (ORDER BY a) FROM t1
} {1 1   0 2}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t1(a);
  CREATE TABLE t2(a,b,c);
}

do_execsql_test 3.1 {
  SELECT EXISTS(SELECT 1 FROM t1 ORDER BY sum(a) OVER ()) FROM t1;
}

do_execsql_test 3.2 {
  SELECT sum(a) OVER () FROM t2
   ORDER BY EXISTS(SELECT 1 FROM t2 ORDER BY sum(a) OVER ());
}

do_catchsql_test 3.3 {
  SELECT a, sum(a) OVER (ORDER BY a DESC) FROM t2 
  ORDER BY EXISTS(
    SELECT 1 FROM t2 ORDER BY sum(a) OVER (ORDER BY a)
  ) OVER (ORDER BY a);
} {1 {near "OVER": syntax error}}

do_catchsql_test 3.4 {
  SELECT y, y+1, y+2 FROM (
      SELECT c IN (
        SELECT min(a) OVER (),
        (abs(row_number() OVER())+22)/19,
        max(a) OVER () FROM t1
        ) AS y FROM t2
      );
} {1 {sub-select returns 3 columns - expected 1}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE TABLE t1(a, b TEXT);
  INSERT INTO t1 VALUES('A', 1), ('A', 2), ('2', 1), ('2', 2);
}

do_execsql_test 4.1.1 {
  SELECT b, b=count(*), '1,2'                   FROM t1 GROUP BY b;
} {1 0 1,2 2 1 1,2}
do_execsql_test 4.1.2 {
  SELECT b, b=count(*), group_concat(b) OVER () FROM t1 GROUP BY b;
} {1 0 1,2 2 1 1,2}

#--------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  CREATE TABLE t1(a, b, c, d, e);
  CREATE INDEX i1 ON t1(a, b, c, d, e);
}

foreach {tn sql} {
  1 {
    SELECT 
      sum(e) OVER (),
      sum(e) OVER (ORDER BY a),
      sum(e) OVER (PARTITION BY a ORDER BY b),
      sum(e) OVER (PARTITION BY a, b ORDER BY c),
      sum(e) OVER (PARTITION BY a, b, c ORDER BY d)
    FROM t1;
  }
  2 {
    SELECT sum(e) OVER (PARTITION BY a ORDER BY b) FROM t1 ORDER BY a;
  }
} {
  do_test 5.1.$tn {
    execsql "EXPLAIN QUERY PLAN $sql"
  } {~/ORDER/}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES (0);
}

do_execsql_test 6.1 {
  SELECT * FROM t0 WHERE 
  EXISTS (
    SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0
  ) >=1 AND 
  EXISTS (
    SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0
  ) <=1;
} {0}

do_execsql_test 6.2 {
  SELECT * FROM t0 WHERE EXISTS (
    SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0
  ) 
  BETWEEN 1 AND 1;
} {0}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x, y);
  INSERT INTO t1 VALUES(10, 1);
  INSERT INTO t1 VALUES(20, 2);
  INSERT INTO t1 VALUES(3, 3);
  INSERT INTO t1 VALUES(2, 4);
  INSERT INTO t1 VALUES(1, 5);
} {}


do_execsql_test 7.1 {
  SELECT avg(x) OVER (ORDER BY y) AS z FROM t1 ORDER BY z
} {
  7.2 8.75 10.0 11.0 15.0
}

do_execsql_test 7.2 {
  SELECT avg(x) OVER (ORDER BY y) z FROM t1 ORDER BY (z IS y);
} {
  10.0 15.0 11.0 8.75 7.2
}

do_execsql_test 7.3 {
  SELECT avg(x) OVER (ORDER BY y) z FROM t1 ORDER BY (y IS z);
} {
  10.0 15.0 11.0 8.75 7.2
}

do_execsql_test 7.4 {
  SELECT avg(x) OVER (ORDER BY y) z FROM t1 ORDER BY z + 0.0;
} {
  7.2 8.75 10.0 11.0 15.0
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 8.1.1 {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, 2), (3, 4);
  SELECT min( sum(a) ) OVER () FROM t1;
} {4}

do_execsql_test 8.1.2 {
  SELECT min( sum(a) ) OVER () FROM t1 GROUP BY a;
} {1 1}

do_execsql_test 8.2 {
  CREATE VIEW v1 AS 
    SELECT 0 AS x
      UNION 
    SELECT count() OVER() FROM (SELECT 0) 
    ORDER BY 1
  ;
}

do_catchsql_test 8.3 {
  SELECT min( max((SELECT x FROM v1)) ) OVER()
} {0 0}

do_execsql_test 8.4 {
  SELECT(
      SELECT x UNION 
      SELECT sum( avg((SELECT x FROM v1)) ) OVER()
  )
  FROM v1;
} {0.0 0.0}

#--------------------------------------------------------------------------
reset_db
do_execsql_test 9.0 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(NULL,'bb',356);
  INSERT INTO t1 VALUES('CB','aa',158);
  INSERT INTO t1 VALUES('BB','aa',399);
  INSERT INTO t1 VALUES('FF','bb',938);
}

do_catchsql_test 9.1 {
  SELECT sum(c) OVER (
    ORDER BY c RANGE BETWEEN 0 PRECEDING AND '-700' PRECEDING
  )
  FROM t1
} {1 {frame ending offset must be a non-negative number}}

finish_test

Deleted test/windowA.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





















































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-08-30
#
# 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 RANGE BETWEEN and especially with NULLS LAST
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix windowA

ifcapable !windowfunc {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b CHAR(1), d FLOAT);
  INSERT INTO t1 VALUES
   (1, 'A', 5.4),
   (2, 'B', 5.55),
   (3, 'C', 8.0),
   (4, 'D', 10.25),
   (5, 'E', 10.26),
   (6, 'N', NULL),
   (7, 'N', NULL);
} {}

do_execsql_test 1.1 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS LAST
      RANGE BETWEEN 2.50 PRECEDING AND 2.25 FOLLOWING)
  ORDER BY +d DESC NULLS LAST, +a;
} [list \
  5 E 10.26 ED   \
  4 D 10.25 EDC  \
  3 C   8.0 EDC  \
  2 B  5.55 CBA  \
  1 A   5.4 BA   \
  6 N  NULL NN   \
  7 N  NULL NN   \
]

do_execsql_test 1.2 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN 2.50 PRECEDING AND 2.25 FOLLOWING)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NN   \
  7 N  NULL NN   \
  5 E 10.26 ED   \
  4 D 10.25 EDC  \
  3 C   8.0 EDC  \
  2 B  5.55 CBA  \
  1 A   5.4 BA   \
]

do_execsql_test 1.3 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS LAST
      RANGE BETWEEN 2.50 PRECEDING AND UNBOUNDED FOLLOWING)
  ORDER BY +d DESC NULLS LAST, +a;
} [list \
  5 E 10.26 EDCBANN  \
  4 D 10.25 EDCBANN  \
  3 C   8.0 EDCBANN  \
  2 B  5.55 CBANN    \
  1 A   5.4 BANN     \
  6 N  NULL NN       \
  7 N  NULL NN       \
]

do_execsql_test 1.4 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN 2.50 PRECEDING AND UNBOUNDED FOLLOWING)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NNEDCBA  \
  7 N  NULL NNEDCBA  \
  5 E 10.26 EDCBA    \
  4 D 10.25 EDCBA    \
  3 C   8.0 EDCBA    \
  2 B  5.55 CBA      \
  1 A   5.4 BA       \
]

do_execsql_test 1.5 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS LAST
      RANGE BETWEEN 2.50 PRECEDING AND CURRENT ROW)
  ORDER BY +d DESC NULLS LAST, +a;
} [list \
  5 E 10.26 E    \
  4 D 10.25 ED   \
  3 C   8.0 EDC  \
  2 B  5.55 CB   \
  1 A   5.4 BA   \
  6 N  NULL NN   \
  7 N  NULL NN   \
]

do_execsql_test 1.6 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN 2.50 PRECEDING AND CURRENT ROW)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NN   \
  7 N  NULL NN   \
  5 E 10.26 E    \
  4 D 10.25 ED   \
  3 C   8.0 EDC  \
  2 B  5.55 CB   \
  1 A   5.4 BA   \
]

do_execsql_test 2.1 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS LAST
      RANGE BETWEEN UNBOUNDED PRECEDING AND 2.25 FOLLOWING)
  ORDER BY +d DESC NULLS LAST, +a;
} [list \
  5 E 10.26 ED       \
  4 D 10.25 EDC      \
  3 C   8.0 EDC      \
  2 B  5.55 EDCBA    \
  1 A   5.4 EDCBA    \
  6 N  NULL EDCBANN  \
  7 N  NULL EDCBANN  \
]

do_execsql_test 2.2 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN UNBOUNDED PRECEDING AND 2.25 FOLLOWING)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NN         \
  7 N  NULL NN         \
  5 E 10.26 NNED       \
  4 D 10.25 NNEDC      \
  3 C   8.0 NNEDC      \
  2 B  5.55 NNEDCBA    \
  1 A   5.4 NNEDCBA    \
]

do_execsql_test 2.3 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS LAST
      RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
  ORDER BY +d DESC NULLS LAST, +a;
} [list \
  5 E 10.26 EDCBANN  \
  4 D 10.25 EDCBANN  \
  3 C   8.0 EDCBANN  \
  2 B  5.55 EDCBANN  \
  1 A   5.4 EDCBANN  \
  6 N  NULL EDCBANN  \
  7 N  NULL EDCBANN  \
]

do_execsql_test 2.4 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NNEDCBA  \
  7 N  NULL NNEDCBA  \
  5 E 10.26 NNEDCBA  \
  4 D 10.25 NNEDCBA  \
  3 C   8.0 NNEDCBA  \
  2 B  5.55 NNEDCBA  \
  1 A   5.4 NNEDCBA  \
]

do_execsql_test 2.5 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS LAST
      RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
  ORDER BY +d DESC NULLS LAST, +a;
} [list \
  5 E 10.26 E        \
  4 D 10.25 ED       \
  3 C   8.0 EDC      \
  2 B  5.55 EDCB     \
  1 A   5.4 EDCBA    \
  6 N  NULL EDCBANN  \
  7 N  NULL EDCBANN  \
]

do_execsql_test 2.6 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NN       \
  7 N  NULL NN       \
  5 E 10.26 NNE      \
  4 D 10.25 NNED     \
  3 C   8.0 NNEDC    \
  2 B  5.55 NNEDCB   \
  1 A   5.4 NNEDCBA  \
]


do_execsql_test 3.1 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS LAST
      RANGE BETWEEN CURRENT ROW AND 2.25 FOLLOWING)
  ORDER BY +d DESC NULLS LAST, +a;
} [list \
  5 E 10.26 ED       \
  4 D 10.25 DC       \
  3 C   8.0 C        \
  2 B  5.55 BA       \
  1 A   5.4 A        \
  6 N  NULL NN       \
  7 N  NULL NN       \
]

do_execsql_test 3.2 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN CURRENT ROW AND 2.25 FOLLOWING)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NN       \
  7 N  NULL NN       \
  5 E 10.26 ED       \
  4 D 10.25 DC       \
  3 C   8.0 C        \
  2 B  5.55 BA       \
  1 A   5.4 A        \
]

do_execsql_test 3.3 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS LAST
      RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  ORDER BY +d DESC NULLS LAST, +a;
} [list \
  5 E 10.26 EDCBANN  \
  4 D 10.25 DCBANN   \
  3 C   8.0 CBANN    \
  2 B  5.55 BANN     \
  1 A   5.4 ANN      \
  6 N  NULL NN       \
  7 N  NULL NN       \
]

do_execsql_test 3.4 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NNEDCBA  \
  7 N  NULL NNEDCBA  \
  5 E 10.26 EDCBA    \
  4 D 10.25 DCBA     \
  3 C   8.0 CBA      \
  2 B  5.55 BA       \
  1 A   5.4 A        \
]

do_execsql_test 4.0 {
  SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1
  WINDOW w1 AS 
     (ORDER BY d DESC NULLS FIRST
      RANGE BETWEEN 2.50 PRECEDING AND 0.5 PRECEDING)
  ORDER BY +d DESC NULLS FIRST, +a;
} [list \
  6 N  NULL NN  \
  7 N  NULL NN  \
  5 E 10.26 {}  \
  4 D 10.25 {}  \
  3 C   8.0 ED  \
  2 B  5.55 C   \
  1 A   5.4 {}  \
]


finish_test

Deleted test/windowB.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








































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019-08-30
#
# 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 RANGE BETWEEN and especially with NULLS LAST
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix windowB

ifcapable !windowfunc {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(NULL, 1);
  INSERT INTO t1 VALUES(NULL, 2);
  INSERT INTO t1 VALUES(NULL, 3);
} {}

foreach {tn win} {
  1 { ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
  2 { ORDER BY a NULLS LAST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
  3 { ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
  4 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }

  5 { ORDER BY a      NULLS LAST  RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING }
  6 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING }

  7 { ORDER BY a      NULLS LAST  RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING }
  8 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING }
} {
  do_execsql_test 1.$tn "
    SELECT sum(b) OVER win FROM t1
    WINDOW win AS ( $win )
  " {6 6 6}
}

do_execsql_test 1.2 {
  SELECT sum(b) OVER win FROM t1
  WINDOW win AS (
    ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
  )
} {6 6 6}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, NULL);
  INSERT INTO t1 VALUES(2, 45);
  INSERT INTO t1 VALUES(3, 66.2);
  INSERT INTO t1 VALUES(4, 'hello world');
  INSERT INTO t1 VALUES(5, 'hello world');
  INSERT INTO t1 VALUES(6, X'1234');
  INSERT INTO t1 VALUES(7, X'1234');
  INSERT INTO t1 VALUES(8, NULL);
}

foreach {tn win} {
  1 "ORDER BY b RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING"
  2 "ORDER BY b RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING"
  3 "ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING"
  4 "ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING"
} {
  do_execsql_test 2.1.$tn "
    SELECT a, sum(a) OVER win FROM t1
    WINDOW win AS ( $win )
    ORDER BY 1
  " {1 9   2 {}  3 {}  4 9  5 9  6 13  7 13  8 9}
}

#-------------------------------------------------------------------------
ifcapable json1 {
  reset_db
  do_execsql_test 3.0 {
    CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT, x TEXT);
    INSERT INTO testjson VALUES(1, '{"a":1}', 'a');
    INSERT INTO testjson VALUES(2, '{"b":2}', 'b');
    INSERT INTO testjson VALUES(3, '{"c":3}', 'c');
    INSERT INTO testjson VALUES(4, '{"d":4}', 'd');
  }
  
  do_execsql_test 3.1 {
    SELECT json_group_array(json(j)) FROM testjson;
  } {
    {[{"a":1},{"b":2},{"c":3},{"d":4}]}
  }
  
  do_execsql_test 3.2 {
    SELECT json_group_array(json(j)) OVER (ORDER BY id) FROM testjson;
  } {
    {[{"a":1}]}
    {[{"a":1},{"b":2}]}
    {[{"a":1},{"b":2},{"c":3}]}
    {[{"a":1},{"b":2},{"c":3},{"d":4}]}
  }
  
  do_execsql_test 3.3 {
    SELECT json_group_array(json(j)) OVER (
      ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
      EXCLUDE TIES
    ) FROM testjson;
  } {
    {[{"a":1}]}
    {[{"a":1},{"b":2}]}
    {[{"a":1},{"b":2},{"c":3}]}
    {[{"a":1},{"b":2},{"c":3},{"d":4}]}
  }
  
  do_execsql_test 3.4 {
    SELECT json_group_array(json(j)) OVER (
      ORDER BY id ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
    ) FROM testjson;
  } {
    {[{"a":1},{"b":2}]}
    {[{"a":1},{"b":2},{"c":3}]}
    {[{"b":2},{"c":3},{"d":4}]}
    {[{"c":3},{"d":4}]}
  }
  
  do_execsql_test 3.5 {
    SELECT json_group_array(json(j)) OVER (
      ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
    ) FROM testjson;
  } {
    {[]}
    {[{"a":1}]}
    {[{"a":1},{"b":2}]}
    {[{"b":2},{"c":3}]}
  }
  
  do_execsql_test 3.5a {
    UPDATE testjson SET j = replace(j,char(125),',"e":9'||char(125));
    SELECT j FROM testjson;
  } {
    {{"a":1,"e":9}}
    {{"b":2,"e":9}}
    {{"c":3,"e":9}}
    {{"d":4,"e":9}}
  }
  do_execsql_test 3.5b {
    SELECT group_concat(x,'') OVER (
      ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
    ) FROM testjson ORDER BY id;
  } {bc cd d {}}
  do_execsql_test 3.5c {
    SELECT json_group_array(json(j)) OVER (
      ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
    ) FROM testjson;
  } {
    {[{"b":2,"e":9},{"c":3,"e":9}]}
    {[{"c":3,"e":9},{"d":4,"e":9}]}
    {[{"d":4,"e":9}]}
    {[]}
  }
  do_execsql_test 3.5d {
    SELECT json_group_object(x,json(j)) OVER (
      ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
    ) FROM testjson;
  } {
    {{"b":{"b":2,"e":9},"c":{"c":3,"e":9}}}
    {{"c":{"c":3,"e":9},"d":{"d":4,"e":9}}}
    {{"d":{"d":4,"e":9}}}
    {{}}
  }
  
  do_execsql_test 3.7b {
    SELECT group_concat(x,'') FILTER (WHERE id!=2) OVER (
      ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
    ) FROM testjson;
  } {{} a a c}

  do_execsql_test 3.7c {
    SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER (
      ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
    ) FROM testjson
  } {
    {[]}
    {[{"a":1,"e":9}]}
    {[{"a":1,"e":9}]}
    {[{"c":3,"e":9}]}
  }
  do_execsql_test 3.7d {
    SELECT json_group_object(x,json(j)) FILTER (WHERE id!=2) OVER (
      ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
    ) FROM testjson
  } {
    {{}}
    {{"a":{"a":1,"e":9}}}
    {{"a":{"a":1,"e":9}}}
    {{"c":{"c":3,"e":9}}}
  }
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE TABLE x(a);
  INSERT INTO x VALUES(1);
  INSERT INTO x VALUES(2);
}

do_execsql_test 4.1 {
  WITH y AS (
      SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION BY a)
  )
  SELECT * FROM y;
} {
  1 1
}

do_catchsql_test 4.2 {
  WITH y AS (
    SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION
  BY fake_column))
  SELECT * FROM y;
} {1 {no such column: fake_column}}

do_catchsql_test 4.3 {
  SELECT 1 WINDOW win AS (PARTITION BY fake_column);
} {0 1}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  CREATE TABLE t1(a, c);
  CREATE INDEX i1 ON t1(a);

  INSERT INTO t1 VALUES(0, 421);
  INSERT INTO t1 VALUES(1, 844);
  INSERT INTO t1 VALUES(2, 1001);
}

do_execsql_test 5.1 {
  SELECT a, sum(c) OVER (
    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING
  ) FROM t1;
} {0 {} 1 {} 2 {}}

do_execsql_test 5.2 {
  INSERT INTO t1 VALUES(NULL, 123);
  INSERT INTO t1 VALUES(NULL, 111);
  INSERT INTO t1 VALUES('xyz', 222);
  INSERT INTO t1 VALUES('xyz', 333);

  SELECT a, sum(c) OVER (
    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING
  ) FROM t1;
} {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}

do_execsql_test 5.3 {
  SELECT a, sum(c) OVER (
    ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
  ) FROM t1;
} {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}

do_execsql_test 5.4 {
  SELECT a, sum(c) OVER (
    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING EXCLUDE NO OTHERS
  ) FROM t1;
} {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}

do_execsql_test 5.5 {
  SELECT a, sum(c) OVER (
    ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING EXCLUDE NO OTHERS
  ) FROM t1;
} {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
  CREATE TABLE t1(a, c);
  CREATE INDEX i1 ON t1(a);

  INSERT INTO t1 VALUES(7,  997);
  INSERT INTO t1 VALUES(8,  997);
  INSERT INTO t1 VALUES('abc', 1001);
}
do_execsql_test 6.1 {
  SELECT a, sum(c) OVER (
    ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING 
  ) FROM t1;
} {7 {} 8 {} abc 1001} 
do_execsql_test 6.2 {
  SELECT a, sum(c) OVER (
    ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING EXCLUDE NO OTHERS
  ) FROM t1;
} {7 {} 8 {} abc 1001} 

#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
  CREATE TABLE t1(a, c);
  CREATE INDEX i1 ON t1(a);

  INSERT INTO t1 VALUES(NULL, 46);
  INSERT INTO t1 VALUES(NULL, 45);
  INSERT INTO t1 VALUES(7,  997);
  INSERT INTO t1 VALUES(7,  1000);
  INSERT INTO t1 VALUES(8,  997);
  INSERT INTO t1 VALUES(8,  1000);
  INSERT INTO t1 VALUES('abc', 1001);
  INSERT INTO t1 VALUES('abc', 1004);
  INSERT INTO t1 VALUES('xyz', 3333);
}

do_execsql_test 7.1 {
  SELECT a, max(c) OVER (
    ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
  ) FROM t1;
} {{} 46 {} 46  7 {} 7 {} 8 {} 8 {}  abc 1004 abc 1004 xyz 3333}
do_execsql_test 7.2 {
  SELECT a, min(c) OVER (
    ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
  ) FROM t1;
} {{} 45 {} 45  7 {} 7 {} 8 {} 8 {}  abc 1001 abc 1001 xyz 3333}

do_execsql_test 7.3 {
  SELECT a, max(c) OVER (
    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 2 PRECEDING
  ) 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/windowerr.tcl.

60
61
62
63
64
65
66
67
68
69
70
71
72
60
61
62
63
64
65
66



67
68
69







-
-
-



  WINDOW win AS (ROWS BETWEEN 'hello' PRECEDING AND 10 FOLLOWING)
}
errorsql_test 3.2 {
  SELECT sum(a) OVER win FROM t1
  WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING)
}

errorsql_test 3.3 {
  SELECT row_number(a) OVER () FROM t1;
}

finish_test

Changes to test/windowerr.test.

104
105
106
107
108
109
110
111
112
113
114
115
116
104
105
106
107
108
109
110





111







-
-
-
-
-


# PG says ERROR:  argument of ROWS must be type bigint, not type bit
do_test 3.2 { catch { execsql {
  SELECT sum(a) OVER win FROM t1
  WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING)
} } } 1

# PG says ERROR:  function row_number(integer) does not exist
do_test 3.3 { catch { execsql {
  SELECT row_number(a) OVER () FROM t1;
} } } 1

finish_test

Changes to test/windowfault.test.

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
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219

220
221
222
223
224
225




































































226







-








-
+





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

}
proc tmpread_injectstop {} {
  set ret [expr $::tmp_read_fail<=0]
  unset -nocomplain ::tmp_read_fail 
  return $ret
}

set L [db eval {SELECT 0.0 FROM t}]
do_faultsim_test 9 -end 25 -faults tmpread -body {
  execsql {
    SELECT sum(y) OVER win FROM t
    WINDOW win AS (
      ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND 1800 FOLLOWING
    )
  }
} -test {
  faultsim_test_result [list 0 $::L]
  faultsim_test_result {0 {}}
}

catch {db close}
tvfs delete

reset_db
do_execsql_test 10.0 {
  CREATE TABLE t1(a, b, c, d);
  CREATE TABLE t2(a, b, c, d);
}

do_faultsim_test 10 -faults oom* -prep {
} -body {
  execsql {
    SELECT row_number() OVER win
    FROM t1
    WINDOW win AS (
      ORDER BY (
        SELECT percent_rank() OVER win2 FROM t2
        WINDOW win2 AS (ORDER BY a)
      )
    )
  }
} -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

Deleted 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/with1.test.

348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362







-
+







do_catchsql_test 7.4 {
  WITH t(id) AS (
    VALUES(2)
    UNION ALL
    SELECT i FROM tree WHERE p IN (SELECT id FROM t)
  ) 
  SELECT id FROM t;
} {1 {circular reference: t}}
} {1 {recursive reference in a subquery: t}}

do_catchsql_test 7.5 {
  WITH t(id) AS (
    VALUES(2)
    UNION ALL
    SELECT i FROM tree, t WHERE p = id AND p IN (SELECT id FROM t)
  ) 
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
1087
1088
1089
1090
1091
1092
1093




















































































































1094







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

        SELECT  2 FROM c,c,c,c,c,c,c,c,c
     )
     SELECT 3 FROM c,c,c,c,c,c,c,c,c
  )
  SELECT 4 FROM c,c,c,c,c,c,c,c,c;
} {1 {too many FROM clause terms, max: 200}}

# 2019-05-22
# ticket https://www.sqlite.org/src/tktview/ce823231949d3abf42453c8f20
#
sqlite3 db :memory:
do_execsql_test 23.1 {
  CREATE TABLE t1(id INTEGER NULL PRIMARY KEY, name Text);
  INSERT INTO t1 VALUES (1, 'john');
  INSERT INTO t1 VALUES (2, 'james');
  INSERT INTO t1 VALUES (3, 'jingle');
  INSERT INTO t1 VALUES (4, 'himer');
  INSERT INTO t1 VALUES (5, 'smith');
  CREATE VIEW v2 AS
    WITH t4(Name) AS (VALUES ('A'), ('B'))
    SELECT Name Name FROM t4;
  CREATE VIEW v3 AS
    WITH t4(Att, Val, Act) AS (VALUES
      ('C', 'D', 'E'),
      ('F', 'G', 'H')
    )
    SELECT D.Id Id, P.Name Protocol, T.Att Att, T.Val Val, T.Act Act
    FROM t1 D
    CROSS JOIN v2 P
    CROSS JOIN t4 T;
  SELECT * FROM v3;
} {1 A C D E 1 A F G H 1 B C D E 1 B F G H 2 A C D E 2 A F G H 2 B C D E 2 B F G H 3 A C D E 3 A F G H 3 B C D E 3 B F G H 4 A C D E 4 A F G H 4 B C D E 4 B F G H 5 A C D E 5 A F G H 5 B C D E 5 B F G H}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 24.1 {
  CREATE TABLE t1(a, b, c);
  CREATE VIEW v1 AS SELECT max(a), min(b) FROM t1 GROUP BY c;
}
do_test 24.1 {
  set program [db eval {EXPLAIN SELECT 1 FROM v1,v1,v1}]
  expr [lsearch $program OpenDup]>0
} {1}
do_execsql_test 24.2 {
  ATTACH "" AS aux;
  CREATE VIEW aux.v3 AS VALUES(1);
  CREATE VIEW main.v3 AS VALUES(3);

  CREATE VIEW aux.v2 AS SELECT * FROM v3;
  CREATE VIEW main.v2 AS SELECT * FROM v3;

  SELECT * FROM main.v2 AS a, aux.v2 AS b, aux.v2 AS c, main.v2 AS d;
} {
  3 1 1 3
}

# 2020-01-02 chromium ticket 1033461
# Do not allow the generated name of a CTE be "true" or "false" as
# such a label might be later confused for the boolean literals of
# the same name, causing inconsistencies in the abstract syntax
# tree.  This problem first arose in version 3.23.0 when SQLite
# began recognizing "true" and "false" as boolean literals, but also
# had to continue to recognize "true" and "false" as identifiers for
# backwards compatibility.
#
reset_db
do_execsql_test 25.1 {
  CREATE TABLE dual(dummy);
  INSERT INTO dual(dummy) VALUES('X');
  WITH cte1 AS (
    SELECT TRUE, (
      WITH cte2 AS (SELECT avg(DISTINCT TRUE) FROM dual)
      SELECT 2571 FROM cte2
    ) AS subquery1
    FROM dual
    GROUP BY 1
  )
  SELECT (SELECT 1324 FROM cte1) FROM cte1;
} {1324}

do_catchsql_test 26.0 {
  WITH i(x) AS ( 
    VALUES(1) UNION ALL SELECT x+1 FRO, a.b,O. * ,I¬i O, a.b,O. * ORDER BY 1
  )
  SELECT x,O. * O FROM i ¬I,I? 10;
} {1 {near "O": syntax error}}

# 2020-09-17 ticket c51489c3b8f919c5
# DISTINCT cannot be ignored in a UNION ALL recursive CTE
#
reset_db
do_execsql_test 26.1 {
  CREATE TABLE t (label VARCHAR(10), step INTEGER);
  INSERT INTO T VALUES('a', 1);
  INSERT INTO T VALUES('a', 1);
  INSERT INTO T VALUES('b', 1);
  WITH RECURSIVE cte(label, step) AS (
      SELECT DISTINCT * FROM t 
    UNION ALL 
      SELECT label, step + 1 FROM cte WHERE step < 3
  )
  SELECT * FROM cte ORDER BY +label, +step;
} {a 1 a 2 a 3 b 1 b 2 b 3}
do_execsql_test 26.2 {
  WITH RECURSIVE cte(label, step) AS (
      SELECT * FROM t 
    UNION
      SELECT label, step + 1 FROM cte WHERE step < 3
  )
  SELECT * FROM cte ORDER BY +label, +step;
} {a 1 a 2 a 3 b 1 b 2 b 3}
do_execsql_test 26.3 {
  CREATE TABLE tworow(x);
  INSERT INTO tworow(x) VALUES(1),(2);
  DELETE FROM t WHERE rowid=2;
  WITH RECURSIVE cte(label, step) AS (
      SELECT * FROM t
    UNION ALL
      SELECT DISTINCT label, step + 1 FROM cte, tworow WHERE step < 3
  )
  SELECT * FROM cte ORDER BY +label, +step;
} {a 1 a 2 a 3 b 1 b 2 b 3}

finish_test

Changes to test/with2.test.

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
410
411
412
413
414
415
416






































































































































417
418







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


    SELECT 1
    UNION ALL
    SELECT a+1 FROM q, v WHERE a<5
  )
  SELECT * FROM q;
} {1 2 3 4 5}

# 2021-03-18
# Ticket bb8a9fd4a9b7fce5
reset_db
do_execsql_test 9.1 {
  WITH xyz(a) AS (
    WITH abc AS ( SELECT 1234 ) SELECT * FROM abc
  )
  SELECT * FROM xyz AS one, xyz AS two, (
    SELECT * FROM xyz UNION ALL SELECT * FROM xyz
  );
} {1234 1234 1234 1234 1234 1234}
ifcapable vtab {
load_static_extension db series
do_execsql_test 9.2 {
  WITH
    cst(rsx, rsy) AS  (
      SELECT 100, 100
    ),
    cst2(minx, maxx, stepx, miny, maxy, stepy, qualitativex, qualitativey) AS (
      SELECT NULL, NULL, NULL, NULL, NULL, NULL, 0, 0
    ),
    ds0(m, n, x, y, x2, y2, title, size, mark, label, markmode) AS (
      SELECT 1, 2, 3, 4, 5, 6, 7 , 8, 9, 10, 11
    ),
    ds(m, n, x, y, x2, y2, title, size, mark, label, markmode) AS (
      SELECT m, n, x,
        y, x2,
        y2,
        title, size, mark, label, markmode
      FROM ds0
      WINDOW w AS (PARTITION BY m, x ORDER BY n)
    ),
    d(m, n, x, y, x2, y2, labelx,labely,title,size,mark,label,markmode) AS (
      SELECT m, n, x, y,  x2, y2, x, y, title, size, mark, label, markmode
      FROM ds, cst2
    ),
    ylabels(y, label) AS (
      SELECT y, MIN(labely) FROM d GROUP BY y
    ),
    yaxis(maxy, miny, stepy , minstepy) AS (
      WITH
        xt0(minx, maxx) AS (
          SELECT  coalesce(miny, min(min(y2),
                  min(y))), coalesce(maxy, max(max(y2),
                  max(y))) + qualitativey
           FROM d, cst2
        ),
        xt1(mx, mn) AS (SELECT maxx, minx FROM xt0),
        xt2(mx, mn, step) AS (SELECT mx, mn, (mx-mn)  FROM xt1),
        
        xt3(mx, mn, ms) AS (
          SELECT mx, mn, first_value(rs) OVER (order by x desc) AS ms
            FROM (SELECT mx, mn, step, f,(mx-mn) as rng,
                         1.0*step/f as rs, 1.0*(mx-mn)/(step/f) AS x
                    FROM xt2, (SELECT 1 AS f UNION ALL SELECT 2
                                UNION ALL SELECT 4
                                UNION ALL SELECT 5)) AS src
                   WHERE x < 10 limit 1),
        xt4(minstepy) AS (
          SELECT MIN(abs(y2-y)) FROM d WHERE y2 != y
        )
      SELECT (mx/ms)*ms, (mn/ms)*ms, coalesce(stepy, ms),
                     coalesce(minstepy, ms, stepy)  FROM xt3, cst2,xt4
    ),
    distinct_mark_n_m(mark, ze, zem, title) AS (
      SELECT DISTINCT mark, n AS ze, m AS zem, title FROM ds0
    ),
    facet0(m, mi, title, radial) AS (
      SELECT md, row_number() OVER () - 1, title, 'radial'
                      IN (SELECT mark FROM distinct_mark_n_m WHERE zem = md)
      FROM (SELECT DISTINCT zem AS md, title AS title
                       FROM distinct_mark_n_m ORDER BY 2, 1)
    ),
    facet(m, mi, xorigin, yorigin, title, radial) AS (
      SELECT m, mi,
        rsx * 1.2 * IFNULL(CASE WHEN (
          0
        ) > 0 THEN mi / (
          0
        ) ELSE mi % (
          2
        )  END, mi),
        rsy  * 1.2 * IFNULL(CASE WHEN (
          2
        ) > 0 THEN mi / (
          2
        ) ELSE mi / (
          0
        )  END, 0),
        title, radial FROM facet0, cst
    ),
    radygrid(m, mi, tty, wty, ttx, ttx2, xorigin, yorigin) AS (
      SELECT m, mi,  rsy / 2 / ((maxy-miny)/stepy) * (value-1) AS tty,
             coalesce(NULL, miny + stepy * (value-1)) AS wty,
             xorigin, xorigin+rsx, xorigin + rsx / 2,
             yorigin + rsy / 2
        FROM generate_series(1), yaxis, cst,
             facet LEFT JOIN ylabels ON ylabels.y = (miny + (value-1) * stepy)
       WHERE radial AND stop = 1+1.0*(maxy-miny)/stepy
    ),
    ypos(m, mi, pcx, pcy, radial) AS (
      SELECT m, mi, xorigin, yorigin + CASE
        WHEN 0 BETWEEN miny AND maxy THEN
          rsy - (0 - miny) * rsy / (maxy-miny)
        WHEN 0 >= maxy THEN 0
        ELSE  rsy
      END, radial FROM yaxis, cst, facet WHERE NOT radial
      UNION ALL
      SELECT m, mi, xorigin + rsx / 2, yorigin + (CASE
        WHEN 0 BETWEEN miny AND maxy THEN
          rsy - (0 - miny) * rsy / 2 / (maxy-miny)
        WHEN 0 >= maxy THEN 0
        ELSE  rsy
      END ) / 2, radial FROM yaxis, cst, facet WHERE radial
    )
  SELECT * FROM radygrid , ypos;
} {}
} ;# end ifcapable vtab

# 2021-03-19
# dbsqlfuzz 01b8355086998f0a452cb31208e80b9d29ca739a
#
# Correlated CTEs should not be materialized.
#
reset_db
do_execsql_test 10.1 {
  SELECT 1 AS c WHERE (
    SELECT (
      WITH t1(a) AS (VALUES( c ))
      SELECT ( SELECT t1a.a FROM t1 AS t1a, t1 AS t1x )
      FROM t1 AS xyz GROUP BY 1
    )
  )
} {1}

finish_test

Changes to test/with3.test.

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
28
29
30
31
32
33
34








35
36
37
38
39
40
41







-
-
-
-
-
-
-
-







  WITH i(x) AS (
    WITH j AS (SELECT 10)
    SELECT 5 FROM t0 UNION SELECT 8 FROM m
  )
  SELECT * FROM i;
} {1 {no such table: m}}

# 2019-11-09 dbfuzzcheck find
do_catchsql_test 1.1 {
  CREATE VIEW v1(x,y) AS
    WITH t1(a,b) AS (VALUES(1,2))
    SELECT * FROM nosuchtable JOIN t1;
  SELECT * FROM v1;
} {1 {no such table: main.nosuchtable}}

# Additional test cases that came out of the work to
# fix for Kostya's problem.
#
do_execsql_test 2.0 {
 WITH
  x1 AS (SELECT 10),
  x2 AS (SELECT 11),
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
125
126
127
128
129
130
131
132










































































































133








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  |  `--RECURSIVE STEP
  |     |--SCAN TABLE w1
  |     `--SCAN TABLE c
  |--SCAN SUBQUERY xxxxxx
  |--SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)
  `--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)
}

do_execsql_test 4.0 {
  WITH t5(t5col1) AS (
    SELECT (
      WITH t3(t3col1) AS (
        WITH t2 AS (
          WITH t1 AS (SELECT 1 AS c1 GROUP BY 1) 
          SELECT a.c1 FROM t1 AS a, t1 AS b
          WHERE anoncol1 = 1
        )
        SELECT (SELECT 1 FROM t2) FROM t2
      ) 
      SELECT t3col1 FROM t3 WHERE t3col1
    ) FROM (SELECT 1 AS anoncol1)
  )
  SELECT t5col1, t5col1 FROM t5
} {1 1}
do_execsql_test 4.1 {
  SELECT EXISTS (
    WITH RECURSIVE Table0 AS (
      WITH RECURSIVE Table0(Col0) AS (SELECT ALL 1  ) 
      SELECT ALL (
        WITH RECURSIVE Table0 AS (
          WITH RECURSIVE Table0 AS (
            WITH RECURSIVE Table0 AS (SELECT DISTINCT 1  GROUP BY 1  ) 
            SELECT DISTINCT * FROM Table0 NATURAL INNER JOIN Table0
            WHERE Col0 = 1  
          )
          SELECT ALL (SELECT DISTINCT * FROM Table0) FROM Table0 WHERE Col0 = 1
        ) 
        SELECT ALL * FROM Table0  NATURAL INNER JOIN  Table0      
      ) FROM Table0 ) 
      SELECT DISTINCT * FROM Table0  NATURAL INNER JOIN  Table0      
    ); 
} {1}

# 2020-01-18 chrome ticket 1043236
# Correct handling of the sequence:
#    OP_OpenEphem
#    OP_OpenDup
#    Op_OpenEphem
#    OP_OpenDup
#
do_execsql_test 4.2 {
  SELECT (
    WITH t1(a) AS (VALUES(1))
    SELECT (
      WITH t2(b) AS (
        WITH t3(c) AS (
          WITH t4(d) AS (VALUES('elvis'))
          SELECT t4a.d FROM t4 AS t4a JOIN t4 AS t4b LEFT JOIN t4 AS t4c
        )
        SELECT c FROM t3 WHERE a = 1
      )
      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}

#-------------------------------------------------------------------------
# At one point this would incorrectly report "circular reference: cte1"
#
do_catchsql_test 6.0 {
  with
    cte1(x, y) AS ( select 1, 2, 3 ),
    cte2(z) as ( select 1 from cte1 )
  select * from cte2, cte1;
} {1 {table cte1 has 3 values for 2 columns}}

do_catchsql_test 6.1 {
  with
    cte1(x, y) AS ( select 1, 2, 3 ),
    cte2(z) as ( select 1 from cte1 UNION ALL SELECT z+1 FROM cte2 WHERE z<5)
  select * from cte2, cte1;
} {1 {table cte1 has 3 values for 2 columns}}




finish_test

Deleted test/with5.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


































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2020-10-19
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is recursive common table expressions with
# multiple recursive terms in the compound select.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix with5

ifcapable {!cte} {
  finish_test
  return
}

do_execsql_test 100 {
  CREATE TABLE link(aa INT, bb INT);
  CREATE INDEX link_f ON link(aa,bb);
  CREATE INDEX link_t ON link(bb,aa);
  INSERT INTO link(aa,bb) VALUES
    (1,3),
    (5,3),
    (7,1),
    (7,9),
    (9,9),
    (5,11),
    (11,7),
    (2,4),
    (4,6),
    (8,6);
} {}
do_execsql_test 110 {
  WITH RECURSIVE closure(x) AS (
     VALUES(1)
     UNION
     SELECT aa FROM closure, link WHERE link.bb=closure.x
     UNION
     SELECT bb FROM closure, link WHERE link.aa=closure.x
  )
  SELECT x FROM closure ORDER BY x;
} {1 3 5 7 9 11}
do_execsql_test 111 {
  WITH RECURSIVE closure(x) AS (
     VALUES(1)
     UNION
     SELECT aa FROM link, closure WHERE link.bb=closure.x
     UNION
     SELECT bb FROM closure, link WHERE link.aa=closure.x
  )
  SELECT x FROM closure ORDER BY x;
} {1 3 5 7 9 11}
do_execsql_test 112 {
  WITH RECURSIVE closure(x) AS (
     VALUES(1)
     UNION
     SELECT bb FROM closure, link WHERE link.aa=closure.x
     UNION
     SELECT aa FROM link, closure WHERE link.bb=closure.x
  )
  SELECT x FROM closure ORDER BY x;
} {1 3 5 7 9 11}
do_execsql_test 113 {
  WITH RECURSIVE closure(x) AS (
     VALUES(1),(200),(300),(400)
     INTERSECT
     VALUES(1)
     UNION
     SELECT bb FROM closure, link WHERE link.aa=closure.x
     UNION
     SELECT aa FROM link, closure WHERE link.bb=closure.x
  )
  SELECT x FROM closure ORDER BY x;
} {1 3 5 7 9 11}
do_execsql_test 114 {
  WITH RECURSIVE closure(x) AS (
     VALUES(1),(200),(300),(400)
     UNION ALL
     VALUES(2)
     UNION
     SELECT bb FROM closure, link WHERE link.aa=closure.x
     UNION
     SELECT aa FROM link, closure WHERE link.bb=closure.x
  )
  SELECT x FROM closure ORDER BY x;
} {1 2 3 4 5 6 7 8 9 11 200 300 400}

do_catchsql_test 120 {
  WITH RECURSIVE closure(x) AS (
     VALUES(1),(200),(300),(400)
     UNION ALL
     VALUES(2)
     UNION ALL
     SELECT bb FROM closure, link WHERE link.aa=closure.x
     UNION
     SELECT aa FROM link, closure WHERE link.bb=closure.x
  )
  SELECT x FROM closure ORDER BY x;
} {1 {circular reference: closure}}
do_catchsql_test 121 {
  WITH RECURSIVE closure(x) AS (
     VALUES(1),(200),(300),(400)
     UNION ALL
     VALUES(2)
     UNION
     SELECT bb FROM closure, link WHERE link.aa=closure.x
     UNION ALL
     SELECT aa FROM link, closure WHERE link.bb=closure.x
  )
  SELECT x FROM closure ORDER BY x;
} {1 {circular reference: closure}}

do_execsql_test 130 {
  WITH RECURSIVE closure(x) AS (
    SELECT 1 AS x
    UNION
    SELECT aa FROM link JOIN closure ON bb=x
    UNION
    SELECT bb FROM link JOIN closure on aa=x
    ORDER BY x LIMIT 4
  )
  SELECT * FROM closure;
} {1 3 5 7}
do_execsql_test 131 {
  WITH RECURSIVE closure(x) AS (
    SELECT 1 AS x
    UNION ALL
    SELECT 2
    UNION
    SELECT aa FROM link JOIN closure ON bb=x
    UNION
    SELECT bb FROM link JOIN closure on aa=x
    ORDER BY x LIMIT 4
  )
  SELECT * FROM closure;
} {1 2 3 4}

do_execsql_test 200 {
  CREATE TABLE linkA(aa1,aa2);
  INSERT INTO linkA(aa1,aa2) VALUES(1,3),(5,7),(9,11);
  CREATE TABLE linkB(bb1,bb2);
  INSERT INTO linkB(bb1,bb2) VALUES(7,9),(11,13),(3,5);
  CREATE TABLE linkC(cc1,cc2);
  INSERT INTO linkC(cc1,cc2) VALUES(1,2),(2,4),(6,8);
  CREATE TABLE linkD(dd1,dd2);
  INSERT INTO linkD(dd1,dd2) VALUES(4,6),(100,110);
} {}
do_execsql_test 210 {
  WITH RECURSIVE closure(x) AS (
    VALUES(1)
    UNION ALL
    SELECT aa2 FROM linkA JOIN closure ON x=aa1
    UNION ALL
    SELECT bb2 FROM linkB JOIN closure ON x=bb1
    UNION ALL
    SELECT cc2 FROM linkC JOIN closure ON x=cc1
    UNION ALL
    SELECT dd2 FROM linkD JOIN closure ON x=dd1
  )
  SELECT x FROM closure ORDER BY +x;
} {1 2 3 4 5 6 7 8 9 11 13}
do_execsql_test 220 {
  CREATE TABLE linkA_ipk(aa1 INTEGER PRIMARY KEY,aa2);
  INSERT INTO linkA_ipk(aa1,aa2) SELECT aa1, aa2 FROM linkA;
  CREATE TABLE linkB_ipk(bb1 INTEGER PRIMARY KEY,bb2);
  INSERT INTO linkB_ipk(bb1,bb2) SELECT bb1, bb2 FROM linkB;
  CREATE TABLE linkC_ipk(cc1 INTEGER PRIMARY KEY,cc2);
  INSERT INTO linkC_ipk(cc1,cc2) SELECT cc1, cc2 FROM linkC;
  CREATE TABLE linkD_ipk(dd1 INTEGER PRIMARY KEY,dd2);
  INSERT INTO linkD_ipk(dd1,dd2) SELECT dd1, dd2 FROM linkD;
  WITH RECURSIVE closure(x) AS (
    VALUES(1)
    UNION ALL
    SELECT aa2 FROM linkA_ipk JOIN closure ON x=aa1
    UNION ALL
    SELECT bb2 FROM linkB_ipk JOIN closure ON x=bb1
    UNION ALL
    SELECT cc2 FROM linkC_ipk JOIN closure ON x=cc1
    UNION ALL
    SELECT dd2 FROM linkD_ipk JOIN closure ON x=dd1
  )
  SELECT x FROM closure ORDER BY +x;
} {1 2 3 4 5 6 7 8 9 11 13}


finish_test

Deleted 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 test/without_rowid1.test.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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







-
-
-
-














-
-
-
-







# focus of this file is testing WITHOUT ROWID tables.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix without_rowid1

proc do_execsql_test_if_vtab {tn sql {res {}}} {
  ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}

# Create and query a WITHOUT ROWID table.
#
do_execsql_test without_rowid1-1.0 {
  CREATE TABLE t1(a,b,c,d, PRIMARY KEY(c,a)) WITHOUT ROWID;
  CREATE INDEX t1bd ON t1(b, d);
  INSERT INTO t1 VALUES('journal','sherman','ammonia','helena');
  INSERT INTO t1 VALUES('dynamic','juliet','flipper','command');
  INSERT INTO t1 VALUES('journal','sherman','gamma','patriot');
  INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena');
  SELECT *, '|' FROM t1 ORDER BY c, a;
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

integrity_check without_rowid1-1.0ic

do_execsql_test_if_vtab without_rowid1-1.0ixi {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {c 1 a 1 b 0 d 0}

do_execsql_test without_rowid1-1.1 {
  SELECT *, '|' FROM t1 ORDER BY +c, a;
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

do_execsql_test without_rowid1-1.2 {
  SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC;
} {journal sherman gamma patriot | dynamic juliet flipper command | journal sherman ammonia helena | arctic sleep ammonia helena |}
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
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







+
+
+
+
+

















-
-
-












-
-
-
-
-






-
-
-
-
-














-
-
-
-
-








# Verify that ANALYZE works
#
do_execsql_test without_rowid1-1.50 {
  ANALYZE;
  SELECT * FROM sqlite_stat1 ORDER BY idx;
} {t1 t1 {4 2 1} t1 t1bd {4 2 2}}
ifcapable stat3 {
  do_execsql_test without_rowid1-1.51 {
    SELECT DISTINCT tbl, idx FROM sqlite_stat3 ORDER BY idx;
  } {t1 t1 t1 t1bd}
}
ifcapable stat4 {
  do_execsql_test without_rowid1-1.52 {
    SELECT DISTINCT tbl, idx FROM sqlite_stat4 ORDER BY idx;
  } {t1 t1 t1 t1bd}
}

#----------

do_execsql_test 2.1.1 {
  CREATE TABLE t4 (a COLLATE nocase PRIMARY KEY, b) WITHOUT ROWID;
  INSERT INTO t4 VALUES('abc', 'def');
  SELECT * FROM t4;
} {abc def}
do_execsql_test 2.1.2 {
  UPDATE t4 SET a = 'ABC';
  SELECT * FROM t4;
} {ABC def}
do_execsql_test_if_vtab 2.1.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t4');
} {a nocase 1 b BINARY 0}

do_execsql_test 2.2.1 {
  DROP TABLE t4;
  CREATE TABLE t4 (b, a COLLATE nocase PRIMARY KEY) WITHOUT ROWID;
  INSERT INTO t4(a, b) VALUES('abc', 'def');
  SELECT * FROM t4;
} {def abc}

do_execsql_test 2.2.2 {
  UPDATE t4 SET a = 'ABC', b = 'xyz';
  SELECT * FROM t4;
} {xyz ABC}

do_execsql_test_if_vtab 2.2.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t4');
} {a nocase 1 b BINARY 0}


do_execsql_test 2.3.1 {
  CREATE TABLE t5 (a, b, PRIMARY KEY(b, a)) WITHOUT ROWID;
  INSERT INTO t5(a, b) VALUES('abc', 'def');
  UPDATE t5 SET a='abc', b='def';
} {}

do_execsql_test_if_vtab 2.3.2 {
  SELECT name, coll, key FROM pragma_index_xinfo('t5');
} {b BINARY 1 a BINARY 1}


do_execsql_test 2.4.1 {
  CREATE TABLE t6 (
    a COLLATE nocase, b, c UNIQUE, PRIMARY KEY(b, a)
  ) WITHOUT ROWID;

  INSERT INTO t6(a, b, c) VALUES('abc', 'def', 'ghi');
  UPDATE t6 SET a='ABC', c='ghi';
} {}

do_execsql_test 2.4.2 {
  SELECT * FROM t6 ORDER BY b, a;
  SELECT * FROM t6 ORDER BY c;
} {ABC def ghi ABC def ghi}

do_execsql_test_if_vtab 2.4.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t6');
} {b BINARY 1 a nocase 1 c BINARY 0}


#-------------------------------------------------------------------------
# Unless the destination table is completely empty, the xfer optimization 
# is disabled for WITHOUT ROWID tables. The following tests check for
# some problems that might occur if this were not the case.
#
reset_db
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330







-
+







     a INT CHECK( rowid!=33 ),
     b TEXT PRIMARY KEY
  );
  INSERT INTO t70a(a,b) VALUES(99,'hello');
} {}
do_catchsql_test 7.2 {
  INSERT INTO t70a(rowid,a,b) VALUES(33,99,'xyzzy');
} {1 {CHECK constraint failed: rowid!=33}}
} {1 {CHECK constraint failed: t70a}}
do_catchsql_test 7.3 {
  CREATE TABLE t70b(
     a INT CHECK( rowid!=33 ),
     b TEXT PRIMARY KEY
  ) WITHOUT ROWID;
} {1 {no such column: rowid}}

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
387
388
389
390
391
392
393









394
































395







-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  CREATE TRIGGER t1_tr BEFORE UPDATE ON t1 BEGIN
    DELETE FROM t1 WHERE a = new.a;
  END;
  UPDATE t1 SET c = c+1 WHERE a = 'a';
  SELECT * FROM t1;
} {b a 3  b b 4}

# 2019-04-29 ticket https://www.sqlite.org/src/info/3182d3879020ef3
do_execsql_test 11.1 {
  CREATE TABLE t11(a TEXT PRIMARY KEY, b INT) WITHOUT ROWID;
  CREATE INDEX t11a ON t11(a COLLATE NOCASE);
  INSERT INTO t11(a,b) VALUES ('A',1),('a',2);
  PRAGMA integrity_check;
  SELECT a FROM t11 ORDER BY a COLLATE binary;
} {ok A a}

  
# 2019-05-13 ticket https://www.sqlite.org/src/info/bba7b69f9849b5b
do_execsql_test 12.1 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0 (c0 INTEGER PRIMARY KEY DESC, c1 UNIQUE DEFAULT NULL) WITHOUT ROWID;
  INSERT INTO t0(c0) VALUES (1), (2), (3), (4), (5);
  REINDEX;
  PRAGMA integrity_check;
} {ok}

# 2019-11-07 ticket https://www.sqlite.org/src/info/302027baf1374498
# The xferCompatibleIndex() function confuses a PRIMARY KEY index
# with a UNIQUE index.
#
do_execsql_test 13.10 {
  DROP TABLE IF EXISTS t0;
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t0(
    c0,
    c1 UNIQUE,
    PRIMARY KEY(c1, c1)
  ) WITHOUT ROWID;
  INSERT INTO t0(c0,c1) VALUES('abc','xyz');
  CREATE TABLE t1(
    c0,
    c1 UNIQUE,
    PRIMARY KEY(c1, c1)
  ) WITHOUT ROWID;
  INSERT INTO t1 SELECT * FROM t0;
  PRAGMA integrity_check;
  SELECT * FROM t0, t1;
} {ok abc xyz abc xyz}
  
finish_test

Changes to test/without_rowid3.test.

413
414
415
416
417
418
419
420

421
422
423
424
425
426
427

428
429
430
431
432
433
434
413
414
415
416
417
418
419

420
421
422
423
424
425
426

427
428
429
430
431
432
433
434







-
+






-
+







    INSERT INTO ab VALUES(1, 'b');
    INSERT INTO cd VALUES(1, 'd');
    INSERT INTO ef VALUES(1, 'e');
  }
} {}
do_test without_rowid3-3.1.3 {
  catchsql { UPDATE ab SET a = 5 }
} {1 {CHECK constraint failed: e!=5}}
} {1 {CHECK constraint failed: ef}}
do_test without_rowid3-3.1.4 {
  execsql { SELECT * FROM ab }
} {1 b}
do_test without_rowid3-3.1.4 {
  execsql BEGIN;
  catchsql { UPDATE ab SET a = 5 }
} {1 {CHECK constraint failed: e!=5}}
} {1 {CHECK constraint failed: ef}}
do_test without_rowid3-3.1.5 {
  execsql COMMIT;
  execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
} {1 b 1 d 1 e}

do_test without_rowid3-3.2.1 {
  execsql BEGIN;
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945

946
947
948
949
950
951
952
953
954
955
956
957

958
959
960
961
962
963
964
965
966
967

968
969
970
971
972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
987
988

989
990
991
992
993
994
995
917
918
919
920
921
922
923

924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943

944
945
946
947
948
949
950
951
952
953
954
955

956
957
958
959
960
961
962
963
964
965

966
967
968
969
970
971
972
973
974
975
976
977

978
979
980
981
982
983
984
985
986

987
988
989
990
991
992
993
994







-




















-
+











-
+









-
+











-
+








-
+







drop_all_tables
ifcapable altertable {
  do_test without_rowid3-14.1.1 {
    # Adding a column with a REFERENCES clause is not supported.
    execsql { 
      CREATE TABLE t1(a PRIMARY KEY) WITHOUT rowid;
      CREATE TABLE t2(a, b);
      INSERT INTO t2(a,b) VALUES(1,2);
    }
    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
  } {0 {}}
  do_test without_rowid3-14.1.2 {
    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
  } {0 {}}
  do_test without_rowid3-14.1.3 {
    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
  } {0 {}}
  do_test without_rowid3-14.1.4 {
    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
  do_test without_rowid3-14.1.5 {
    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
  do_test without_rowid3-14.1.6 {
    execsql { 
      PRAGMA foreign_keys = off;
      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
      PRAGMA foreign_keys = on;
      SELECT sql FROM sqlite_schema WHERE name='t2';
      SELECT sql FROM sqlite_master WHERE name='t2';
    }
  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
  
  
  # Test the sqlite_rename_parent() function directly.
  #
  proc test_rename_parent {zCreate zOld zNew} {
    db eval {SELECT sqlite_rename_table(
        'main', 'table', 't1', $zCreate, $zOld, $zNew, 0
    )}
  }
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
  do_test without_rowid3-14.2.1.1 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  do_test without_rowid3-14.2.1.2 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
  } {{CREATE TABLE t1(a REFERENCES t2)}}
  do_test without_rowid3-14.2.1.3 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
  
  # Test ALTER TABLE RENAME TABLE a bit.
  #
  do_test without_rowid3-14.2.2.1 {
    drop_all_tables
    execsql {
      CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
      CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
            WITHOUT rowid;
      CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
    }
    execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
    execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
  } [list \
    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid}       \
    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
            WITHOUT rowid}    \
    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
  ]
  do_test without_rowid3-14.2.2.2 {
    execsql { ALTER TABLE t1 RENAME TO t4 }
    execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
    execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
  } [list \
    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid}      \
    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
            WITHOUT rowid}     \
    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
  ]
  do_test without_rowid3-14.2.2.3 {
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
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







-




















-
+



-
+









-
+











-
+








-
+







  #
  drop_all_tables
  do_test without_rowid3-14.1tmp.1 {
    # Adding a column with a REFERENCES clause is not supported.
    execsql { 
      CREATE TEMP TABLE t1(a PRIMARY KEY) WITHOUT rowid;
      CREATE TEMP TABLE t2(a, b);
      INSERT INTO temp.t2(a,b) VALUES(1,2);
    }
    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
  } {0 {}}
  do_test without_rowid3-14.1tmp.2 {
    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
  } {0 {}}
  do_test without_rowid3-14.1tmp.3 {
    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
  } {0 {}}
  do_test without_rowid3-14.1tmp.4 {
    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
  do_test without_rowid3-14.1tmp.5 {
    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
  do_test without_rowid3-14.1tmp.6 {
    execsql { 
      PRAGMA foreign_keys = off;
      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
      PRAGMA foreign_keys = on;
      SELECT sql FROM temp.sqlite_schema WHERE name='t2';
      SELECT sql FROM temp.sqlite_master WHERE name='t2';
    }
  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}

  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
  do_test without_rowid3-14.2tmp.1.1 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  do_test without_rowid3-14.2tmp.1.2 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
  } {{CREATE TABLE t1(a REFERENCES t2)}}
  do_test without_rowid3-14.2tmp.1.3 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
  
  # Test ALTER TABLE RENAME TABLE a bit.
  #
  do_test without_rowid3-14.2tmp.2.1 {
    drop_all_tables
    execsql {
      CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
      CREATE TEMP TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
            WITHOUT rowid;
      CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
    }
    execsql { SELECT sql FROM sqlite_temp_schema WHERE type = 'table'}
    execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'}
  } [list \
    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid}       \
    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
            WITHOUT rowid}    \
    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
  ]
  do_test without_rowid3-14.2tmp.2.2 {
    execsql { ALTER TABLE t1 RENAME TO t4 }
    execsql { SELECT sql FROM temp.sqlite_schema WHERE type = 'table'}
    execsql { SELECT sql FROM temp.sqlite_master WHERE type = 'table'}
  } [list \
    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid}      \
    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
            WITHOUT rowid}     \
    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
  ]
  do_test without_rowid3-14.2tmp.2.3 {
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
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







-




















-
+



-
+









-
+











-
+








-
+







  drop_all_tables
  do_test without_rowid3-14.1aux.1 {
    # Adding a column with a REFERENCES clause is not supported.
    execsql { 
      ATTACH ':memory:' AS aux;
      CREATE TABLE aux.t1(a PRIMARY KEY) WITHOUT rowid;
      CREATE TABLE aux.t2(a, b);
      INSERT INTO aux.t2(a,b) VALUES(1,2);
    }
    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
  } {0 {}}
  do_test without_rowid3-14.1aux.2 {
    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
  } {0 {}}
  do_test without_rowid3-14.1aux.3 {
    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
  } {0 {}}
  do_test without_rowid3-14.1aux.4 {
    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
  do_test without_rowid3-14.1aux.5 {
    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
  do_test without_rowid3-14.1aux.6 {
    execsql { 
      PRAGMA foreign_keys = off;
      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
      PRAGMA foreign_keys = on;
      SELECT sql FROM aux.sqlite_schema WHERE name='t2';
      SELECT sql FROM aux.sqlite_master WHERE name='t2';
    }
  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}

  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
  do_test without_rowid3-14.2aux.1.1 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  do_test without_rowid3-14.2aux.1.2 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
  } {{CREATE TABLE t1(a REFERENCES t2)}}
  do_test without_rowid3-14.2aux.1.3 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
  
  # Test ALTER TABLE RENAME TABLE a bit.
  #
  do_test without_rowid3-14.2aux.2.1 {
    drop_all_tables
    execsql {
      CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
      CREATE TABLE aux.t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
            WITHOUT rowid;
      CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
    }
    execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
    execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}
  } [list \
    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid}       \
    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
            WITHOUT rowid}    \
    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
  ]
  do_test without_rowid3-14.2aux.2.2 {
    execsql { ALTER TABLE t1 RENAME TO t4 }
    execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
    execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}
  } [list \
    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid}      \
    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
            WITHOUT rowid}     \
    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
  ]
  do_test without_rowid3-14.2aux.2.3 {

Changes to test/without_rowid6.test.

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
12
13
14
15
16
17
18




19
20
21
22
23
24
25
26



27
28
29
30
31
32
33







-
-
-
-








-
-
-







# Verify that WITHOUT ROWID tables work correctly when the PRIMARY KEY
# has redundant columns.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc do_execsql_test_if_vtab {tn sql {res {}}} {
  ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}

do_execsql_test without_rowid6-100 {
  CREATE TABLE t1(a,b,c,d,e, PRIMARY KEY(a,b,c,a,b,c,d,a,b,c)) WITHOUT ROWID;
  CREATE INDEX t1a ON t1(b, b);
  WITH RECURSIVE
    c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<1000)
  INSERT INTO t1(a,b,c,d,e) SELECT i, i+1000, printf('x%dy',i), 0, 0 FROM c;
  ANALYZE;
} {}
do_execsql_test_if_vtab without_rowid6-101 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {a 1 b 1 c 1 d 1 e 0}
do_execsql_test without_rowid6-110 {
  SELECT c FROM t1 WHERE a=123;
} {x123y}
do_execsql_test without_rowid6-120 {
  SELECT c FROM t1 WHERE b=1123;
} {x123y}
do_execsql_test without_rowid6-130 {
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
47
48
49
50
51
52
53



54
55
56
57
58
59
60







-
-
-







    b UNIQUE,
    c UNIQUE,
    PRIMARY KEY(b)
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9);
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {4 1}
do_execsql_test_if_vtab without_rowid6-201 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {b 1 a 0 c 0}
do_execsql_test without_rowid6-210 {
  EXPLAIN QUERY PLAN
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {/SEARCH TABLE t1 USING PRIMARY KEY .b>../}
do_execsql_test without_rowid6-220 {
  PRAGMA index_list(t1);
} {/sqlite_autoindex_t1_2 1 pk/}
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
101
102
103
104
105
106
107



108
109
110
111
112
113
114







-
-
-







  CREATE TABLE t1(a,b,c,
    UNIQUE(b,c),
    PRIMARY KEY(b,c)
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9);
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {4 1}
do_execsql_test_if_vtab without_rowid6-501 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {b 1 c 1 a 0}
do_execsql_test without_rowid6-510 {
  EXPLAIN QUERY PLAN
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {/SEARCH TABLE t1 USING PRIMARY KEY .b>../}
do_execsql_test without_rowid6-520 {
  PRAGMA index_list(t1);
} {/sqlite_autoindex_t1_1 1 pk/}

Deleted test/without_rowid7.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




























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2019 July 17
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix without_rowid7

proc do_execsql_test_if_vtab {tn sql {res {}}} {
  ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b COLLATE nocase, PRIMARY KEY(a, a, b)) WITHOUT ROWID;
}

do_catchsql_test 1.1 {
  INSERT INTO t1 VALUES(1, 'one'), (1, 'ONE');
} {1 {UNIQUE constraint failed: t1.a, t1.b}}


do_execsql_test 2.0 {
  CREATE TABLE t2(a, b, PRIMARY KEY(a COLLATE nocase, a)) WITHOUT ROWID;
}

do_execsql_test 2.1 {
  INSERT INTO t2 VALUES(1, 'one');
  SELECT b FROM t2;
} {one}

do_execsql_test 2.2a {
  PRAGMA index_info(t2);
} {0 0 a 1 0 a}
do_execsql_test_if_vtab 2.2b {
  SELECT *, '|' FROM pragma_index_info('t2');
} {0 0 a | 1 0 a |}
do_execsql_test 2.3a {
  PRAGMA index_xinfo(t2);
} {0 0 a 0 nocase 1 1 0 a 0 BINARY 1 2 1 b 0 BINARY 0}
do_execsql_test_if_vtab 2.3b {
  SELECT *, '|' FROM pragma_index_xinfo('t2');
} {0 0 a 0 nocase 1 | 1 0 a 0 BINARY 1 | 2 1 b 0 BINARY 0 |}

do_execsql_test 2.4 {
  CREATE TABLE t3(a, b, PRIMARY KEY(a COLLATE nocase, a));
  PRAGMA index_info(t3);
} {}



finish_test

Changes to test/zipfile.test.

791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
791
792
793
794
795
796
797
















































798







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  } {subdir subdir/x1.txt subdir/x2.txt}

  do_execsql_test 12.5 {
    SELECT name FROM d JOIN x JOIN fsdir('.', d) ORDER BY 1;
  } {. ./x1.txt ./x2.txt}
}

# 2019-12-18 Yongheng and Rui fuzzer
#
do_execsql_test 13.10 {
  DROP TABLE IF EXISTS t0;
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t0(a,b,c,d,e,f,g);
  REPLACE INTO t0(c,b,f) VALUES(10,10,10);
  CREATE VIRTUAL TABLE t1 USING zipfile('h.zip');
  REPLACE INTO t1 SELECT * FROM t0;
  SELECT quote(name),quote(mode),quote(mtime),quote(sz),quote(rawdata),
         quote(data),quote(method) FROM t1;
} {'' 10 10 2 X'3130' X'3130' 0}

# 2019-12-23 Yongheng and Rui fuzzer
# Run using valgrind to see the problem.
#
do_execsql_test 14.10 {
  DROP TABLE t1;
  CREATE TABLE t1(x char);
  INSERT INTO t1(x) VALUES('1');
  INSERT INTO t1(x) SELECT zipfile(x, 'xyz') FROM t1;
  INSERT INTO t1(x) SELECT zipfile(x, 'uvw') FROM t1;
  SELECT count(*) FROM t1;
  PRAGMA integrity_check;
} {3 ok}

# 2019-12-26 More problems in zipfile from the Yongheng and Rui fuzzer
#
do_execsql_test 15.10 {
  DROP TABLE IF EXISTS t1;
  CREATE VIRTUAL TABLE t1 USING zipfile(null);
  REPLACE INTO t1 VALUES(null,null,0,null,null,null,null);
} {}
do_execsql_test 15.20 {
  DROP TABLE IF EXISTS t2;
  CREATE VIRTUAL TABLE t2 USING zipfile(null);
  REPLACE INTO t2 values(null,null,null,null,null,10,null);
} {}

# 2020-01-02 Yongheng fuzzer discovery
#
do_catchsql_test 16.10 {
  DELETE FROM zipfile;
} {1 {zipfile: missing filename}}
do_catchsql_test 16.20 {
  REPLACE INTO zipfile VALUES(null,null,null,null,null,123,null);
} {1 {zipfile: missing filename}}

finish_test

Changes to tool/GetFile.cs.

163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
163
164
165
166
167
168
169

170

171
172
173
174
175
176
177







-
+
-







        {
            if (message != null)
                Console.WriteLine(message);

            string fileName = Path.GetFileName(
                Process.GetCurrentProcess().MainModule.FileName);

            Console.WriteLine(String.Format(
            Console.WriteLine(String.Format("usage: {0} <uri>", fileName));
                "usage: {0} <uri> [fileName]", fileName));
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This method attempts to determine the file name portion of the
        /// specified URI.
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
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







-
+


















-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+
-

















-
-
-
-
-
-
-
-
-







            //
            if (args == null)
            {
                Error(null, true);
                return (int)ExitCode.MissingArgs;
            }

            if ((args.Length < 1) || (args.Length > 2))
            if (args.Length != 1)
            {
                Error(null, true);
                return (int)ExitCode.WrongNumArgs;
            }

            //
            // NOTE: Attempt to convert the first (and only) command line
            //       argument to an absolute URI.
            //
            Uri uri;

            if (!Uri.TryCreate(args[0], UriKind.Absolute, out uri))
            {
                Error("Could not create absolute URI from argument.", false);
                return (int)ExitCode.BadUri;
            }

            //
            // NOTE: If a file name was specified on the command line, try to
            //       use it (without its directory name); otherwise, fallback
            //       to using the file name portion of the URI.
            //
            string fileName = (args.Length == 2) ?
                Path.GetFileName(args[1]) : null;

            if (String.IsNullOrEmpty(fileName))
            {
                //
                // NOTE: Attempt to extract the file name portion of the URI
                //       we just created.
                //
                fileName = GetFileName(uri);
            // NOTE: Attempt to extract the file name portion of the URI we
            //       just created.
            //
            string fileName = GetFileName(uri);

                if (fileName == null)
                {
                    Error("Could not extract file name from URI.", false);
                    return (int)ExitCode.BadFileName;
            if (fileName == null)
            {
                Error("Could not extract the file name from the URI.", false);
                return (int)ExitCode.BadFileName;
                }
            }

            //
            // NOTE: Grab the temporary path setup for this process.  If it is
            //       unavailable, we will not continue.
            //
            string directory = Path.GetTempPath();

            if (String.IsNullOrEmpty(directory) ||
                !Directory.Exists(directory))
            {
                Error("Temporary directory is invalid or unavailable.", false);
                return (int)ExitCode.BadTempPath;
            }

            try
            {
                //
                // HACK: For use of the TLS 1.2 security protocol because some
                //       web servers fail without it.  In order to support the
                //       .NET Framework 2.0+ at compilation time, must use its
                //       integer constant here.
                //
                ServicePointManager.SecurityProtocol =
                    (SecurityProtocolType)0xC00;

                using (WebClient webClient = new WebClient())
                {
                    //
                    // NOTE: Create the event used to signal completion of the
                    //       file download.
                    //
                    doneEvent = new ManualResetEvent(false);

Changes to tool/GetTclKit.bat.

35
36
37
38
39
40
41
42
43
44



45
46

47
48
49
50
51
52
53
35
36
37
38
39
40
41



42
43
44


45
46
47
48
49
50
51
52







-
-
-
+
+
+
-
-
+








SET DUMMY2=%2

IF DEFINED DUMMY2 (
  GOTO usage
)

IF NOT DEFINED ENVDIR (
  SET ENVDIR=%CD%
)
SET ROOT=%~dp0\..
SET ROOT=%ROOT:\\=\%


%_VECHO% EnvDir = '%ENVDIR%'
%_VECHO% Root = '%ROOT%'

SET TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

IF NOT DEFINED windir (
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
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







-
+




-
-
-
-
-
-
-
-
-
-
-
-


-
-
-
-


-
-
-
-






-







  ECHO The TEMP environment variable must be set first.
  GOTO errors
)

%_VECHO% Temp = '%TEMP%'

IF NOT DEFINED TCLKIT_URI (
  SET TCLKIT_URI=https://urn.to/r/tclsh/
  SET TCLKIT_URI=https://tclsh.com/
)

%_VECHO% TclKitUri = '%TCLKIT_URI%'

IF NOT DEFINED TCLKIT_PATCHLEVEL (
  SET TCLKIT_PATCHLEVEL=8.6.6
)

%_VECHO% TclKitPatchLevel = '%TCLKIT_PATCHLEVEL%'

IF NOT DEFINED TCLKIT_EXE_PATCHLEVEL (
  SET TCLKIT_EXE_PATCHLEVEL=8.6.4
)

%_VECHO% TclKitExePatchLevel = '%TCLKIT_EXE_PATCHLEVEL%'

IF /I "%PROCESSOR%" == "x86" (
  CALL :fn_TclKitX86Variables

  IF ERRORLEVEL 1 (
    GOTO errors
  )
) ELSE IF /I "%PROCESSOR%" == "x64" (
  CALL :fn_TclKitX64Variables

  IF ERRORLEVEL 1 (
    GOTO errors
  )
) ELSE (
  GOTO usage
)

%_VECHO% TclKitVersion = '%TCLKIT_VERSION%'
%_VECHO% TclKitPatchLevel = '%TCLKIT_PATCHLEVEL%'
%_VECHO% TclKitExePatchLevel = '%TCLKIT_EXE_PATCHLEVEL%'
%_VECHO% TclKitNoEnv = '%TCLKIT_NOENV%'
%_VECHO% TclKitNoSdk = '%TCLKIT_NOSDK%'
%_VECHO% TclKitExe = '%TCLKIT_EXE%'
%_VECHO% TclKitLib = '%TCLKIT_LIB%'
%_VECHO% TclKitLibStub = '%TCLKIT_LIB_STUB%'
%_VECHO% TclKitSdk = '%TCLKIT_SDK%'
%_VECHO% TclKitSdkZip = '%TCLKIT_SDK_ZIP%'
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
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







-
+



-
-
-
-
-
+
+
+
+
+




-
+















-
+
-
-



-
-
+
-
-
+
-


















-
+
-
-



-
-
+
-
-
+
-







  GOTO errors
)

:skip_sdkUnZip

IF DEFINED TCLKIT_NOENV GOTO skip_sdkEnvironment

%__ECHO% ECHO SET TCLSH_CMD=%TEMP%\%TCLKIT_EXE%%OVERWRITE%"%ENVDIR%\SetTclKitEnv.bat"
%__ECHO% ECHO SET TCLSH_CMD=%TEMP%\%TCLKIT_EXE%%OVERWRITE%"%ROOT%\SetTclKitEnv.bat"

IF DEFINED TCLKIT_NOSDK GOTO skip_sdkVariables

%__ECHO% ECHO SET TCLINCDIR=%TEMP%\%TCLKIT_SDK%\include%APPEND%"%ENVDIR%\SetTclKitEnv.bat"
%__ECHO% ECHO SET TCLLIBDIR=%TEMP%\%TCLKIT_SDK%\lib%APPEND%"%ENVDIR%\SetTclKitEnv.bat"
%__ECHO% ECHO SET LIBTCLPATH=%TEMP%\%TCLKIT_SDK%\lib%APPEND%"%ENVDIR%\SetTclKitEnv.bat"
%__ECHO% ECHO SET LIBTCL=%TCLKIT_LIB%%APPEND%"%ENVDIR%\SetTclKitEnv.bat"
%__ECHO% ECHO SET LIBTCLSTUB=%TCLKIT_LIB_STUB%%APPEND%"%ENVDIR%\SetTclKitEnv.bat"
%__ECHO% ECHO SET TCLINCDIR=%TEMP%\%TCLKIT_SDK%\include%APPEND%"%ROOT%\SetTclKitEnv.bat"
%__ECHO% ECHO SET TCLLIBDIR=%TEMP%\%TCLKIT_SDK%\lib%APPEND%"%ROOT%\SetTclKitEnv.bat"
%__ECHO% ECHO SET LIBTCLPATH=%TEMP%\%TCLKIT_SDK%\lib%APPEND%"%ROOT%\SetTclKitEnv.bat"
%__ECHO% ECHO SET LIBTCL=%TCLKIT_LIB%%APPEND%"%ROOT%\SetTclKitEnv.bat"
%__ECHO% ECHO SET LIBTCLSTUB=%TCLKIT_LIB_STUB%%APPEND%"%ROOT%\SetTclKitEnv.bat"

:skip_sdkVariables

ECHO.
ECHO Wrote "%ENVDIR%\SetTclKitEnv.bat".
ECHO Wrote "%ROOT%\SetTclKitEnv.bat".
ECHO Please run it to set the necessary Tcl environment variables.
ECHO.

:skip_sdkEnvironment

GOTO no_errors

:fn_TclKitX86Variables
  REM
  REM NOTE: By default, use latest available version of the TclKit SDK
  REM       for x86.  However, the "default" TclKit executable for x86
  REM       is still used here because it is the only one "well-known"
  REM       to be available for download.
  REM
  IF NOT DEFINED TCLKIT_PATCHLEVEL (
    ECHO The TCLKIT_PATCHLEVEL environment variable must be set first.
    SET TCLKIT_PATCHLEVEL=8.6.6
    CALL :fn_SetErrorLevel
    GOTO :EOF
  )
  SET TCLKIT_VERSION=%TCLKIT_PATCHLEVEL:.=%
  SET TCLKIT_VERSION=%TCLKIT_VERSION:~0,2%
  IF DEFINED TCLKIT_EXE_PATCHLEVEL (
    SET TCLKIT_EXE=tclkit-%TCLKIT_EXE_PATCHLEVEL%.exe
  REM SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
  ) ELSE (
    SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
  SET TCLKIT_EXE=tclkit-8.6.4.exe
  )
  SET TCLKIT_LIB=libtclkit%TCLKIT_PATCHLEVEL:.=%.lib
  SET TCLKIT_LIB_STUB=libtclstub%TCLKIT_VERSION:.=%.a
  SET TCLKIT_SDK=libtclkit-sdk-x86-%TCLKIT_PATCHLEVEL%
  SET TCLKIT_SDK_ZIP=%TCLKIT_SDK%.zip
  SET TCLKIT_FILES=%TCLKIT_EXE%
  IF NOT DEFINED TCLKIT_NOENV IF NOT DEFINED TCLKIT_NOSDK (
    SET TCLKIT_FILES=%TCLKIT_FILES% unzip.exe %TCLKIT_SDK_ZIP%
  )
  GOTO :EOF

:fn_TclKitX64Variables
  REM
  REM NOTE: By default, use latest available version of the TclKit SDK
  REM       for x64.  However, the "default" TclKit executable for x86
  REM       is still used here because it is the only one "well-known"
  REM       to be available for download.
  REM
  IF NOT DEFINED TCLKIT_PATCHLEVEL (
    ECHO The TCLKIT_PATCHLEVEL environment variable must be set first.
    SET TCLKIT_PATCHLEVEL=8.6.6
    CALL :fn_SetErrorLevel
    GOTO :EOF
  )
  SET TCLKIT_VERSION=%TCLKIT_PATCHLEVEL:.=%
  SET TCLKIT_VERSION=%TCLKIT_VERSION:~0,2%
  IF DEFINED TCLKIT_EXE_PATCHLEVEL (
    SET TCLKIT_EXE=tclkit-%TCLKIT_EXE_PATCHLEVEL%.exe
  REM SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
  ) ELSE (
    SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
  SET TCLKIT_EXE=tclkit-8.6.4.exe
  )
  SET TCLKIT_LIB=libtclkit%TCLKIT_PATCHLEVEL:.=%.lib
  SET TCLKIT_LIB_STUB=libtclstub%TCLKIT_VERSION:.=%.a
  SET TCLKIT_SDK=libtclkit-sdk-x64-%TCLKIT_PATCHLEVEL%
  SET TCLKIT_SDK_ZIP=%TCLKIT_SDK%.zip
  SET TCLKIT_FILES=%TCLKIT_EXE%
  IF NOT DEFINED TCLKIT_NOENV IF NOT DEFINED TCLKIT_NOSDK (
    SET TCLKIT_FILES=%TCLKIT_FILES% unzip.exe %TCLKIT_SDK_ZIP%

Changes to tool/dbhash.c.

58
59
60
61
62
63
64













65
66
67


68
69
70
71
72
73
74
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







+
+
+
+
+
+
+
+
+
+
+
+
+



+
+







*/
/*
 * blk0() and blk() perform the initial expand.
 * I got the idea of expanding during the round function from SSLeay
 *
 * blk0le() for little-endian and blk0be() for big-endian.
 */
#if __GNUC__ && (defined(__i386__) || defined(__x86_64__))
/*
 * GCC by itself only generates left rotates.  Use right rotates if
 * possible to be kinder to dinky implementations with iterative rotate
 * instructions.
 */
#define SHA_ROT(op, x, k) \
        ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; })
#define rol(x,k) SHA_ROT("roll", x, k)
#define ror(x,k) SHA_ROT("rorl", x, k)

#else
/* Generic C equivalent */
#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
#define rol(x,k) SHA_ROT(x,k,32-(k))
#define ror(x,k) SHA_ROT(x,32-(k),k)
#endif


#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
    |(rol(block[i],8)&0x00FF00FF))
#define blk0be(i) block[i]
#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
    ^block[(i+2)&15]^block[i&15],1))

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
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







-
+













-
+







    ;
    zDb = argv[i];
    rc = sqlite3_open_v2(zDb, &g.db, openFlags, 0);
    if( rc ){
      fprintf(stderr, "cannot open database file '%s'\n", zDb);
      continue;
    }
    rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_schema", 0, 0, &zErrMsg);
    rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
    if( rc || zErrMsg ){
      sqlite3_close(g.db);
      g.db = 0;
      fprintf(stderr, "'%s' is not a valid SQLite database\n", zDb);
      continue;
    }

    /* Start the hash */
    hash_init();
  
    /* Hash table content */
    if( !omitContent ){
      pStmt = db_prepare(
        "SELECT name FROM sqlite_schema\n"
        "SELECT name FROM sqlite_master\n"
        " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
        "   AND name NOT LIKE 'sqlite_%%'\n"
        "   AND name LIKE '%q'\n"
        " ORDER BY name COLLATE nocase;\n",
        zLike
      );
      while( SQLITE_ROW==sqlite3_step(pStmt) ){
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
487
488
489
490
491
492
493

494
495
496
497
498
499
500
501
502
503
504
505
506







-
+












      }
      sqlite3_finalize(pStmt);
    }
  
    /* Hash the database schema */
    if( !omitSchema ){
      hash_one_query(
         "SELECT type, name, tbl_name, sql FROM sqlite_schema\n"
         "SELECT type, name, tbl_name, sql FROM sqlite_master\n"
         " WHERE tbl_name LIKE '%q'\n"
         " ORDER BY name COLLATE nocase;\n",
         zLike
      );
    }
  
    /* Finish and output the hash and close the database connection. */
    hash_finish(zDb);
    sqlite3_close(g.db);
  }
  return 0;
}

Deleted tool/enlargedb.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




































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** Try to enlarge an SQLite database by appending many unused pages.
** The resulting database will fail PRAGMA integrity_check due to the
** appended unused pages, but it should work otherwise.
**
** Usage:
**
**        enlargedb  DATABASE   N
**
** Adds N blank pages onto the end of DATABASE.  N can be decimal
** or hex.  The total number of pages after adding must be no greater
** than 4294967297
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv){
  char *zEnd;
  long long int toAppend;
  long long int currentSz;
  long long int newSz;
  FILE *f;
  size_t got;
  int pgsz;
  char zero = 0;
  unsigned char buf[100];

  if( argc!=3 ) goto usage_error;
  toAppend = strtoll(argv[2], &zEnd, 0);
  if( zEnd==argv[2] || zEnd[0] ) goto usage_error;
  if( toAppend<1 ){
    fprintf(stderr, "N must be at least 1\n");
    exit(1);
  }
  f = fopen(argv[1], "r+b");
  if( f==0 ){
    fprintf(stderr, "cannot open \"%s\" for reading and writing\n", argv[1]);
    exit(1);
  }
  got = fread(buf, 1, sizeof(buf), f);
  if( got!=sizeof(buf) ) goto not_valid_db;
  if( strcmp((char*)buf,"SQLite format 3")!=0 ) goto not_valid_db;
  pgsz = (buf[16]<<8) + buf[17];
  if( pgsz==1 ) pgsz = 65536;
  if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto not_valid_db;
  currentSz = (buf[28]<<24) + (buf[29]<<16) + (buf[30]<<8) + buf[31];
  newSz = currentSz + toAppend;
  if( newSz > 0xffffffff ) newSz = 0xffffffff;
  buf[28] = (newSz>>24) & 0xff;
  buf[29] = (newSz>>16) & 0xff;
  buf[30] = (newSz>>8) & 0xff;
  buf[31] = newSz & 0xff;
  fseek(f, 28, SEEK_SET);
  fwrite(&buf[28],4,1,f);
  fseek(f, (long)(newSz*pgsz - 1), SEEK_SET);
  fwrite(&zero,1,1,f);
  fclose(f);
  return 0;  

not_valid_db:
  fprintf(stderr,"not a valid database: %s\n", argv[1]);
  exit(1);  

usage_error:
  fprintf(stderr,"Usage: %s DATABASE N\n", argv[0]);
  exit(1);
}

Changes to tool/fast_vacuum.c.

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
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







-
+











-
+




-
+



-
+









-
+








-
+




-
+








-
+

-
+







  sqlite3_free(zSql);

  /* TODO:
  ** Set the page_size and auto_vacuum mode for zTempDb here, if desired.
  */

  /* The vacuum will occur inside of a transaction.  Set writable_schema
  ** to ON so that we can directly update the sqlite_schema table in the
  ** to ON so that we can directly update the sqlite_master table in the
  ** zTempDb database.
  */
  execSql(db, "PRAGMA writable_schema=ON");
  execSql(db, "BEGIN");


  /* Query the schema of the main database. Create a mirror schema
  ** in the temporary database.
  */
  execExecSql(db, 
      "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
      "  FROM sqlite_schema WHERE type='table' AND name!='sqlite_sequence'"
      "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
      "   AND rootpage>0"
  );
  execExecSql(db,
      "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
      "  FROM sqlite_schema WHERE sql LIKE 'CREATE INDEX %'"
      "  FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %'"
  );
  execExecSql(db,
      "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
      "  FROM sqlite_schema WHERE sql LIKE 'CREATE UNIQUE INDEX %'"
      "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'"
  );

  /* Loop through the tables in the main database. For each, do
  ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
  ** the contents to the temporary database.
  */
  execExecSql(db,
      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
      "|| ' SELECT * FROM main.' || quote(name) "
      "FROM main.sqlite_schema "
      "FROM main.sqlite_master "
      "WHERE type = 'table' AND name!='sqlite_sequence' "
      "  AND rootpage>0"
  );

  /* Copy over the sequence table
  */
  execExecSql(db,
      "SELECT 'DELETE FROM vacuum_db.' || quote(name) "
      "FROM vacuum_db.sqlite_schema WHERE name='sqlite_sequence'"
      "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence'"
  );
  execExecSql(db,
      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
      "|| ' SELECT * FROM main.' || quote(name) "
      "FROM vacuum_db.sqlite_schema WHERE name=='sqlite_sequence'"
      "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence'"
  );

  /* Copy the triggers, views, and virtual tables from the main database
  ** over to the temporary database.  None of these objects has any
  ** associated storage, so all we have to do is copy their entries
  ** from the SQLITE_MASTER table.
  */
  execSql(db,
      "INSERT INTO vacuum_db.sqlite_schema "
      "INSERT INTO vacuum_db.sqlite_master "
      "  SELECT type, name, tbl_name, rootpage, sql"
      "    FROM main.sqlite_schema"
      "    FROM main.sqlite_master"
      "   WHERE type='view' OR type='trigger'"
      "      OR (type='table' AND rootpage=0)"
  );

  /* Commit the transaction and close the database
  */
  execSql(db, "COMMIT");

Changes to tool/index_usage.c.

100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114







-
+








  if( argc!=3 ) usage(argv[0]);
  rc = sqlite3_open_v2(argv[1], &db, SQLITE_OPEN_READONLY, 0);
  if( rc ){
    printf("Cannot open \"%s\" for reading: %s\n", argv[1], sqlite3_errmsg(db));
    goto errorOut;
  }
  rc = sqlite3_prepare_v2(db, "SELECT * FROM sqlite_schema", -1, &pStmt, 0);
  rc = sqlite3_prepare_v2(db, "SELECT * FROM sqlite_master", -1, &pStmt, 0);
  if( rc ){
    printf("Cannot read the schema from \"%s\" - %s\n", argv[1],
           sqlite3_errmsg(db));
    goto errorOut;
  }
  sqlite3_finalize(pStmt);
  pStmt = 0;
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







  if( rc ){
    printf("Cannot create the result table - %s\n",
           sqlite3_errmsg(db));
    goto errorOut;
  }
  rc = sqlite3_exec(db,
     "INSERT INTO temp.idxu(tbl,idx,cnt)"
     " SELECT tbl_name, name, 0 FROM sqlite_schema"
     " SELECT tbl_name, name, 0 FROM sqlite_master"
     " WHERE type='index' AND sql IS NOT NULL", 0, 0, 0);

  /* Open the LOG database */
  zSql = sqlite3_mprintf("ATTACH %Q AS log", argv[2]);
  rc = sqlite3_exec(db, zSql, 0, 0, 0);
  sqlite3_free(zSql);
  if( rc ){
201
202
203
204
205
206
207
208
209
210



211
212
213
214
215
216
217
201
202
203
204
205
206
207



208
209
210
211
212
213
214
215
216
217







-
-
-
+
+
+







  }
  sqlite3_finalize(pStmt);

  /* Generate the report */
  rc = sqlite3_prepare_v2(db,
     "SELECT tbl, idx, cnt, "
     "   (SELECT group_concat(name,',') FROM pragma_index_info(idx))"
     " FROM temp.idxu, main.sqlite_schema"
     " WHERE temp.idxu.tbl=main.sqlite_schema.tbl_name"
     "   AND temp.idxu.idx=main.sqlite_schema.name"
     " FROM temp.idxu, main.sqlite_master"
     " WHERE temp.idxu.tbl=main.sqlite_master.tbl_name"
     "   AND temp.idxu.idx=main.sqlite_master.name"
     " ORDER BY cnt DESC, tbl, idx",
     -1, &pStmt, 0);
  if( rc ){
    printf("Cannot query the result table - %s\n",
           sqlite3_errmsg(db));
    goto errorOut;
  }

Changes to tool/lemon.c.

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
44
45
46
47
48
49
50

51
52
53
54
55
56
57







-








#ifdef TEST
#define MAXRHS 5       /* Set low to exercise exception code */
#else
#define MAXRHS 1000
#endif

extern void memory_error();
static int showPrecedenceConflict = 0;
static char *msort(char*,char**,int(*)(const char*,const char*));

/*
** Compilers are getting increasingly pedantic about type conversions
** as C evolves ever closer to Ada....  To work around the latest problems
** we have to define the following variant of strlen().
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227







-
+







void Plink_add(struct plink **, struct config *);
void Plink_copy(struct plink **, struct plink *);
void Plink_delete(struct plink *);

/********** From the file "report.h" *************************************/
void Reprint(struct lemon *);
void ReportOutput(struct lemon *);
void ReportTable(struct lemon *, int, int);
void ReportTable(struct lemon *, int);
void ReportHeader(struct lemon *);
void CompressTables(struct lemon *);
void ResortStates(struct lemon *);

/********** From the file "set.h" ****************************************/
void  SetSize(int);             /* All sets will be of size N */
char *SetNew(void);               /* A new set for element 0..N */
288
289
290
291
292
293
294


295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
287
288
289
290
291
292
293
294
295
296
297
298


299
300


301
302
303
304
305
306
307







+
+



-
-


-
-







  int nrhs;                /* Number of RHS symbols */
  struct symbol **rhs;     /* The RHS symbols */
  const char **rhsalias;   /* An alias for each RHS symbol (NULL if none) */
  int line;                /* Line number at which code begins */
  const char *code;        /* The code executed when this rule is reduced */
  const char *codePrefix;  /* Setup code before code[] above */
  const char *codeSuffix;  /* Breakdown code after code[] above */
  int noCode;              /* True if this rule has no associated C code */
  int codeEmitted;         /* True if the code has been emitted already */
  struct symbol *precsym;  /* Precedence symbol for this rule */
  int index;               /* An index number for this rule */
  int iRule;               /* Rule number as used in the generated tables */
  Boolean noCode;          /* True if this rule has no associated C code */
  Boolean codeEmitted;     /* True if the code has been emitted already */
  Boolean canReduce;       /* True if this rule is ever reduced */
  Boolean doesReduce;      /* Reduce actions occur after optimization */
  Boolean neverReduce;     /* Reduce is theoretically possible, but prevented
                           ** by actions or other outside implementation */
  struct rule *nextlhs;    /* Next rule with the same LHS */
  struct rule *next;       /* Next rule in the global list */
};

/* A configuration is a production rule of the grammar together with
** a mark (dot) showing how much of that rule has been processed so far.
** Configurations also contain a follow-set which is a list of terminal
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
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







-













-
+







struct lemon {
  struct state **sorted;   /* Table of states sorted by state number */
  struct rule *rule;       /* List of all rules */
  struct rule *startRule;  /* First rule */
  int nstate;              /* Number of states */
  int nxstate;             /* nstate with tail degenerate states removed */
  int nrule;               /* Number of rules */
  int nruleWithAction;     /* Number of rules with actions */
  int nsymbol;             /* Number of terminal and nonterminal symbols */
  int nterminal;           /* Number of terminal symbols */
  int minShiftReduce;      /* Minimum shift-reduce action value */
  int errAction;           /* Error action value */
  int accAction;           /* Accept action value */
  int noAction;            /* No-op action value */
  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 *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 */
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
415
416
417
418
419
420
421

422
423
424
425
426
427
428







-







  char *outname;           /* Name of the current output file */
  char *tokenprefix;       /* A prefix added to token names in the .h file */
  int nconflict;           /* Number of parsing conflicts */
  int nactiontab;          /* Number of entries in the yy_action[] table */
  int nlookaheadtab;       /* Number of entries in yy_lookahead[] */
  int tablesize;           /* Total table size of all tables in bytes */
  int basisflag;           /* Print only basis configurations */
  int printPreprocessed;   /* Show preprocessor output on stdout */
  int has_fallback;        /* True if any %fallback is seen in the grammar */
  int nolinenosflag;       /* True if #line statements should not be printed */
  char *argv0;             /* Name of the program */
};

#define MemoryCheck(X) if((X)==0){ \
  extern void memory_error(); \
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
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







-
+


-
+


-
-
+
+



-
-
+
+

-
-
+
+







/****************** From the file "action.c" *******************************/
/*
** Routines processing parser actions in the LEMON parser generator.
*/

/* Allocate a new parser action */
static struct action *Action_new(void){
  static struct action *actionfreelist = 0;
  static struct action *freelist = 0;
  struct action *newaction;

  if( actionfreelist==0 ){
  if( freelist==0 ){
    int i;
    int amt = 100;
    actionfreelist = (struct action *)calloc(amt, sizeof(struct action));
    if( actionfreelist==0 ){
    freelist = (struct action *)calloc(amt, sizeof(struct action));
    if( freelist==0 ){
      fprintf(stderr,"Unable to allocate memory for a new parser action.");
      exit(1);
    }
    for(i=0; i<amt-1; i++) actionfreelist[i].next = &actionfreelist[i+1];
    actionfreelist[amt-1].next = 0;
    for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
    freelist[amt-1].next = 0;
  }
  newaction = actionfreelist;
  actionfreelist = actionfreelist->next;
  newaction = freelist;
  freelist = freelist->next;
  return newaction;
}

/* Compare two actions for sorting purposes.  Return negative, zero, or
** positive if the first action is less than, equal to, or greater than
** the first
*/
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
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







-
-
-
+
+
+















-
-
-
+
+
+







  Configlist_init();

  /* Find the start symbol */
  if( lemp->start ){
    sp = Symbol_find(lemp->start);
    if( sp==0 ){
      ErrorMsg(lemp->filename,0,
        "The specified start symbol \"%s\" is not "
        "in a nonterminal of the grammar.  \"%s\" will be used as the start "
        "symbol instead.",lemp->start,lemp->startRule->lhs->name);
"The specified start symbol \"%s\" is not \
in a nonterminal of the grammar.  \"%s\" will be used as the start \
symbol instead.",lemp->start,lemp->startRule->lhs->name);
      lemp->errorcnt++;
      sp = lemp->startRule->lhs;
    }
  }else{
    sp = lemp->startRule->lhs;
  }

  /* Make sure the start symbol doesn't occur on the right-hand side of
  ** any rule.  Report an error if it does.  (YACC would generate a new
  ** start symbol in this case.) */
  for(rp=lemp->rule; rp; rp=rp->next){
    int i;
    for(i=0; i<rp->nrhs; i++){
      if( rp->rhs[i]==sp ){   /* FIX ME:  Deal with multiterminals */
        ErrorMsg(lemp->filename,0,
          "The start symbol \"%s\" occurs on the "
          "right-hand side of a rule. This will result in a parser which "
          "does not work properly.",sp->name);
"The start symbol \"%s\" occurs on the \
right-hand side of a rule. This will result in a parser which \
does not work properly.",sp->name);
        lemp->errorcnt++;
      }
    }
  }

  /* The basis configuration set for the first state
  ** is all rules which have the start symbol as their
1023
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030
1031
1032







-
+







  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
  /* 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 */
1587
1588
1589
1590
1591
1592
1593
1594

1595
1596
1597
1598
1599
1600
1601

1602
1603
1604
1605
1606
1607
1608
1582
1583
1584
1585
1586
1587
1588

1589
1590
1591
1592
1593
1594
1595

1596
1597
1598
1599
1600
1601
1602
1603







-
+






-
+







  return pFirst;
}

/*
** Sort a list of rules in order of increasing iRule value
*/
static struct rule *Rule_sort(struct rule *rp){
  unsigned int i;
  int i;
  struct rule *pNext;
  struct rule *x[32];
  memset(x, 0, sizeof(x));
  while( rp ){
    pNext = rp->next;
    rp->next = 0;
    for(i=0; i<sizeof(x)/sizeof(x[0])-1 && x[i]; i++){
    for(i=0; i<sizeof(x)/sizeof(x[0]) && x[i]; i++){
      rp = Rule_merge(x[i], rp);
      x[i] = 0;
    }
    x[i] = rp;
    rp = pNext;
  }
  rp = 0;
1621
1622
1623
1624
1625
1626
1627
1628


1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697

1698
1699
1700
1701
1702
1703
1704
1616
1617
1618
1619
1620
1621
1622

1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633


1634
1635
1636
1637
1638
1639

1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651


1652
1653
1654
1655
1656
1657
1658
1659
1660
1661

1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681

1682
1683
1684
1685

1686
1687
1688
1689
1690
1691
1692
1693







-
+
+









-
-






-












-
-










-




















-




-
+







  int nLabel = lemonStrlen(zLabel);
  printf("  %s%.*s %5d\n", zLabel,
         35-nLabel, "................................",
         iValue);
}

/* The main program.  Parse the command line and do it... */
int main(int argc, char **argv){
int main(int argc, char **argv)
{
  static int version = 0;
  static int rpflag = 0;
  static int basisflag = 0;
  static int compress = 0;
  static int quiet = 0;
  static int statistics = 0;
  static int mhflag = 0;
  static int nolinenosflag = 0;
  static int noResort = 0;
  static int sqlFlag = 0;
  static int printPP = 0;
  
  static struct s_options options[] = {
    {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."},
    {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."},
    {OPT_FSTR, "d", (char*)&handle_d_option, "Output directory.  Default '.'"},
    {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
    {OPT_FLAG, "E", (char*)&printPP, "Print input file after preprocessing."},
    {OPT_FSTR, "f", 0, "Ignored.  (Placeholder for -f compiler options.)"},
    {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},
    {OPT_FSTR, "I", 0, "Ignored.  (Placeholder for '-I' compiler options.)"},
    {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."},
    {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."},
    {OPT_FSTR, "O", 0, "Ignored.  (Placeholder for '-O' compiler options.)"},
    {OPT_FLAG, "p", (char*)&showPrecedenceConflict,
                    "Show conflicts resolved by precedence rules"},
    {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."},
    {OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states"},
    {OPT_FLAG, "s", (char*)&statistics,
                                   "Print parser stats to standard output."},
    {OPT_FLAG, "S", (char*)&sqlFlag,
                    "Generate the *.sql file describing the parser tables."},
    {OPT_FLAG, "x", (char*)&version, "Print the version number."},
    {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."},
    {OPT_FSTR, "W", 0, "Ignored.  (Placeholder for '-W' compiler options.)"},
    {OPT_FLAG,0,0,0}
  };
  int i;
  int exitcode;
  struct lemon lem;
  struct rule *rp;

  (void)argc;
  OptInit(argv,options,stderr);
  if( version ){
     printf("Lemon version 1.0\n");
     exit(0);
  }
  if( OptNArgs()!=1 ){
    fprintf(stderr,"Exactly one filename argument is required.\n");
    exit(1);
  }
  memset(&lem, 0, sizeof(lem));
  lem.errorcnt = 0;

  /* Initialize the machine */
  Strsafe_init();
  Symbol_init();
  State_init();
  lem.argv0 = argv[0];
  lem.filename = OptArg(0);
  lem.basisflag = basisflag;
  lem.nolinenosflag = nolinenosflag;
  lem.printPreprocessed = printPP;
  Symbol_new("$");

  /* Parse the input file */
  Parse(&lem);
  if( lem.printPreprocessed || lem.errorcnt ) exit(lem.errorcnt);
  if( lem.errorcnt ) exit(lem.errorcnt);
  if( lem.nrule==0 ){
    fprintf(stderr,"Empty grammar.\n");
    exit(1);
  }
  lem.errsym = Symbol_find("error");

  /* Count and index the symbols of the grammar */
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1706
1707
1708
1709
1710
1711
1712

1713
1714
1715
1716
1717
1718
1719







-







  /* Assign sequential rule numbers.  Start with 0.  Put rules that have no
  ** reduce action C-code associated with them last, so that the switch()
  ** statement that selects reduction actions will have a smaller jump table.
  */
  for(i=0, rp=lem.rule; rp; rp=rp->next){
    rp->iRule = rp->code ? i++ : -1;
  }
  lem.nruleWithAction = i;
  for(rp=lem.rule; rp; rp=rp->next){
    if( rp->iRule<0 ) rp->iRule = i++;
  }
  lem.startRule = lem.rule;
  lem.rule = Rule_sort(lem.rule);

  /* Generate a reprint of the grammar, if requested on the command line */
1765
1766
1767
1768
1769
1770
1771
1772

1773
1774
1775
1776
1777
1778
1779
1753
1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765
1766
1767







-
+







    ** generated parser tables smaller. */
    if( noResort==0 ) ResortStates(&lem);

    /* Generate a report of the parser generated.  (the "y.output" file) */
    if( !quiet ) ReportOutput(&lem);

    /* Generate the source code for the parser */
    ReportTable(&lem, mhflag, sqlFlag);
    ReportTable(&lem, mhflag);

    /* Produce a header file for use by the scanner.  (This step is
    ** omitted if the "-m" option is used because makeheaders will
    ** generate the file for us.) */
    if( !mhflag ) ReportHeader(&lem);
  }
  if( statistics ){
1883
1884
1885
1886
1887
1888
1889
1890

1891
1892
1893
1894
1895
1896
1897
1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881
1882
1883
1884
1885







-
+







** 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.
**   orginally in list.
**
** Side effects:
**   The "next" pointers for elements in list are changed.
*/
#define LISTSIZE 30
static char *msort(
  char *list,
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
1903
1904
1905
1906
1907
1908
1909

1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922





1923
1924
1925
1926
1927
1928
1929

1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945



1946
1947
1948
1949
1950
1951

1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968

1969
1970

1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1992







-
+












-
-
-
-
-
+
+
+
+
+


-
+















-
-
-
+
+
+



-
+
















-
+

-
+













-
+







    set[i] = ep;
  }
  ep = 0;
  for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(set[i],ep,cmp,offset);
  return ep;
}
/************************ From the file "option.c" **************************/
static char **g_argv;
static char **argv;
static struct s_options *op;
static FILE *errstream;

#define ISOPT(X) ((X)[0]=='-'||(X)[0]=='+'||strchr((X),'=')!=0)

/*
** Print the command line with a carrot pointing to the k-th character
** of the n-th field.
*/
static void errline(int n, int k, FILE *err)
{
  int spcnt, i;
  if( g_argv[0] ) fprintf(err,"%s",g_argv[0]);
  spcnt = lemonStrlen(g_argv[0]) + 1;
  for(i=1; i<n && g_argv[i]; i++){
    fprintf(err," %s",g_argv[i]);
    spcnt += lemonStrlen(g_argv[i])+1;
  if( argv[0] ) fprintf(err,"%s",argv[0]);
  spcnt = lemonStrlen(argv[0]) + 1;
  for(i=1; i<n && argv[i]; i++){
    fprintf(err," %s",argv[i]);
    spcnt += lemonStrlen(argv[i])+1;
  }
  spcnt += k;
  for(; g_argv[i]; i++) fprintf(err," %s",g_argv[i]);
  for(; argv[i]; i++) fprintf(err," %s",argv[i]);
  if( spcnt<20 ){
    fprintf(err,"\n%*s^-- here\n",spcnt,"");
  }else{
    fprintf(err,"\n%*shere --^\n",spcnt-7,"");
  }
}

/*
** Return the index of the N-th non-switch argument.  Return -1
** if N is out of range.
*/
static int argindex(int n)
{
  int i;
  int dashdash = 0;
  if( g_argv!=0 && *g_argv!=0 ){
    for(i=1; g_argv[i]; i++){
      if( dashdash || !ISOPT(g_argv[i]) ){
  if( argv!=0 && *argv!=0 ){
    for(i=1; argv[i]; i++){
      if( dashdash || !ISOPT(argv[i]) ){
        if( n==0 ) return i;
        n--;
      }
      if( strcmp(g_argv[i],"--")==0 ) dashdash = 1;
      if( strcmp(argv[i],"--")==0 ) dashdash = 1;
    }
  }
  return -1;
}

static char emsg[] = "Command line syntax error: ";

/*
** Process a flag command line argument.
*/
static int handleflags(int i, FILE *err)
{
  int v;
  int errcnt = 0;
  int j;
  for(j=0; op[j].label; j++){
    if( strncmp(&g_argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break;
    if( strncmp(&argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break;
  }
  v = g_argv[i][0]=='-' ? 1 : 0;
  v = argv[i][0]=='-' ? 1 : 0;
  if( op[j].label==0 ){
    if( err ){
      fprintf(err,"%sundefined option.\n",emsg);
      errline(i,1,err);
    }
    errcnt++;
  }else if( op[j].arg==0 ){
    /* Ignore this option */
  }else if( op[j].type==OPT_FLAG ){
    *((int*)op[j].arg) = v;
  }else if( op[j].type==OPT_FFLAG ){
    (*(void(*)(int))(op[j].arg))(v);
  }else if( op[j].type==OPT_FSTR ){
    (*(void(*)(char *))(op[j].arg))(&g_argv[i][2]);
    (*(void(*)(char *))(op[j].arg))(&argv[i][2]);
  }else{
    if( err ){
      fprintf(err,"%smissing argument on switch.\n",emsg);
      errline(i,1,err);
    }
    errcnt++;
  }
2012
2013
2014
2015
2016
2017
2018
2019

2020
2021
2022
2023

2024
2025
2026
2027
2028
2029
2030
2000
2001
2002
2003
2004
2005
2006

2007
2008
2009
2010

2011
2012
2013
2014
2015
2016
2017
2018







-
+



-
+







{
  int lv = 0;
  double dv = 0.0;
  char *sv = 0, *end;
  char *cp;
  int j;
  int errcnt = 0;
  cp = strchr(g_argv[i],'=');
  cp = strchr(argv[i],'=');
  assert( cp!=0 );
  *cp = 0;
  for(j=0; op[j].label; j++){
    if( strcmp(g_argv[i],op[j].label)==0 ) break;
    if( strcmp(argv[i],op[j].label)==0 ) break;
  }
  *cp = '=';
  if( op[j].label==0 ){
    if( err ){
      fprintf(err,"%sundefined option.\n",emsg);
      errline(i,0,err);
    }
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
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







-
+










-
+







      case OPT_DBL:
      case OPT_FDBL:
        dv = strtod(cp,&end);
        if( *end ){
          if( err ){
            fprintf(err,
               "%sillegal character in floating-point argument.\n",emsg);
            errline(i,(int)((char*)end-(char*)g_argv[i]),err);
            errline(i,(int)((char*)end-(char*)argv[i]),err);
          }
          errcnt++;
        }
        break;
      case OPT_INT:
      case OPT_FINT:
        lv = strtol(cp,&end,0);
        if( *end ){
          if( err ){
            fprintf(err,"%sillegal character in integer argument.\n",emsg);
            errline(i,(int)((char*)end-(char*)g_argv[i]),err);
            errline(i,(int)((char*)end-(char*)argv[i]),err);
          }
          errcnt++;
        }
        break;
      case OPT_STR:
      case OPT_FSTR:
        sv = cp;
2094
2095
2096
2097
2098
2099
2100
2101

2102
2103
2104

2105
2106
2107


2108
2109

2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129




2130
2131
2132
2133
2134
2135
2136
2137
2138
2139

2140
2141
2142
2143
2144
2145
2146
2082
2083
2084
2085
2086
2087
2088

2089
2090
2091

2092
2093


2094
2095
2096

2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113




2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126

2127
2128
2129
2130
2131
2132
2133
2134







-
+


-
+

-
-
+
+

-
+
















-
-
-
-
+
+
+
+









-
+







  }
  return errcnt;
}

int OptInit(char **a, struct s_options *o, FILE *err)
{
  int errcnt = 0;
  g_argv = a;
  argv = a;
  op = o;
  errstream = err;
  if( g_argv && *g_argv && op ){
  if( argv && *argv && op ){
    int i;
    for(i=1; g_argv[i]; i++){
      if( g_argv[i][0]=='+' || g_argv[i][0]=='-' ){
    for(i=1; argv[i]; i++){
      if( argv[i][0]=='+' || argv[i][0]=='-' ){
        errcnt += handleflags(i,err);
      }else if( strchr(g_argv[i],'=') ){
      }else if( strchr(argv[i],'=') ){
        errcnt += handleswitch(i,err);
      }
    }
  }
  if( errcnt>0 ){
    fprintf(err,"Valid command line options for \"%s\" are:\n",*a);
    OptPrint();
    exit(1);
  }
  return 0;
}

int OptNArgs(void){
  int cnt = 0;
  int dashdash = 0;
  int i;
  if( g_argv!=0 && g_argv[0]!=0 ){
    for(i=1; g_argv[i]; i++){
      if( dashdash || !ISOPT(g_argv[i]) ) cnt++;
      if( strcmp(g_argv[i],"--")==0 ) dashdash = 1;
  if( argv!=0 && argv[0]!=0 ){
    for(i=1; argv[i]; i++){
      if( dashdash || !ISOPT(argv[i]) ) cnt++;
      if( strcmp(argv[i],"--")==0 ) dashdash = 1;
    }
  }
  return cnt;
}

char *OptArg(int n)
{
  int i;
  i = argindex(n);
  return i>=0 ? g_argv[i] : 0;
  return i>=0 ? argv[i] : 0;
}

void OptErr(int n)
{
  int i;
  i = argindex(n);
  if( i>=0 ) errline(i,0,errstream);
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
2250
2251
2252
2253
2254
2255
2256

2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268


2269
2270
2271
2272
2273


2274
2275
2276


2277
2278
2279
2280
2281
2282
2283







-
+











-
-
+
+



-
-
+
+

-
-







#endif
  switch( psp->state ){
    case INITIALIZE:
      psp->prevrule = 0;
      psp->preccounter = 0;
      psp->firstrule = psp->lastrule = 0;
      psp->gp->nrule = 0;
      /* fall through */
      /* Fall thru to next case */
    case WAITING_FOR_DECL_OR_RULE:
      if( x[0]=='%' ){
        psp->state = WAITING_FOR_DECL_KEYWORD;
      }else if( ISLOWER(x[0]) ){
        psp->lhs = Symbol_new(x);
        psp->nrhs = 0;
        psp->lhsalias = 0;
        psp->state = WAITING_FOR_ARROW;
      }else if( x[0]=='{' ){
        if( psp->prevrule==0 ){
          ErrorMsg(psp->filename,psp->tokenlineno,
            "There is no prior rule upon which to attach the code "
            "fragment which begins on this line.");
"There is no prior rule upon which to attach the code \
fragment which begins on this line.");
          psp->errorcnt++;
        }else if( psp->prevrule->code!=0 ){
          ErrorMsg(psp->filename,psp->tokenlineno,
            "Code fragment beginning on this line is not the first "
            "to follow the previous rule.");
"Code fragment beginning on this line is not the first \
to follow the previous rule.");
          psp->errorcnt++;
        }else if( strcmp(x, "{NEVER-REDUCE")==0 ){
          psp->prevrule->neverReduce = 1;
        }else{
          psp->prevrule->line = psp->tokenlineno;
          psp->prevrule->code = &x[1];
          psp->prevrule->noCode = 0;
        }
      }else if( x[0]=='[' ){
        psp->state = PRECEDENCE_MARK_1;
2309
2310
2311
2312
2313
2314
2315
2316
2317


2318
2319
2320
2321
2322
2323
2324
2295
2296
2297
2298
2299
2300
2301


2302
2303
2304
2305
2306
2307
2308
2309
2310







-
-
+
+







        psp->errorcnt++;
      }else if( psp->prevrule==0 ){
        ErrorMsg(psp->filename,psp->tokenlineno,
          "There is no prior rule to assign precedence \"[%s]\".",x);
        psp->errorcnt++;
      }else if( psp->prevrule->precsym!=0 ){
        ErrorMsg(psp->filename,psp->tokenlineno,
          "Precedence mark on this line is not the first "
          "to follow the previous rule.");
"Precedence mark on this line is not the first \
to follow the previous rule.");
        psp->errorcnt++;
      }else{
        psp->prevrule->precsym = Symbol_new(x);
      }
      psp->state = PRECEDENCE_MARK_2;
      break;
    case PRECEDENCE_MARK_2:
2422
2423
2424
2425
2426
2427
2428
2429

2430
2431
2432
2433
2434
2435
2436
2408
2409
2410
2411
2412
2413
2414

2415
2416
2417
2418
2419
2420
2421
2422







-
+







          psp->errorcnt++;
          psp->state = RESYNC_AFTER_RULE_ERROR;
        }else{
          psp->rhs[psp->nrhs] = Symbol_new(x);
          psp->alias[psp->nrhs] = 0;
          psp->nrhs++;
        }
      }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 && ISUPPER(x[1]) ){
      }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){
        struct symbol *msp = psp->rhs[psp->nrhs-1];
        if( msp->type!=MULTITERMINAL ){
          struct symbol *origsp = msp;
          msp = (struct symbol *) calloc(1,sizeof(*msp));
          memset(msp, 0, sizeof(*msp));
          msp->type = MULTITERMINAL;
          msp->nsubsym = 1;
2634
2635
2636
2637
2638
2639
2640
2641

2642
2643
2644

2645
2646
2647
2648
2649
2650
2651
2620
2621
2622
2623
2624
2625
2626

2627



2628
2629
2630
2631
2632
2633
2634
2635







-
+
-
-
-
+







        if( *psp->declargslot ){
          zOld = *psp->declargslot;
        }else{
          zOld = "";
        }
        nOld = lemonStrlen(zOld);
        n = nOld + nNew + 20;
        addLineMacro = !psp->gp->nolinenosflag
        addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro &&
                       && psp->insertLineMacro
                       && psp->tokenlineno>1
                       && (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0);
                        (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0);
        if( addLineMacro ){
          for(z=psp->filename, nBack=0; *z; z++){
            if( *z=='\\' ) nBack++;
          }
          lemon_sprintf(zLine, "#line %d ", psp->tokenlineno);
          nLine = lemonStrlen(zLine);
          n += nLine + lemonStrlen(psp->filename) + nBack;
2740
2741
2742
2743
2744
2745
2746
2747

2748
2749
2750
2751
2752
2753
2754
2724
2725
2726
2727
2728
2729
2730

2731
2732
2733
2734
2735
2736
2737
2738







-
+







          psp->errorcnt++;
        }
      }
      break;
    case WAITING_FOR_CLASS_ID:
      if( !ISLOWER(x[0]) ){
        ErrorMsg(psp->filename, psp->tokenlineno,
          "%%token_class must be followed by an identifier: %s", x);
          "%%token_class must be followed by an identifier: ", x);
        psp->errorcnt++;
        psp->state = RESYNC_AFTER_DECL_ERROR;
     }else if( Symbol_find(x) ){
        ErrorMsg(psp->filename, psp->tokenlineno,
          "Symbol \"%s\" already used", x);
        psp->errorcnt++;
        psp->state = RESYNC_AFTER_DECL_ERROR;
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889

2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915

2916
2917

2918
2919
2920
2921
2922
2923

2924
2925
2926
2927
2928
2929
2930
2931









2932
2933
2934
2935
2936
2937
2938
2765
2766
2767
2768
2769
2770
2771































































































2772
2773
2774
2775
2776
2777

2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793











2794


2795
2796
2797
2798



2799








2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+















-
-
-
-
-
-
-
-
-
-
-
+
-
-
+



-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+







    case RESYNC_AFTER_DECL_ERROR:
      if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
      if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD;
      break;
  }
}

/* The text in the input is part of the argument to an %ifdef or %ifndef.
** Evaluate the text as a boolean expression.  Return true or false.
*/
static int eval_preprocessor_boolean(char *z, int lineno){
  int neg = 0;
  int res = 0;
  int okTerm = 1;
  int i;
  for(i=0; z[i]!=0; i++){
    if( ISSPACE(z[i]) ) continue;
    if( z[i]=='!' ){
      if( !okTerm ) goto pp_syntax_error;
      neg = !neg;
      continue;
    }
    if( z[i]=='|' && z[i+1]=='|' ){
      if( okTerm ) goto pp_syntax_error;
      if( res ) return 1;
      i++;
      okTerm = 1;
      continue;
    }
    if( z[i]=='&' && z[i+1]=='&' ){
      if( okTerm ) goto pp_syntax_error;
      if( !res ) return 0;
      i++;
      okTerm = 1;
      continue;
    }
    if( z[i]=='(' ){
      int k;
      int n = 1;
      if( !okTerm ) goto pp_syntax_error;
      for(k=i+1; z[k]; k++){
        if( z[k]==')' ){
          n--;
          if( n==0 ){
            z[k] = 0;
            res = eval_preprocessor_boolean(&z[i+1], -1);
            z[k] = ')';
            if( res<0 ){
              i = i-res;
              goto pp_syntax_error;
            }
            i = k;
            break;
          }
        }else if( z[k]=='(' ){
          n++;
        }else if( z[k]==0 ){
          i = k;
          goto pp_syntax_error;
        }
      }
      if( neg ){
        res = !res;
        neg = 0;
      }
      okTerm = 0;
      continue;
    }
    if( ISALPHA(z[i]) ){
      int j, k, n;
      if( !okTerm ) goto pp_syntax_error;
      for(k=i+1; ISALNUM(z[k]) || z[k]=='_'; k++){}
      n = k - i;
      res = 0;
      for(j=0; j<nDefine; j++){
        if( strncmp(azDefine[j],&z[i],n)==0 && azDefine[j][n]==0 ){
          res = 1;
          break;
        }
      }
      i = k-1;
      if( neg ){
        res = !res;
        neg = 0;
      }
      okTerm = 0;
      continue;
    }
    goto pp_syntax_error;
  }
  return res;

pp_syntax_error:
  if( lineno>0 ){
    fprintf(stderr, "%%if syntax error on line %d.\n", lineno);
    fprintf(stderr, "  %.*s <-- syntax error here\n", i+1, z);
    exit(1);
  }else{
    return -(i+1);
  }
}

/* Run the preprocessor over the input file text.  The global variables
** azDefine[0] through azDefine[nDefine-1] contains the names of all defined
** macros.  This routine looks for "%ifdef" and "%ifndef" and "%endif" and
** comments them out.  Text in between is also commented out as appropriate.
*/
static void preprocess_input(char *z){
  int i, j, k;
  int i, j, k, n;
  int exclude = 0;
  int start = 0;
  int lineno = 1;
  int start_lineno = 1;
  for(i=0; z[i]; i++){
    if( z[i]=='\n' ) lineno++;
    if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue;
    if( strncmp(&z[i],"%endif",6)==0 && ISSPACE(z[i+6]) ){
      if( exclude ){
        exclude--;
        if( exclude==0 ){
          for(j=start; j<i; j++) if( z[j]!='\n' ) z[j] = ' ';
        }
      }
      for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' ';
    }else if( strncmp(&z[i],"%else",5)==0 && ISSPACE(z[i+5]) ){
      if( exclude==1){
        exclude = 0;
        for(j=start; j<i; j++) if( z[j]!='\n' ) z[j] = ' ';
      }else if( exclude==0 ){
        exclude = 1;
        start = i;
        start_lineno = lineno;
      }
      for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' ';
    }else if( strncmp(&z[i],"%ifdef ",7)==0 
    }else if( (strncmp(&z[i],"%ifdef",6)==0 && ISSPACE(z[i+6]))
          || strncmp(&z[i],"%if ",4)==0
          || strncmp(&z[i],"%ifndef ",8)==0 ){
          || (strncmp(&z[i],"%ifndef",7)==0 && ISSPACE(z[i+7])) ){
      if( exclude ){
        exclude++;
      }else{
        int isNot;
        int iBool;
        for(j=i; z[j] && !ISSPACE(z[j]); j++){}
        for(j=i+7; ISSPACE(z[j]); j++){}
        iBool = j;
        isNot = (j==i+7);
        while( z[j] && z[j]!='\n' ){ j++; }
        k = z[j];
        z[j] = 0;
        exclude = eval_preprocessor_boolean(&z[iBool], lineno);
        z[j] = k;
        if( !isNot ) exclude = !exclude;
        for(n=0; z[j+n] && !ISSPACE(z[j+n]); n++){}
        exclude = 1;
        for(k=0; k<nDefine; k++){
          if( strncmp(azDefine[k],&z[j],n)==0 && lemonStrlen(azDefine[k])==n ){
            exclude = 0;
            break;
          }
        }
        if( z[i+3]=='n' ) exclude = !exclude;
        if( exclude ){
          start = i;
          start_lineno = lineno;
        }
      }
      for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' ';
    }
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
2869
2870
2871
2872
2873
2874
2875




2876
2877
2878
2879
2880
2881
2882







-
-
-
-







    return;
  }
  fclose(fp);
  filebuf[filesize] = 0;

  /* Make an initial pass through the file to handle %ifdef and %ifndef */
  preprocess_input(filebuf);
  if( gp->printPreprocessed ){
    printf("%s\n", filebuf);
    return;
  }

  /* Now scan the text of the input file */
  lineno = 1;
  for(cp=filebuf; (c= *cp)!=0; ){
    if( c=='\n' ) lineno++;              /* Keep track of the line number */
    if( ISSPACE(c) ){ cp++; continue; }  /* Skip all white space */
    if( c=='/' && cp[1]=='/' ){          /* Skip C++ style comments */
3026
3027
3028
3029
3030
3031
3032
3033

3034
3035
3036
3037
3038
3039
3040
3041
2899
2900
2901
2902
2903
2904
2905

2906

2907
2908
2909
2910
2911
2912
2913







-
+
-







      cp++;
      while( (c= *cp)!=0 && c!='\"' ){
        if( c=='\n' ) lineno++;
        cp++;
      }
      if( c==0 ){
        ErrorMsg(ps.filename,startline,
            "String starting on this line is not terminated before "
"String starting on this line is not terminated before the end of the file.");
            "the end of the file.");
        ps.errorcnt++;
        nextcp = cp;
      }else{
        nextcp = cp+1;
      }
    }else if( c=='{' ){               /* A block of C code */
      int level;
3066
3067
3068
3069
3070
3071
3072
3073

3074
3075
3076
3077
3078
3079
3080
3081
2938
2939
2940
2941
2942
2943
2944

2945

2946
2947
2948
2949
2950
2951
2952







-
+
-







            if( prevc=='\\' ) prevc = 0;
            else              prevc = c;
          }
        }
      }
      if( c==0 ){
        ErrorMsg(ps.filename,ps.tokenlineno,
          "C code starting on this line is not terminated before "
"C code starting on this line is not terminated before the end of the file.");
          "the end of the file.");
        ps.errorcnt++;
        nextcp = cp;
      }else{
        nextcp = cp+1;
      }
    }else if( ISALNUM(c) ){          /* Identifiers */
      while( (c= *cp)!=0 && (ISALNUM(c) || c=='_') ) cp++;
3509
3510
3511
3512
3513
3514
3515
3516

3517
3518
3519
3520
3521


3522
3523
3524
3525
3526
3527
3528
3380
3381
3382
3383
3384
3385
3386

3387
3388
3389
3390


3391
3392
3393
3394
3395
3396
3397
3398
3399







-
+



-
-
+
+







    fprintf(fp,"\n");
  }
  fclose(fp);
  return;
}

/* Search for the file "name" which is in the same directory as
** the executable */
** the exacutable */
PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
{
  const char *pathlist;
  char *pathbufptr = 0;
  char *pathbuf = 0;
  char *pathbufptr;
  char *pathbuf;
  char *path,*cp;
  char c;

#ifdef __WIN32__
  cp = strrchr(argv0,'\\');
#else
  cp = strrchr(argv0,'/');
3548
3549
3550
3551
3552
3553
3554
3555
3556


3557
3558
3559
3560
3561
3562
3563
3419
3420
3421
3422
3423
3424
3425


3426
3427
3428
3429
3430
3431
3432
3433
3434







-
-
+
+







        *cp = 0;
        lemon_sprintf(path,"%s/%s",pathbuf,name);
        *cp = c;
        if( c==0 ) pathbuf[0] = 0;
        else pathbuf = &cp[1];
        if( access(path,modemask)==0 ) break;
      }
    }
    free(pathbufptr);
      free(pathbufptr);
    }
  }
  return path;
}

/* Given an action, compute the integer value for that action
** which is to be put in the action table of the generated machine.
** Return negative if no action should be generated.
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
3486
3487
3488
3489
3490
3491
3492










3493
3494
3495
3496
3497
3498
3499
3500

3501
3502
3503
3504
3505
3506
3507







-
-
-
-
-
-
-
-
-
-








-







        }
      }
    }
    fprintf(out,"%s",&line[iStart]);
  }
}

/* Skip forward past the header of the template file to the first "%%"
*/
PRIVATE void tplt_skip_header(FILE *in, int *lineno)
{
  char line[LINESIZE];
  while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){
    (*lineno)++;
  }
}

/* The next function finds the template file and opens it, returning
** a pointer to the opened file. */
PRIVATE FILE *tplt_open(struct lemon *lemp)
{
  static char templatename[] = "lempar.c";
  char buf[1000];
  FILE *in;
  char *tpltname;
  char *toFree = 0;
  char *cp;

  /* first, see if user specified a template filename on the command line. */
  if (user_templatename != 0) {
    if( access(user_templatename,004)==-1 ){
      fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
        user_templatename);
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
3525
3526
3527
3528
3529
3530
3531

3532
3533
3534
3535
3536
3537
3538
3539
3540
3541

3542
3543
3544
3545

3546
3547
3548
3549
3550
3551
3552







-
+









-
+

+

-







    lemon_sprintf(buf,"%s.lt",lemp->filename);
  }
  if( access(buf,004)==0 ){
    tpltname = buf;
  }else if( access(templatename,004)==0 ){
    tpltname = templatename;
  }else{
    toFree = tpltname = pathsearch(lemp->argv0,templatename,0);
    tpltname = pathsearch(lemp->argv0,templatename,0);
  }
  if( tpltname==0 ){
    fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
    templatename);
    lemp->errorcnt++;
    return 0;
  }
  in = fopen(tpltname,"rb");
  if( in==0 ){
    fprintf(stderr,"Can't open the template file \"%s\".\n",tpltname);
    fprintf(stderr,"Can't open the template file \"%s\".\n",templatename);
    lemp->errorcnt++;
    return 0;
  }
  free(toFree);
  return in;
}

/* Print a #line directive line to the output file. */
PRIVATE void tplt_linedir(FILE *out, int lineno, char *filename)
{
  fprintf(out,"#line %d \"",lineno);
3864
3865
3866
3867
3868
3869
3870
3871

3872
3873
3874
3875
3876
3877
3878
3724
3725
3726
3727
3728
3729
3730

3731
3732
3733
3734
3735
3736
3737
3738







-
+









  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. */
    ** 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;
3984
3985
3986
3987
3988
3989
3990
3991

3992
3993
3994
3995
3996
3997
3998
3844
3845
3846
3847
3848
3849
3850

3851
3852
3853
3854
3855
3856
3857
3858







-
+







    if( rp->rhsalias[i] ){
      if( i>0 ){
        int j;
        if( rp->lhsalias && strcmp(rp->lhsalias,rp->rhsalias[i])==0 ){
          ErrorMsg(lemp->filename,rp->ruleline,
            "%s(%s) has the same label as the LHS but is not the left-most "
            "symbol on the RHS.",
            rp->rhs[i]->name, rp->rhsalias[i]);
            rp->rhs[i]->name, rp->rhsalias);
          lemp->errorcnt++;
        }
        for(j=0; j<i; j++){
          if( rp->rhsalias[j] && strcmp(rp->rhsalias[j],rp->rhsalias[i])==0 ){
            ErrorMsg(lemp->filename,rp->ruleline,
              "Label %s used for multiple symbols on the RHS of a rule.",
              rp->rhsalias[i]);
4278
4279
4280
4281
4282
4283
4284
4285

4286
4287
4288

4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410

4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425

4426

4427

4428
4429
4430
4431
4432
4433
4434






4435
4436
4437
4438
4439
4440
4441
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
4190
4191
4192

4193







4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206







-
+
-

-
+







-






-















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-











-
-

+

+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+







  }
}


/* Generate C source code for the parser */
void ReportTable(
  struct lemon *lemp,
  int mhflag,     /* Output in makeheaders format if true */
  int mhflag     /* Output in makeheaders format if true */
  int sqlFlag     /* Generate the *.sql file too */
){
  FILE *out, *in, *sql;
  FILE *out, *in;
  char line[LINESIZE];
  int  lineno;
  struct state *stp;
  struct action *ap;
  struct rule *rp;
  struct acttab *pActtab;
  int i, j, n, sz;
  int nLookAhead;
  int szActionType;     /* sizeof(YYACTIONTYPE) */
  int szCodeType;       /* sizeof(YYCODETYPE)   */
  const char *name;
  int mnTknOfst, mxTknOfst;
  int mnNtOfst, mxNtOfst;
  struct axset *ax;
  char *prefix;

  lemp->minShiftReduce = lemp->nstate;
  lemp->errAction = lemp->minShiftReduce + lemp->nrule;
  lemp->accAction = lemp->errAction + 1;
  lemp->noAction = lemp->accAction + 1;
  lemp->minReduce = lemp->noAction + 1;
  lemp->maxAction = lemp->minReduce + lemp->nrule;

  in = tplt_open(lemp);
  if( in==0 ) return;
  out = file_open(lemp,".c","wb");
  if( out==0 ){
    fclose(in);
    return;
  }
  if( sqlFlag==0 ){
    sql = 0;
  }else{
    sql = file_open(lemp, ".sql", "wb");
    if( sql==0 ){
      fclose(in);
      fclose(out);
      return;
    }
    fprintf(sql,
       "BEGIN;\n"
       "CREATE TABLE symbol(\n"
       "  id INTEGER PRIMARY KEY,\n"
       "  name TEXT NOT NULL,\n"
       "  isTerminal BOOLEAN NOT NULL,\n"
       "  fallback INTEGER REFERENCES symbol"
               " DEFERRABLE INITIALLY DEFERRED\n"
       ");\n"
    );
    for(i=0; i<lemp->nsymbol; i++){
      fprintf(sql,
         "INSERT INTO symbol(id,name,isTerminal,fallback)"
         "VALUES(%d,'%s',%s",
         i, lemp->symbols[i]->name,
         i<lemp->nterminal ? "TRUE" : "FALSE"
      );
      if( lemp->symbols[i]->fallback ){
        fprintf(sql, ",%d);\n", lemp->symbols[i]->fallback->index);
      }else{
        fprintf(sql, ",NULL);\n");
      }
    }
    fprintf(sql,
      "CREATE TABLE rule(\n"
      "  ruleid INTEGER PRIMARY KEY,\n"
      "  lhs INTEGER REFERENCES symbol(id),\n"
      "  txt TEXT\n"
      ");\n"
      "CREATE TABLE rulerhs(\n"
      "  ruleid INTEGER REFERENCES rule(ruleid),\n"
      "  pos INTEGER,\n"
      "  sym INTEGER REFERENCES symbol(id)\n"
      ");\n"
    );
    for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
      assert( i==rp->iRule );
      fprintf(sql,
        "INSERT INTO rule(ruleid,lhs,txt)VALUES(%d,%d,'",
        rp->iRule, rp->lhs->index
      );
      writeRuleText(sql, rp);
      fprintf(sql,"');\n");
      for(j=0; j<rp->nrhs; j++){
        struct symbol *sp = rp->rhs[j];
        if( sp->type!=MULTITERMINAL ){
          fprintf(sql,
            "INSERT INTO rulerhs(ruleid,pos,sym)VALUES(%d,%d,%d);\n",
            i,j,sp->index
          );
        }else{
          int k;
          for(k=0; k<sp->nsubsym; k++){
            fprintf(sql,
              "INSERT INTO rulerhs(ruleid,pos,sym)VALUES(%d,%d,%d);\n",
              i,j,sp->subsym[k]->index
            );
          }
        }
      }
    }
    fprintf(sql, "COMMIT;\n");
  }
  lineno = 1;

  fprintf(out, 
     "/* This file is automatically generated by Lemon from input grammar\n"
     "** source file \"%s\". */\n", lemp->filename); lineno += 2;
  
  /* The first %include directive begins with a C-language comment,
  ** then skip over the header comment of the template file
  */
  if( lemp->include==0 ) lemp->include = "";
  for(i=0; ISSPACE(lemp->include[i]); i++){
    if( lemp->include[i]=='\n' ){
      lemp->include += i+1;
      i = -1;
    }
  }
  if( lemp->include[0]=='/' ){
    tplt_skip_header(in,&lineno);
  }else{
    tplt_xfer(lemp->name,in,out,&lineno);
  tplt_xfer(lemp->name,in,out,&lineno);
  }

  /* Generate the include code, if any */
  tplt_print(out,lemp,lemp->include,&lineno);
  if( mhflag ){
    char *incName = file_makename(lemp, ".h");
    fprintf(out,"#include \"%s\"\n", incName); lineno++;
    free(incName);
  }
  tplt_xfer(lemp->name,in,out,&lineno);

  /* Generate #defines for all tokens */
  if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
  else                    prefix = "";
  if( mhflag ){
    const char *prefix;
    fprintf(out,"#if INTERFACE\n"); lineno++;
    if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
  }else{
    else                    prefix = "";
    fprintf(out,"#ifndef %s%s\n", prefix, lemp->symbols[1]->name);
  }
  for(i=1; i<lemp->nterminal; i++){
    fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
    lineno++;
  }
  fprintf(out,"#endif\n"); lineno++;
    for(i=1; i<lemp->nterminal; i++){
      fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
      lineno++;
    }
    fprintf(out,"#endif\n"); lineno++;
  }
  tplt_xfer(lemp->name,in,out,&lineno);

  /* Generate the defines */
  fprintf(out,"#define YYCODETYPE %s\n",
    minimum_size_type(0, lemp->nsymbol, &szCodeType)); lineno++;
  fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol);  lineno++;
  fprintf(out,"#define YYACTIONTYPE %s\n",
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4344
4345
4346
4347
4348
4349
4350


4351
4352
4353
4354
4355
4356
4357







-
-







    }
  }

  /* Finish rendering the constants now that the action table has
  ** been computed */
  fprintf(out,"#define YYNSTATE             %d\n",lemp->nxstate);  lineno++;
  fprintf(out,"#define YYNRULE              %d\n",lemp->nrule);  lineno++;
  fprintf(out,"#define YYNRULE_WITH_ACTION  %d\n",lemp->nruleWithAction);
         lineno++;
  fprintf(out,"#define YYNTOKEN             %d\n",lemp->nterminal); lineno++;
  fprintf(out,"#define YY_MAX_SHIFT         %d\n",lemp->nxstate-1); lineno++;
  i = lemp->minShiftReduce;
  fprintf(out,"#define YY_MIN_SHIFTREDUCE   %d\n",i); lineno++;
  i += lemp->nrule;
  fprintf(out,"#define YY_MAX_SHIFTREDUCE   %d\n", i-1); lineno++;
  fprintf(out,"#define YY_ERROR_ACTION      %d\n", lemp->errAction); lineno++;
4635
4636
4637
4638
4639
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
4398
4399
4400
4401
4402
4403
4404

4405
4406
4407
4408
4409
4410
4411
















4412
4413
4414
4415
4416
4417
4418







-
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  lemp->tablesize += n*szCodeType;
  fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++;
  for(i=j=0; i<n; i++){
    int la = acttab_yylookahead(pActtab, i);
    if( la<0 ) la = lemp->nsymbol;
    if( j==0 ) fprintf(out," /* %5d */ ", i);
    fprintf(out, " %4d,", la);
    if( j==9 ){
    if( j==9 || i==n-1 ){
      fprintf(out, "\n"); lineno++;
      j = 0;
    }else{
      j++;
    }
  }
  /* Add extra entries to the end of the yy_lookahead[] table so that
  ** yy_shift_ofst[]+iToken will always be a valid index into the array,
  ** even for the largest possible value of yy_shift_ofst[] and iToken. */
  nLookAhead = lemp->nterminal + lemp->nactiontab;
  while( i<nLookAhead ){
    if( j==0 ) fprintf(out," /* %5d */ ", i);
    fprintf(out, " %4d,", lemp->nterminal);
    if( j==9 ){
      fprintf(out, "\n"); lineno++;
      j = 0;
    }else{
      j++;
    }
    i++;
  }
  if( j>0 ){ fprintf(out, "\n"); lineno++; }
  fprintf(out, "};\n"); lineno++;

  /* Output the yy_shift_ofst[] table */
  n = lemp->nxstate;
  while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
  fprintf(out, "#define YY_SHIFT_COUNT    (%d)\n", n-1); lineno++;
  fprintf(out, "#define YY_SHIFT_MIN      (%d)\n", mnTknOfst); lineno++;
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746

4747
4748
4749
4750
4751
4752
4753
4484
4485
4486
4487
4488
4489
4490



4491
4492
4493
4494
4495
4496
4497
4498







-
-
-
+







  fprintf(out, "};\n"); lineno++;
  tplt_xfer(lemp->name,in,out,&lineno);

  /* Generate the table of fallback tokens.
  */
  if( lemp->has_fallback ){
    int mx = lemp->nterminal - 1;
    /* 2019-08-28:  Generate fallback entries for every token to avoid
    ** having to do a range check on the index */
    /* while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; } */
    while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; }
    lemp->tablesize += (mx+1)*szCodeType;
    for(i=0; i<=mx; i++){
      struct symbol *p = lemp->symbols[i];
      if( p->fallback==0 ){
        fprintf(out, "    0,  /* %10s => nothing */\n", p->name);
      }else{
        fprintf(out, "  %3d,  /* %10s => %s */\n", p->fallback->index,
4845
4846
4847
4848
4849
4850
4851
4852

4853
4854
4855
4856
4857
4858
4859
4590
4591
4592
4593
4594
4595
4596

4597
4598
4599
4600
4601
4602
4603
4604







-
+







  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.
  ** 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);
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910

4911
4912
4913
4914
4915
4916
4917
4645
4646
4647
4648
4649
4650
4651




4652
4653
4654
4655
4656
4657
4658
4659







-
-
-
-
+







  ** empty actions. */
  fprintf(out,"      default:\n"); lineno++;
  for(rp=lemp->rule; rp; rp=rp->next){
    if( rp->codeEmitted ) continue;
    assert( rp->noCode );
    fprintf(out,"      /* (%d) ", rp->iRule);
    writeRuleText(out, rp);
    if( rp->neverReduce ){
      fprintf(out, " (NEVER REDUCES) */ assert(yyruleno!=%d);\n",
              rp->iRule); lineno++;
    }else if( rp->doesReduce ){
    if( rp->doesReduce ){
      fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++;
    }else{
      fprintf(out, " (OPTIMIZED OUT) */ assert(yyruleno!=%d);\n",
              rp->iRule); lineno++;
    }
  }
  fprintf(out,"        break;\n"); lineno++;
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4673
4674
4675
4676
4677
4678
4679

4680
4681
4682
4683
4684
4685
4686







-








  /* Append any addition code the user desires */
  tplt_print(out,lemp,lemp->extracode,&lineno);

  acttab_free(pActtab);
  fclose(in);
  fclose(out);
  if( sql ) fclose(sql);
  return;
}

/* Generate a header file for the parser */
void ReportHeader(struct lemon *lemp)
{
  FILE *out, *in;
5174
5175
5176
5177
5178
5179
5180

5181
5182
5183
5184
5185
5186
5187
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929







+







}

/* Allocate a new set */
char *SetNew(void){
  char *s;
  s = (char*)calloc( size, 1);
  if( s==0 ){
    extern void memory_error();
    memory_error();
  }
  return s;
}

/* Deallocate a set */
void SetFree(char *s)

Changes to tool/lempar.c.

18
19
20
21
22
23
24


25
26
27
28
29




30
31

32
33
34
35
36
37
38
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







+
+



-
-
+
+
+
+

-
+







** the value of the %name directive from the grammar.  Otherwise, the content
** of this template is copied straight through into the generate parser
** source file.
**
** The following is the concatenation of all %include directives from the
** input grammar file:
*/
#include <stdio.h>
#include <assert.h>
/************ Begin %include sections from the grammar ************************/
%%
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols.
***************** Begin token definitions *************************************/
/* These constants specify the various numeric values for terminal symbols
** in a format understandable to "makeheaders".  This section is blank unless
** "lemon" is run with the "-m" command-line option.
***************** Begin makeheaders token definitions *************************/
%%
/**************** End token definitions ***************************************/
/**************** End makeheaders token definitions ***************************/

/* The next sections is a series of control #defines.
** various aspects of the generated parser.
**    YYCODETYPE         is the data type used to store the integer codes
**                       that represent terminal and non-terminal symbols.
**                       "unsigned char" is used if there are fewer than
**                       256 symbols.  Larger types otherwise.
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
225
226
227
228
229
230
231

232
233
234
235
236
237
238







-







  yyStackEntry *yystackEnd;            /* Last entry in the stack */
#endif
};
typedef struct yyParser yyParser;

#ifndef NDEBUG
#include <stdio.h>
#include <assert.h>
static FILE *yyTraceFILE = 0;
static char *yyTracePrompt = 0;
#endif /* NDEBUG */

#ifndef NDEBUG
/* 
** Turn parser tracing on by giving a stream to which to write the trace
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
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







-
-
+



-
-
+


-
-
+
+
-














+
+
+
+
+
+
+
-
-
+
+
+













-







  assert( stateno <= YY_SHIFT_COUNT );
#if defined(YYCOVERAGE)
  yycoverage[stateno][iLookAhead] = 1;
#endif
  do{
    i = yy_shift_ofst[stateno];
    assert( i>=0 );
    assert( i<=YY_ACTTAB_COUNT );
    assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD );
    /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */
    assert( iLookAhead!=YYNOCODE );
    assert( iLookAhead < YYNTOKEN );
    i += iLookAhead;
    assert( i<(int)YY_NLOOKAHEAD );
    if( yy_lookahead[i]!=iLookAhead ){
    if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
      YYCODETYPE iFallback;            /* Fallback token */
      assert( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0]) );
      iFallback = yyFallback[iLookAhead];
      if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
             && (iFallback = yyFallback[iLookAhead])!=0 ){
      if( iFallback!=0 ){
#ifndef NDEBUG
        if( yyTraceFILE ){
          fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
             yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
        }
#endif
        assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
        iLookAhead = iFallback;
        continue;
      }
#endif
#ifdef YYWILDCARD
      {
        int j = i - iLookAhead + YYWILDCARD;
        if( 
#if YY_SHIFT_MIN+YYWILDCARD<0
          j>=0 &&
#endif
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
          j<YY_ACTTAB_COUNT &&
#endif
        assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) );
        if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){
          j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) &&
          yy_lookahead[j]==YYWILDCARD && iLookAhead>0
        ){
#ifndef NDEBUG
          if( yyTraceFILE ){
            fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
               yyTracePrompt, yyTokenName[iLookAhead],
               yyTokenName[YYWILDCARD]);
          }
#endif /* NDEBUG */
          return yy_action[j];
        }
      }
#endif /* YYWILDCARD */
      return yy_default[stateno];
    }else{
      assert( i>=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) );
      return yy_action[i];
    }
  }while(1);
}

/*
** Find the appropriate action for a parser given the non-terminal
714
715
716
717
718
719
720













































721
722
723
724
725
726
727
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  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;
#ifndef NDEBUG
  if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
    yysize = yyRuleInfoNRhs[yyruleno];
    if( yysize ){
      fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
        yyTracePrompt,
        yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno);
    }else{
      fprintf(yyTraceFILE, "%sReduce %d [%s].\n",
        yyTracePrompt, yyruleno, yyRuleName[yyruleno]);
    }
  }
#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
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
924
925
926
927
928
929
930


931
932
933
934



















935


























936
937
938
939
940
941
942
943







-
-
+



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







    }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 );
  do{
    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 */

      yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,
      /* 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);
                        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 ){
1034
1035
1036
1037
1038
1039
1040
1041

1042
1043
1044
1045
1046
1047
1048
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
1056







-
+







#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]);
1056
1057
1058
1059
1060
1061
1062
1063
1064



1065
1066
1067
1068

1069
1064
1065
1066
1067
1068
1069
1070


1071
1072
1073
1074
1075

1076
1077
1078







-
-
+
+
+


-

+


/*
** Return the fallback token corresponding to canonical token iToken, or
** 0 if iToken has no fallback.
*/
int ParseFallback(int iToken){
#ifdef YYFALLBACK
  assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) );
  return yyFallback[iToken];
  if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){
    return yyFallback[iToken];
  }
#else
  (void)iToken;
  return 0;
#endif
  return 0;
}

Changes to tool/mkautoconfamal.sh.

1
2
3
4
5
6


7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







#!/bin/sh
# This script is used to build the amalgamation autoconf package.
# It assumes the following:
#
#   1. The files "sqlite3.c", "sqlite3.h", "sqlite3ext.h", "shell.c",
#      and "sqlite3rc.h" are available in the current directory.
#   1. The files "sqlite3.c", "sqlite3.h" and "sqlite3ext.h"
#      are available in the current directory.
#
#   2. Variable $TOP is set to the full path of the root directory
#      of the SQLite source tree.
#
#   3. There is nothing of value in the ./mkpkg_tmp_dir directory.
#      This is important, as the script executes "rm -rf ./mkpkg_tmp_dir".
#
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
45
46
47
48
49
50
51

52
53
54
55
56
57
58







-







fi

rm -rf $TMPSPACE
cp -R $TOP/autoconf       $TMPSPACE
cp sqlite3.c              $TMPSPACE
cp sqlite3.h              $TMPSPACE
cp sqlite3ext.h           $TMPSPACE
cp sqlite3rc.h            $TMPSPACE
cp $TOP/sqlite3.1         $TMPSPACE
cp $TOP/sqlite3.pc.in     $TMPSPACE
cp shell.c                $TMPSPACE
cp $TOP/src/sqlite3.rc    $TMPSPACE
cp $TOP/tool/Replace.cs   $TMPSPACE

cat $TMPSPACE/configure.ac |

Changes to tool/mkkeywordhash.c.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
32
33
34
35
36
37
38

39
40
41
42
43
44
45







-







** table composed of instances of the following structure.
*/
typedef struct Keyword Keyword;
struct Keyword {
  char *zName;         /* The keyword name */
  char *zTokenType;    /* Token value for this keyword */
  int mask;            /* Code this keyword if non-zero */
  int priority;        /* Put higher priorities earlier in the hash chain */
  int id;              /* Unique ID for this record */
  int hash;            /* Hash on the keyword */
  int offset;          /* Offset to start of name string */
  int len;             /* Length of this keyword, not counting final \000 */
  int prefix;          /* Number of characters in prefix */
  int longestSuffix;   /* Longest suffix that is a prefix on another word */
  int iNext;           /* Index in aKeywordTable[] of next with same hash */
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
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







-
-
-
-
-
-
-
-
-
-
-





-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#  define UPSERT     0x00080000
#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      },
  { "ADD",              "TK_ADD",          ALTER,            1      },
  { "AFTER",            "TK_AFTER",        TRIGGER,          0      },
  { "ALL",              "TK_ALL",          ALWAYS,           0      },
  { "ALTER",            "TK_ALTER",        ALTER,            0      },
  { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER       },
  { "ACTION",           "TK_ACTION",       FKEY                   },
  { "ADD",              "TK_ADD",          ALTER                  },
  { "AFTER",            "TK_AFTER",        TRIGGER                },
  { "ALL",              "TK_ALL",          ALWAYS                 },
  { "ALTER",            "TK_ALTER",        ALTER                  },
  { "ALWAYS",           "TK_ALWAYS",       GENCOL,           0      },
  { "ANALYZE",          "TK_ANALYZE",      ANALYZE,          0      },
  { "AND",              "TK_AND",          ALWAYS,           10     },
  { "AS",               "TK_AS",           ALWAYS,           10     },
  { "ASC",              "TK_ASC",          ALWAYS,           0      },
  { "ATTACH",           "TK_ATTACH",       ATTACH,           1      },
  { "AUTOINCREMENT",    "TK_AUTOINCR",     AUTOINCR,         0      },
  { "BEFORE",           "TK_BEFORE",       TRIGGER,          0      },
  { "BEGIN",            "TK_BEGIN",        ALWAYS,           1      },
  { "BETWEEN",          "TK_BETWEEN",      ALWAYS,           5      },
  { "BY",               "TK_BY",           ALWAYS,           10     },
  { "CASCADE",          "TK_CASCADE",      FKEY,             1      },
  { "CASE",             "TK_CASE",         ALWAYS,           5      },
  { "CAST",             "TK_CAST",         CAST,             5      },
  { "CHECK",            "TK_CHECK",        ALWAYS,           1      },
  { "COLLATE",          "TK_COLLATE",      ALWAYS,           1      },
  { "COLUMN",           "TK_COLUMNKW",     ALTER,            1      },
  { "COMMIT",           "TK_COMMIT",       ALWAYS,           1      },
  { "CONFLICT",         "TK_CONFLICT",     CONFLICT,         0      },
  { "CONSTRAINT",       "TK_CONSTRAINT",   ALWAYS,           1      },
  { "CREATE",           "TK_CREATE",       ALWAYS,           2      },
  { "CROSS",            "TK_JOIN_KW",      ALWAYS,           3      },
  { "CURRENT",          "TK_CURRENT",      WINDOWFUNC,       1      },
  { "CURRENT_DATE",     "TK_CTIME_KW",     ALWAYS,           1      },
  { "CURRENT_TIME",     "TK_CTIME_KW",     ALWAYS,           1      },
  { "CURRENT_TIMESTAMP","TK_CTIME_KW",     ALWAYS,           1      },
  { "DATABASE",         "TK_DATABASE",     ATTACH,           0      },
  { "DEFAULT",          "TK_DEFAULT",      ALWAYS,           1      },
  { "DEFERRED",         "TK_DEFERRED",     ALWAYS,           1      },
  { "DEFERRABLE",       "TK_DEFERRABLE",   FKEY,             1      },
  { "DELETE",           "TK_DELETE",       ALWAYS,           10     },
  { "DESC",             "TK_DESC",         ALWAYS,           3      },
  { "DETACH",           "TK_DETACH",       ATTACH,           0      },
  { "DISTINCT",         "TK_DISTINCT",     ALWAYS,           5      },
  { "DO",               "TK_DO",           UPSERT,           2      },
  { "DROP",             "TK_DROP",         ALWAYS,           1      },
  { "END",              "TK_END",          ALWAYS,           1      },
  { "EACH",             "TK_EACH",         TRIGGER,          1      },
  { "ELSE",             "TK_ELSE",         ALWAYS,           2      },
  { "ESCAPE",           "TK_ESCAPE",       ALWAYS,           4      },
  { "EXCEPT",           "TK_EXCEPT",       COMPOUND,         4      },
  { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS,           1      },
  { "EXCLUDE",          "TK_EXCLUDE",      WINDOWFUNC,       1      },
  { "EXISTS",           "TK_EXISTS",       ALWAYS,           4      },
  { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN,          1      },
  { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER, 1      },
  { "FILTER",           "TK_FILTER",       WINDOWFUNC,       4      },
  { "ANALYZE",          "TK_ANALYZE",      ANALYZE                },
  { "AND",              "TK_AND",          ALWAYS                 },
  { "AS",               "TK_AS",           ALWAYS                 },
  { "ASC",              "TK_ASC",          ALWAYS                 },
  { "ATTACH",           "TK_ATTACH",       ATTACH                 },
  { "AUTOINCREMENT",    "TK_AUTOINCR",     AUTOINCR               },
  { "BEFORE",           "TK_BEFORE",       TRIGGER                },
  { "BEGIN",            "TK_BEGIN",        ALWAYS                 },
  { "BETWEEN",          "TK_BETWEEN",      ALWAYS                 },
  { "BY",               "TK_BY",           ALWAYS                 },
  { "CASCADE",          "TK_CASCADE",      FKEY                   },
  { "CASE",             "TK_CASE",         ALWAYS                 },
  { "CAST",             "TK_CAST",         CAST                   },
  { "CHECK",            "TK_CHECK",        ALWAYS                 },
  { "COLLATE",          "TK_COLLATE",      ALWAYS                 },
  { "COLUMN",           "TK_COLUMNKW",     ALTER                  },
  { "COMMIT",           "TK_COMMIT",       ALWAYS                 },
  { "CONFLICT",         "TK_CONFLICT",     CONFLICT               },
  { "CONSTRAINT",       "TK_CONSTRAINT",   ALWAYS                 },
  { "CREATE",           "TK_CREATE",       ALWAYS                 },
  { "CROSS",            "TK_JOIN_KW",      ALWAYS                 },
  { "CURRENT",          "TK_CURRENT",      WINDOWFUNC             },
  { "CURRENT_DATE",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIME",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIMESTAMP","TK_CTIME_KW",     ALWAYS                 },
  { "DATABASE",         "TK_DATABASE",     ATTACH                 },
  { "DEFAULT",          "TK_DEFAULT",      ALWAYS                 },
  { "DEFERRED",         "TK_DEFERRED",     ALWAYS                 },
  { "DEFERRABLE",       "TK_DEFERRABLE",   FKEY                   },
  { "DELETE",           "TK_DELETE",       ALWAYS                 },
  { "DESC",             "TK_DESC",         ALWAYS                 },
  { "DETACH",           "TK_DETACH",       ATTACH                 },
  { "DISTINCT",         "TK_DISTINCT",     ALWAYS                 },
  { "DO",               "TK_DO",           UPSERT                 },
  { "DROP",             "TK_DROP",         ALWAYS                 },
  { "END",              "TK_END",          ALWAYS                 },
  { "EACH",             "TK_EACH",         TRIGGER                },
  { "ELSE",             "TK_ELSE",         ALWAYS                 },
  { "ESCAPE",           "TK_ESCAPE",       ALWAYS                 },
  { "EXCEPT",           "TK_EXCEPT",       COMPOUND               },
  { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS                 },
  { "EXCLUDE",          "TK_EXCLUDE",      WINDOWFUNC             },
  { "EXISTS",           "TK_EXISTS",       ALWAYS                 },
  { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN                },
  { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER       },
  { "FILTER",           "TK_FILTER",       WINDOWFUNC             },
  { "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      },
  { "FOLLOWING",        "TK_FOLLOWING",    WINDOWFUNC             },
  { "FOR",              "TK_FOR",          TRIGGER                },
  { "FOREIGN",          "TK_FOREIGN",      FKEY                   },
  { "FROM",             "TK_FROM",         ALWAYS                 },
  { "FULL",             "TK_JOIN_KW",      ALWAYS                 },
  { "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      },
  { "IN",               "TK_IN",           ALWAYS,           10     },
  { "INDEX",            "TK_INDEX",        ALWAYS,           1      },
  { "INDEXED",          "TK_INDEXED",      ALWAYS,           0      },
  { "INITIALLY",        "TK_INITIALLY",    FKEY,             1      },
  { "INNER",            "TK_JOIN_KW",      ALWAYS,           1      },
  { "INSERT",           "TK_INSERT",       ALWAYS,           10     },
  { "INSTEAD",          "TK_INSTEAD",      TRIGGER,          1      },
  { "INTERSECT",        "TK_INTERSECT",    COMPOUND,         5      },
  { "INTO",             "TK_INTO",         ALWAYS,           10     },
  { "IS",               "TK_IS",           ALWAYS,           5      },
  { "ISNULL",           "TK_ISNULL",       ALWAYS,           5      },
  { "JOIN",             "TK_JOIN",         ALWAYS,           5      },
  { "KEY",              "TK_KEY",          ALWAYS,           1      },
  { "GLOB",             "TK_LIKE_KW",      ALWAYS                 },
  { "GROUP",            "TK_GROUP",        ALWAYS                 },
  { "GROUPS",           "TK_GROUPS",       WINDOWFUNC             },
  { "HAVING",           "TK_HAVING",       ALWAYS                 },
  { "IF",               "TK_IF",           ALWAYS                 },
  { "IGNORE",           "TK_IGNORE",       CONFLICT|TRIGGER       },
  { "IMMEDIATE",        "TK_IMMEDIATE",    ALWAYS                 },
  { "IN",               "TK_IN",           ALWAYS                 },
  { "INDEX",            "TK_INDEX",        ALWAYS                 },
  { "INDEXED",          "TK_INDEXED",      ALWAYS                 },
  { "INITIALLY",        "TK_INITIALLY",    FKEY                   },
  { "INNER",            "TK_JOIN_KW",      ALWAYS                 },
  { "INSERT",           "TK_INSERT",       ALWAYS                 },
  { "INSTEAD",          "TK_INSTEAD",      TRIGGER                },
  { "INTERSECT",        "TK_INTERSECT",    COMPOUND               },
  { "INTO",             "TK_INTO",         ALWAYS                 },
  { "IS",               "TK_IS",           ALWAYS                 },
  { "ISNULL",           "TK_ISNULL",       ALWAYS                 },
  { "JOIN",             "TK_JOIN",         ALWAYS                 },
  { "KEY",              "TK_KEY",          ALWAYS                 },
  { "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      },
  { "LEFT",             "TK_JOIN_KW",      ALWAYS                 },
  { "LIKE",             "TK_LIKE_KW",      ALWAYS                 },
  { "LIMIT",            "TK_LIMIT",        ALWAYS                 },
  { "MATCH",            "TK_MATCH",        ALWAYS                 },
  { "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     },
  { "NATURAL",          "TK_JOIN_KW",      ALWAYS                 },
  { "NO",               "TK_NO",           FKEY|WINDOWFUNC        },
  { "NOT",              "TK_NOT",          ALWAYS                 },
  { "NOTHING",          "TK_NOTHING",      UPSERT                 },
  { "NOTNULL",          "TK_NOTNULL",      ALWAYS                 },
  { "NULL",             "TK_NULL",         ALWAYS                 },
  { "NULLS",            "TK_NULLS",        ALWAYS,           3      },
  { "OF",               "TK_OF",           ALWAYS,           3      },
  { "OFFSET",           "TK_OFFSET",       ALWAYS,           1      },
  { "ON",               "TK_ON",           ALWAYS,           1      },
  { "OR",               "TK_OR",           ALWAYS,           9      },
  { "ORDER",            "TK_ORDER",        ALWAYS,           10     },
  { "OTHERS",           "TK_OTHERS",       WINDOWFUNC,       3      },
  { "OUTER",            "TK_JOIN_KW",      ALWAYS,           5      },
  { "OVER",             "TK_OVER",         WINDOWFUNC,       3      },
  { "PARTITION",        "TK_PARTITION",    WINDOWFUNC,       3      },
  { "PLAN",             "TK_PLAN",         EXPLAIN,          0      },
  { "PRAGMA",           "TK_PRAGMA",       PRAGMA,           0      },
  { "PRECEDING",        "TK_PRECEDING",    WINDOWFUNC,       3      },
  { "PRIMARY",          "TK_PRIMARY",      ALWAYS,           1      },
  { "QUERY",            "TK_QUERY",        EXPLAIN,          0      },
  { "RAISE",            "TK_RAISE",        TRIGGER,          1      },
  { "RANGE",            "TK_RANGE",        WINDOWFUNC,       3      },
  { "RECURSIVE",        "TK_RECURSIVE",    CTE,              3      },
  { "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      },
  { "OF",               "TK_OF",           ALWAYS                 },
  { "OFFSET",           "TK_OFFSET",       ALWAYS                 },
  { "ON",               "TK_ON",           ALWAYS                 },
  { "OR",               "TK_OR",           ALWAYS                 },
  { "ORDER",            "TK_ORDER",        ALWAYS                 },
  { "OTHERS",           "TK_OTHERS",       WINDOWFUNC             },
  { "OUTER",            "TK_JOIN_KW",      ALWAYS                 },
  { "OVER",             "TK_OVER",         WINDOWFUNC             },
  { "PARTITION",        "TK_PARTITION",    WINDOWFUNC             },
  { "PLAN",             "TK_PLAN",         EXPLAIN                },
  { "PRAGMA",           "TK_PRAGMA",       PRAGMA                 },
  { "PRECEDING",        "TK_PRECEDING",    WINDOWFUNC             },
  { "PRIMARY",          "TK_PRIMARY",      ALWAYS                 },
  { "QUERY",            "TK_QUERY",        EXPLAIN                },
  { "RAISE",            "TK_RAISE",        TRIGGER                },
  { "RANGE",            "TK_RANGE",        WINDOWFUNC             },
  { "RECURSIVE",        "TK_RECURSIVE",    CTE                    },
  { "REFERENCES",       "TK_REFERENCES",   FKEY                   },
  { "REGEXP",           "TK_LIKE_KW",      ALWAYS                 },
  { "REINDEX",          "TK_REINDEX",      REINDEX                },
  { "RELEASE",          "TK_RELEASE",      ALWAYS                 },
  { "RENAME",           "TK_RENAME",       ALTER                  },
  { "REPLACE",          "TK_REPLACE",      CONFLICT               },
  { "RESTRICT",         "TK_RESTRICT",     FKEY                   },
  { "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     },
  { "TABLE",            "TK_TABLE",        ALWAYS,           1      },
  { "TEMP",             "TK_TEMP",         ALWAYS,           1      },
  { "TEMPORARY",        "TK_TEMP",         ALWAYS,           1      },
  { "THEN",             "TK_THEN",         ALWAYS,           3      },
  { "TIES",             "TK_TIES",         WINDOWFUNC,       3      },
  { "TO",               "TK_TO",           ALWAYS,           3      },
  { "TRANSACTION",      "TK_TRANSACTION",  ALWAYS,           1      },
  { "TRIGGER",          "TK_TRIGGER",      TRIGGER,          1      },
  { "UNBOUNDED",        "TK_UNBOUNDED",    WINDOWFUNC,       3      },
  { "UNION",            "TK_UNION",        COMPOUND,         3      },
  { "UNIQUE",           "TK_UNIQUE",       ALWAYS,           1      },
  { "UPDATE",           "TK_UPDATE",       ALWAYS,           10     },
  { "USING",            "TK_USING",        ALWAYS,           8      },
  { "VACUUM",           "TK_VACUUM",       VACUUM,           1      },
  { "VALUES",           "TK_VALUES",       ALWAYS,           10     },
  { "VIEW",             "TK_VIEW",         VIEW,             1      },
  { "VIRTUAL",          "TK_VIRTUAL",      VTAB,             1      },
  { "WHEN",             "TK_WHEN",         ALWAYS,           1      },
  { "WHERE",            "TK_WHERE",        ALWAYS,           10     },
  { "WINDOW",           "TK_WINDOW",       WINDOWFUNC,       3      },
  { "WITH",             "TK_WITH",         CTE,              4      },
  { "WITHOUT",          "TK_WITHOUT",      ALWAYS,           1      },
  { "RIGHT",            "TK_JOIN_KW",      ALWAYS                 },
  { "ROLLBACK",         "TK_ROLLBACK",     ALWAYS                 },
  { "ROW",              "TK_ROW",          TRIGGER                },
  { "ROWS",             "TK_ROWS",         ALWAYS                 },
  { "SAVEPOINT",        "TK_SAVEPOINT",    ALWAYS                 },
  { "SELECT",           "TK_SELECT",       ALWAYS                 },
  { "SET",              "TK_SET",          ALWAYS                 },
  { "TABLE",            "TK_TABLE",        ALWAYS                 },
  { "TEMP",             "TK_TEMP",         ALWAYS                 },
  { "TEMPORARY",        "TK_TEMP",         ALWAYS                 },
  { "THEN",             "TK_THEN",         ALWAYS                 },
  { "TIES",             "TK_TIES",         WINDOWFUNC             },
  { "TO",               "TK_TO",           ALWAYS                 },
  { "TRANSACTION",      "TK_TRANSACTION",  ALWAYS                 },
  { "TRIGGER",          "TK_TRIGGER",      TRIGGER                },
  { "UNBOUNDED",        "TK_UNBOUNDED",    WINDOWFUNC             },
  { "UNION",            "TK_UNION",        COMPOUND               },
  { "UNIQUE",           "TK_UNIQUE",       ALWAYS                 },
  { "UPDATE",           "TK_UPDATE",       ALWAYS                 },
  { "USING",            "TK_USING",        ALWAYS                 },
  { "VACUUM",           "TK_VACUUM",       VACUUM                 },
  { "VALUES",           "TK_VALUES",       ALWAYS                 },
  { "VIEW",             "TK_VIEW",         VIEW                   },
  { "VIRTUAL",          "TK_VIRTUAL",      VTAB                   },
  { "WHEN",             "TK_WHEN",         ALWAYS                 },
  { "WHERE",            "TK_WHERE",        ALWAYS                 },
  { "WINDOW",           "TK_WINDOW",       WINDOWFUNC             },
  { "WITH",             "TK_WITH",         CTE                    },
  { "WITHOUT",          "TK_WITHOUT",      ALWAYS                 },
};

/* Number of keywords */
static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0]));

/* Map all alphabetic characters into lower-case for hashing.  This is
** only valid for alphabetics.  In particular it does not work for '_'
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
348
349
350
351
352
353
354


























355
356
357
358
359
360
361







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  int i;
  for(i=0; i<nKeyword; i++){
    if( aKeywordTable[i].id==id ) break;
  }
  return &aKeywordTable[i];
}

/*
** If aKeyword[*pFrom-1].iNext has a higher priority that aKeyword[*pFrom-1]
** itself, then swap them.
*/
static void reorder(int *pFrom){
  int i = *pFrom - 1;
  int j;
  if( i<0 ) return;
  j = aKeywordTable[i].iNext;
  if( j==0 ) return;
  j--;
  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;
423
424
425
426
427
428
429
430
431


432
433
434
435
436
437
438
439
378
379
380
381
382
383
384


385
386

387
388
389
390
391
392
393







-
-
+
+
-







  /* 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->hash = (charMap(p->zName[0])*4) ^
              (charMap(p->zName[p->len-1])*3) ^ (p->len*1);
              (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 */
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
482
483
484
485
486
487
488

489
490
491
492
493
494
495







-








  /* Compute the hash */
  for(i=0; i<bestSize; i++) aKWHash[i] = 0;
  for(i=0; i<nKeyword; i++){
    h = aKeywordTable[i].hash % bestSize;
    aKeywordTable[i].iNext = aKWHash[h];
    aKWHash[h] = i+1;
    reorder(&aKWHash[h]);
  }

  /* Begin generating code */
  printf("%s", zHdr);
  printf("/* Hash score: %d */\n", bestCount);
  printf("/* zKWText[] encodes %d bytes of keyword text in %d bytes */\n",
          totalLen + nKeyword, nChar+1 );
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
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







-
-
-
-
-
-
-
-
-
-
-







-
+
-
-
+


+


-
-
-



-
-
-







    j++;
    if( j>=5 ){
      printf("\n");
      j = 0;
    }
  }
  printf("%s};\n", j==0 ? "" : "\n");
  printf("/* Hash table decoded:\n");
  for(i=0; i<bestSize; i++){
    j = aKWHash[i];
    printf("** %3d:", i);
    while( j ){
      printf(" %s", aKeywordTable[j-1].zOrigName);
      j = aKeywordTable[j-1].iNext;
    }
    printf("\n");
  }
  printf("*/\n");
  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("    i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n",
  printf(" (charMap(z[n-1])*%d) %c", HASH_C1, HASH_CC);
  printf(" n*%d) %% %d;\n", HASH_C2, bestSize);
          bestSize);
  printf("    for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){\n");
  printf("      if( aKWLen[i]!=n ) continue;\n");
  printf("      j = 0;\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");
  printf("      while( j<n && (z[j]&~0x20)==zKW[j] ){ j++; }\n");
  printf("#endif\n");
  printf("#ifdef SQLITE_EBCDIC\n");
  printf("      if( toupper(z[0])!=zKW[0] ) continue;\n");
  printf("      if( toupper(z[1])!=zKW[1] ) continue;\n");
  printf("      j = 2;\n");
  printf("      while( j<n && toupper(z[j])==zKW[j] ){ j++; }\n");
  printf("#endif\n");
  printf("      if( j<n ) continue;\n");
  for(i=0; i<nKeyword; i++){
    printf("      testcase( i==%d ); /* %s */\n",
           i, aKeywordTable[i].zOrigName);
  }

Changes to tool/mkmsvcmin.tcl.

79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93







-
+







set blocks(2) [string trimleft [string map [list \\\\ \\] {
Replace.exe:
	$(CSC) /target:exe $(TOP)\Replace.cs

sqlite3.def:	Replace.exe $(LIBOBJ)
	echo EXPORTS > sqlite3.def
	dumpbin /all $(LIBOBJ) \\
		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
		| sort >> sqlite3.def
}]]

set data "#### DO NOT EDIT ####\n"
append data "# This makefile is automatically "
append data "generated from the [file tail $fromFileName] at\n"
append data "# the root of the canonical SQLite source tree (not the\n"

Changes to tool/mkpragmatab.tcl.

37
38
39
40
41
42
43





44
45
46
47
48
49
50
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55







+
+
+
+
+







  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)

  NAME: empty_result_callbacks
  TYPE: FLAG
  ARG:  SQLITE_NullCallback
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)

  NAME: legacy_file_format
  TYPE: FLAG
  ARG:  SQLITE_LegacyFileFmt
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)

  NAME: fullfsync
  TYPE: FLAG
  ARG:  SQLITE_FullFSync
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)

  NAME: checkpoint_fullfsync
  TYPE: FLAG
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
127
128
129
130
131
132
133





134
135
136
137
138
139
140







-
-
-
-
-







  TYPE: FLAG
  ARG:  SQLITE_ReadUncommit
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)

  NAME: recursive_triggers
  TYPE: FLAG
  ARG:  SQLITE_RecTriggers
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)

  NAME: trusted_schema
  TYPE: FLAG
  ARG:  SQLITE_TrustedSchema
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)

  NAME: foreign_keys
  TYPE: FLAG
  ARG:  SQLITE_ForeignKeys
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
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
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







-
+

-
+






-
+




-
+












-
+











-







  NAME: database_list
  FLAG: NeedSchema Result0
  COLS: seq name file
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)

  NAME: function_list
  FLAG: Result0
  COLS: name builtin type enc narg flags
  COLS: name builtin
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
  IF:   defined(SQLITE_INTROSPECTION_PRAGMAS)

  NAME: module_list
  FLAG: Result0
  COLS: name
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
  IF:   !defined(SQLITE_OMIT_VIRTUALTABLE)
  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
  IF:   defined(SQLITE_INTROSPECTION_PRAGMAS)

  NAME: pragma_list
  FLAG: Result0
  COLS: name
  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
  IF:   defined(SQLITE_INTROSPECTION_PRAGMAS)

  NAME: collation_list
  FLAG: Result0
  COLS: seq name
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)

  NAME: foreign_key_list
  FLAG: NeedSchema Result1 SchemaOpt
  COLS: id seq table from to on_update on_delete match
  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY)

  NAME: foreign_key_check
  FLAG: NeedSchema Result0 Result1 SchemaOpt
  FLAG: NeedSchema Result0
  COLS: table rowid parent fkid
  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)

  NAME: parser_trace
  TYPE: FLAG
  ARG:  SQLITE_ParserTrace
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  IF:   defined(SQLITE_DEBUG)

  NAME: case_sensitive_like
  FLAG: NoColumns
  IF:   !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)

  NAME: integrity_check
  FLAG: NeedSchema Result0 Result1
  IF:   !defined(SQLITE_OMIT_INTEGRITY_CHECK)

  NAME: quick_check
  TYPE: INTEGRITY_CHECK
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+




-
-
-



-
-
-







  COLS: timeout

  NAME: lock_status
  FLAG: Result0
  COLS: database status
  IF:   defined(SQLITE_DEBUG) || defined(SQLITE_TEST)

  NAME: key
  TYPE: KEY
  ARG:  0
  IF:   defined(SQLITE_HAS_CODEC)

  NAME: rekey
  TYPE: KEY
  ARG:  1
  IF:   defined(SQLITE_HAS_CODEC)

  NAME: hexkey
  TYPE: HEXKEY
  ARG:  2
  IF:   defined(SQLITE_HAS_CODEC)

  NAME: hexrekey
  TYPE: HEXKEY
  ARG:  3
  IF:   defined(SQLITE_HAS_CODEC)

  NAME: textkey
  TYPE: KEY
  ARG:  4
  IF:   defined(SQLITE_HAS_CODEC)

  NAME: textrekey
  TYPE: KEY
  ARG:  5
  IF:   defined(SQLITE_HAS_CODEC)

  NAME: activate_extensions
  IF:   defined(SQLITE_ENABLE_CEROD)
  IF:   defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)

  NAME: soft_heap_limit
  FLAG: Result0

  NAME: hard_heap_limit
  FLAG: Result0

  NAME: threads
  FLAG: Result0

  NAME: analysis_limit
  FLAG: Result0

  NAME: optimize
  FLAG: Result1 NeedSchema

  NAME: legacy_alter_table
  TYPE: FLAG
  ARG:  SQLITE_LegacyAlter
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502







-
+







    error "bad pragma_def line: $line"
  }
}
record_one
set allnames [lsort [array names allbyname]]

# Generate #defines for all pragma type names.  Group the pragmas that are
# omit in default builds (ex: defined(SQLITE_DEBUG))
# omit in default builds (defined(SQLITE_DEBUG) and defined(SQLITE_HAS_CODEC))
# at the end.
#
puts $fd "\n/* The various pragma types */"
set pnum 0
foreach name $allnames {
  set type [lindex $allbyname($name) 0]
  if {[info exists seentype($type)]} continue

Changes to tool/mkshellc.tcl.

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
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







-



-



-



-
+
-
-








-






    if {[info exists typedef_seen($line)]} {
      return "/* $line */"
    }
    set typedef_seen($line) 1
  }
  return $line
}
set iLine 0
while {1} {
  set lx [omit_redundant_typedefs [gets $in]]
  if {[eof $in]} break;
  incr iLine
  if {[regexp {^INCLUDE } $lx]} {
    set cfile [lindex $lx 1]
    puts $out "/************************* Begin $cfile ******************/"
#   puts $out "#line 1 \"$cfile\""
    set in2 [open $topdir/src/$cfile rb]
    while {![eof $in2]} {
      set lx [omit_redundant_typedefs [gets $in2]]
      if {[regexp {^#include "sqlite} $lx]} {
      if {[regexp {^#include "sqlite} $lx]} continue
        set lx "/* $lx */"
      }
      if {[regexp {^# *include "test_windirent.h"} $lx]} {
        set lx "/* $lx */"
      }
      set lx [string map [list __declspec(dllexport) {}] $lx]
      puts $out $lx
    }
    close $in2
    puts $out "/************************* End $cfile ********************/"
#   puts $out "#line [expr $iLine+1] \"shell.c.in\""
    continue
  }
  puts $out $lx
}
close $in
close $out

Changes to tool/mksourceid.c.

536
537
538
539
540
541
542













543
544
545





546
547
548
549
550
551
552
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







+
+
+
+
+
+
+
+
+
+
+
+
+



+
+
+
+
+








/*
 * blk0() and blk() perform the initial expand.
 * I got the idea of expanding during the round function from SSLeay
 *
 * blk0le() for little-endian and blk0be() for big-endian.
 */
#if __GNUC__ && (defined(__i386__) || defined(__x86_64__))
/*
 * GCC by itself only generates left rotates.  Use right rotates if
 * possible to be kinder to dinky implementations with iterative rotate
 * instructions.
 */
#define SHA_ROT(op, x, k) \
        ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; })
#define rol(x,k) SHA_ROT("roll", x, k)
#define ror(x,k) SHA_ROT("rorl", x, k)

#else
/* Generic C equivalent */
#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
#define rol(x,k) SHA_ROT(x,k,32-(k))
#define ror(x,k) SHA_ROT(x,32-(k),k)
#endif





#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
    |(rol(block[i],8)&0x00FF00FF))
#define blk0be(i) block[i]
#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
    ^block[(i+2)&15]^block[i&15],1))

Changes to tool/mksqlite3c.tcl.

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
84
85
86
87
88
89
90












91
92
93
94
95
96
97







-
-
-
-
-
-
-
-
-
-
-
-







if {$addstatic} {
  puts $out \
{#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
#endif}
}

# Examine the parse.c file.  If it contains lines of the form:
#
#    "#ifndef SQLITE_ENABLE_UPDATE_LIMIT
# 
# then set the SQLITE_UDL_CAPABLE_PARSER flag in the amalgamation.
#
set in [open tsrc/parse.c]
if {[regexp {ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT} [read $in]]} {
  puts $out "#define SQLITE_UDL_CAPABLE_PARSER 1"
}
close $in

# These are the header files used by SQLite.  The first time any of these
# files are seen in a #include statement in the C code, include the complete
# text of the file in-line.  The file only needs to be included once.
#
foreach hdr {
   btree.h
   btreeInt.h
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193







-
+







  set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)}
  set declpattern {([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3[_a-zA-Z0-9]+)(\(.*)}
  if {[file extension $filename]==".h"} {
    set declpattern " *$declpattern"
  }
  set declpattern ^$declpattern\$
  while {![eof $in]} {
    set line [string trimright [gets $in]]
    set line [gets $in]
    incr ln
    if {[regexp {^\s*#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
      if {[info exists available_hdr($hdr)]} {
        if {$available_hdr($hdr)} {
          if {$hdr!="os_common.h" && $hdr!="hwtime.h"} {
            set available_hdr($hdr) 0
          }
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
337
338
339
340
341
342
343

344
345
346
347
348
349
350







-







   vdbemem.c
   vdbeaux.c
   vdbeapi.c
   vdbetrace.c
   vdbe.c
   vdbeblob.c
   vdbesort.c
   vdbevtab.c
   memjournal.c

   walker.c
   resolve.c
   expr.c
   alter.c
   analyze.c

Changes to tool/mksqlite3h.tcl.

103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117







-
+







foreach file $filelist {
  set in [open $file]
  if {![regexp {sqlite\.h\.in} $file]} {
    puts "/******** Begin file [file tail $file] *********/"
  }
  while {![eof $in]} {

    set line [string trimright [gets $in]]
    set line [gets $in]

    # File sqlite3rtree.h contains a line "#include <sqlite3.h>". Omit this
    # line when copying sqlite3rtree.h into sqlite3.h.
    #
    if {[string match {*#include*[<"]sqlite3.h[>"]*} $line]} continue

    regsub -- --VERS--           $line $zVersion line

Changes to tool/offsets.c.

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85







-
+







  int rc;
  if( p->zErr ) return;
  rc = sqlite3_open(zFile, &db);
  if( rc ){
    ofstError(p, "cannot open database file \"%s\"", zFile);
    goto rootAndColumn_exit;
  }
  zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_schema WHERE name=%Q",
  zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master WHERE name=%Q",
                         zTable);
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc ) ofstError(p, "%s: [%s]", sqlite3_errmsg(db), zSql);
  sqlite3_free(zSql);
  if( p->zErr ) goto rootAndColumn_exit;
  if( sqlite3_step(pStmt)!=SQLITE_ROW ){
    ofstError(p, "cannot find table [%s]\n", zTable);

Changes to tool/omittest.tcl.

94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
+







  if {![file exists $sqlite3_dummy]} {
    set wr [open $sqlite3_dummy w]
    puts $wr "dummy"
    close $wr
  }

  if {$::SKIP_RUN} {
    #  puts "Skip testing $dir."
      puts "Skip testing $dir."
  } else {
    # Run the test suite.
    puts -nonewline "Testing $dir..."
    flush stdout
    set rc [catch {
      exec $::MAKEBIN -C $dir -f makefile test >& $dir/test.log
    }]
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+







proc process_options {argv} {
  set ::MAKEBIN make                        ;# Default value
  if {$::tcl_platform(platform)=="windows"} {
    set ::MAKEFILE ./Makefile               ;# Default value on Windows
  } else {
    set ::MAKEFILE ./Makefile.linux-gcc     ;# Default value
  }
  set ::SKIP_RUN 1                          ;# Default to attempt test
  set ::SKIP_RUN 0                          ;# Default to attempt test
  set ::TARGET testfixture                  ;# Default thing to build

  for {set i 0} {$i < [llength $argv]} {incr i} {
    switch -regexp -- [lindex $argv $i] {
      -{1,2}makefile {
        incr i
        set ::MAKEFILE [lindex $argv $i]
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
146
147
148
149
150
151
152



153
154
155
156
157
158
159







-
-
-







        incr i
        set ::TARGET [lindex $argv $i]
      }

      -{1,2}skip_run {
        set ::SKIP_RUN 1
      }
      -{1,2}run {
        set ::SKIP_RUN 0
      }

      -{1,2}help {
        puts $::USAGE_MESSAGE
        exit
      }

      -.* {
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
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







-















-




-





+







    SQLITE_OMIT_AUTOINIT \
    SQLITE_OMIT_AUTOMATIC_INDEX \
    SQLITE_OMIT_AUTORESET \
    SQLITE_OMIT_AUTOVACUUM \
    SQLITE_OMIT_BETWEEN_OPTIMIZATION \
    SQLITE_OMIT_BLOB_LITERAL \
    SQLITE_OMIT_BTREECOUNT \
    SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA \
    SQLITE_OMIT_CAST \
    SQLITE_OMIT_CHECK \
    SQLITE_OMIT_COMPILEOPTION_DIAGS \
    SQLITE_OMIT_COMPLETE \
    SQLITE_OMIT_COMPOUND_SELECT \
    SQLITE_OMIT_CONFLICT_CLAUSE \
    SQLITE_OMIT_CTE \
    SQLITE_OMIT_DATETIME_FUNCS \
    SQLITE_OMIT_DECLTYPE \
    SQLITE_OMIT_DEPRECATED \
    SQLITE_OMIT_DISKIO \
    SQLITE_OMIT_EXPLAIN \
    SQLITE_OMIT_FLAG_PRAGMAS \
    SQLITE_OMIT_FLOATING_POINT \
    SQLITE_OMIT_FOREIGN_KEY \
    SQLITE_OMIT_GENERATED_COLUMNS \
    SQLITE_OMIT_GET_TABLE \
    SQLITE_OMIT_HEX_INTEGER \
    SQLITE_OMIT_INCRBLOB \
    SQLITE_OMIT_INTEGRITY_CHECK \
    SQLITE_OMIT_INTROSPECTION_PRAGMAS \
    SQLITE_OMIT_LIKE_OPTIMIZATION \
    SQLITE_OMIT_LOAD_EXTENSION \
    SQLITE_OMIT_LOCALTIME \
    SQLITE_OMIT_LOOKASIDE \
    SQLITE_OMIT_MEMORYDB \
    SQLITE_OMIT_MEMORY_ALLOCATION \
    SQLITE_OMIT_OR_OPTIMIZATION \
    SQLITE_OMIT_PAGER_PRAGMAS \
    SQLITE_OMIT_PARSER_TRACE \
    SQLITE_OMIT_POPEN \
    SQLITE_OMIT_PRAGMA \
    SQLITE_OMIT_PROGRESS_CALLBACK \
    SQLITE_OMIT_QUICKBALANCE \

Changes to tool/showdb.c.

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
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







-
-
-
-

-

-
+

-
+





+
+
+
+




















-
+







#endif

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sqlite3.h"

typedef unsigned char u8;         /* unsigned 8-bit */
typedef unsigned int u32;         /* unsigned 32-bit */
typedef sqlite3_int64 i64;        /* signed 64-bit */
typedef sqlite3_uint64 u64;       /* unsigned 64-bit */


static struct GlobalData {
  u32 pagesize;                   /* Size of a database page */
  int pagesize;                   /* Size of a database page */
  int dbfd;                       /* File descriptor for reading the DB */
  u32 mxPage;                     /* Last page number */
  int mxPage;                     /* Last page number */
  int perLine;                    /* HEX elements to print per line */
  int bRaw;                       /* True to access db file via OS APIs */
  sqlite3_file *pFd;              /* File descriptor for non-raw mode */
  sqlite3 *pDb;                   /* Database handle that owns pFd */
} g = {1024, -1, 0, 16,   0, 0, 0};


typedef long long int i64;      /* Datatype for 64-bit integers */


/*
** Convert the var-int format into i64.  Return the number of bytes
** in the var-int.  Write the var-int value into *pVal.
*/
static int decodeVarint(const unsigned char *z, i64 *pVal){
  i64 v = 0;
  int i;
  for(i=0; i<8; i++){
    v = (v<<7) + (z[i]&0x7f);
    if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
  }
  v = (v<<8) + (z[i]&0xff);
  *pVal = v;
  return 9;
}

/*
** Extract a big-endian 32-bit integer
*/
static u32 decodeInt32(const u8 *z){
static unsigned int decodeInt32(const unsigned char *z){
  return (z[0]<<24) + (z[1]<<16) + (z[2]<<8) + z[3];
}

/* Report an out-of-memory error and die.
*/
static void out_of_memory(void){
  fprintf(stderr,"Out of memory...\n");
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
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







-
+



















-
-
+
+







**
** Space to hold the content is obtained from sqlite3_malloc() and needs 
** to be freed by the caller.
*/
static unsigned char *fileRead(sqlite3_int64 ofst, int nByte){
  unsigned char *aData;
  int got;
  aData = sqlite3_malloc64(32+(i64)nByte);
  aData = sqlite3_malloc(nByte+32);
  if( aData==0 ) out_of_memory();
  memset(aData, 0, nByte+32);
  if( g.bRaw==0 ){
    int rc = g.pFd->pMethods->xRead(g.pFd, (void*)aData, nByte, ofst);
    if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
      fprintf(stderr, "error in xRead() - %d\n", rc);
      exit(1);
    }
  }else{
    lseek(g.dbfd, (long)ofst, SEEK_SET);
    got = read(g.dbfd, aData, nByte);
    if( got>0 && got<nByte ) memset(aData+got, 0, nByte-got);
  }
  return aData;
}

/*
** Return the size of the file in byte.
*/
static i64 fileGetsize(void){
  i64 res = 0;
static sqlite3_int64 fileGetsize(void){
  sqlite3_int64 res = 0;
  if( g.bRaw==0 ){
    int rc = g.pFd->pMethods->xFileSize(g.pFd, &res);
    if( rc!=SQLITE_OK ){
      fprintf(stderr, "error in xFileSize() - %d\n", rc);
      exit(1);
    }
  }else{
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
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







-
-
-
+
+
+



















-
-
-
-
-
-







** End of low-level file access functions.
**************************************************************************/

/*
** Print a range of bytes as hex and as ascii.
*/
static unsigned char *print_byte_range(
  sqlite3_int64 ofst,  /* First byte in the range of bytes to print */
  int nByte,           /* Number of bytes to print */
  int printOfst        /* Add this amount to the index on the left column */
  int ofst,          /* First byte in the range of bytes to print */
  int nByte,         /* Number of bytes to print */
  int printOfst      /* Add this amount to the index on the left column */
){
  unsigned char *aData;
  int i, j;
  const char *zOfstFmt;

  if( ((printOfst+nByte)&~0xfff)==0 ){
    zOfstFmt = " %03x: ";
  }else if( ((printOfst+nByte)&~0xffff)==0 ){
    zOfstFmt = " %04x: ";
  }else if( ((printOfst+nByte)&~0xfffff)==0 ){
    zOfstFmt = " %05x: ";
  }else if( ((printOfst+nByte)&~0xffffff)==0 ){
    zOfstFmt = " %06x: ";
  }else{
    zOfstFmt = " %08x: ";
  }

  aData = fileRead(ofst, nByte);
  for(i=0; i<nByte; i += g.perLine){
    int go = 0;
    for(j=0; j<g.perLine; j++){
      if( i+j>nByte ){ break; }
      if( aData[i+j] ){ go = 1; break; }
    }
    if( !go && i>0 && i+g.perLine<nByte ) continue;
    fprintf(stdout, zOfstFmt, i+printOfst);
    for(j=0; j<g.perLine; j++){
      if( i+j>nByte ){
        fprintf(stdout, "   ");
      }else{
        fprintf(stdout,"%02x ", aData[i+j]);
      }
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
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







-
-
+
+

-
-
+
+






-
+







-
+












-
+







  }
  return aData;
}

/*
** Print an entire page of content as hex
*/
static void print_page(u32 iPg){
  i64 iStart;
static void print_page(int iPg){
  int iStart;
  unsigned char *aData;
  iStart = ((i64)(iPg-1))*g.pagesize;
  fprintf(stdout, "Page %u:   (offsets 0x%llx..0x%llx)\n",
  iStart = (iPg-1)*g.pagesize;
  fprintf(stdout, "Page %d:   (offsets 0x%x..0x%x)\n",
          iPg, iStart, iStart+g.pagesize-1);
  aData = print_byte_range(iStart, g.pagesize, 0);
  sqlite3_free(aData);
}


/* Print a line of decoded output showing a 4-byte unsigned integer.
/* Print a line of decode output showing a 4-byte integer.
*/
static void print_decode_line(
  unsigned char *aData,      /* Content being decoded */
  int ofst, int nByte,       /* Start and size of decode */
  const char *zMsg           /* Message to append */
){
  int i, j;
  u32 val = aData[ofst];
  int val = aData[ofst];
  char zBuf[100];
  sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]);
  i = (int)strlen(zBuf);
  for(j=1; j<4; j++){
    if( j>=nByte ){
      sprintf(&zBuf[i], "   ");
    }else{
      sprintf(&zBuf[i], " %02x", aData[ofst+j]);
      val = val*256 + aData[ofst+j];
    }
    i += (int)strlen(&zBuf[i]);
  }
  sprintf(&zBuf[i], "   %10u", val);
  sprintf(&zBuf[i], "   %9d", val);
  printf("%s  %s\n", zBuf, zMsg);
}

/*
** Decode the database header.
*/
static void print_db_header(void){
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
292
293
294
295
296
297
298

299
300
301
302
303
304
305







-







  print_decode_line(aData, 72, 4, "meta[8]");
  print_decode_line(aData, 76, 4, "meta[9]");
  print_decode_line(aData, 80, 4, "meta[10]");
  print_decode_line(aData, 84, 4, "meta[11]");
  print_decode_line(aData, 88, 4, "meta[12]");
  print_decode_line(aData, 92, 4, "Change counter for version number");
  print_decode_line(aData, 96, 4, "SQLite version number");
  sqlite3_free(aData);
}

/*
** Describe cell content.
*/
static i64 describeContent(
  unsigned char *a,       /* Cell content */
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
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







-
+









-
+




















-
+


-
+







  unsigned char *a,       /* Cell content */
  int showCellContent,    /* Show cell content if true */
  char **pzDesc           /* Store description here */
){
  int i;
  i64 nDesc = 0;
  int n = 0;
  u32 leftChild;
  int leftChild;
  i64 nPayload;
  i64 rowid;
  i64 nLocal;
  static char zDesc[1000];
  i = 0;
  if( cType<=5 ){
    leftChild = ((a[0]*256 + a[1])*256 + a[2])*256 + a[3];
    a += 4;
    n += 4;
    sprintf(zDesc, "lx: %u ", leftChild);
    sprintf(zDesc, "lx: %d ", leftChild);
    nDesc = strlen(zDesc);
  }
  if( cType!=5 ){
    i = decodeVarint(a, &nPayload);
    a += i;
    n += i;
    sprintf(&zDesc[nDesc], "n: %lld ", nPayload);
    nDesc += strlen(&zDesc[nDesc]);
    nLocal = localPayload(nPayload, cType);
  }else{
    nPayload = nLocal = 0;
  }
  if( cType==5 || cType==13 ){
    i = decodeVarint(a, &rowid);
    a += i;
    n += i;
    sprintf(&zDesc[nDesc], "r: %lld ", rowid);
    nDesc += strlen(&zDesc[nDesc]);
  }
  if( nLocal<nPayload ){
    u32 ovfl;
    int ovfl;
    unsigned char *b = &a[nLocal];
    ovfl = ((b[0]*256 + b[1])*256 + b[2])*256 + b[3];
    sprintf(&zDesc[nDesc], "ov: %u ", ovfl);
    sprintf(&zDesc[nDesc], "ov: %d ", ovfl);
    nDesc += strlen(&zDesc[nDesc]);
    n += 4;
  }
  if( showCellContent && cType!=5 ){
    nDesc += describeContent(a, nLocal, &zDesc[nDesc-1]);
  }
  *pzDesc = zDesc;
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
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







-
+


















-
+







  unsigned char *a,       /* Page content (without the page-1 header) */
  unsigned pgno,          /* Page number */
  int iCell,              /* Cell index */
  int szPgHdr,            /* Size of the page header.  0 or 100 */
  int ofst                /* Cell begins at a[ofst] */
){
  int i, j = 0;
  u32 leftChild;
  int leftChild;
  i64 k;
  i64 nPayload;
  i64 rowid;
  i64 nHdr;
  i64 iType;
  i64 nLocal;
  unsigned char *x = a + ofst;
  unsigned char *end;
  unsigned char cType = a[0];
  int nCol = 0;
  int szCol[2000];
  int ofstCol[2000];
  int typeCol[2000];

  printf("Cell[%d]:\n", iCell);
  if( cType<=5 ){
    leftChild = ((x[0]*256 + x[1])*256 + x[2])*256 + x[3];
    printBytes(a, x, 4);
    printf("left child page:: %u\n", leftChild);
    printf("left child page:: %d\n", leftChild);
    x += 4;
  }
  if( cType!=5 ){
    i = decodeVarint(x, &nPayload);
    printBytes(a, x, i);
    nLocal = localPayload(nPayload, cType);
    if( nLocal==nPayload ){
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640
618
619
620
621
622
623
624

625
626
627
628
629
630
631
632







-
+







  }
  if( j<nLocal ){
    printBytes(a, x+j, 0);
    printf("... %lld bytes of content ...\n", nLocal-j);
  }
  if( nLocal<nPayload ){
    printBytes(a, x+nLocal, 4);
    printf("overflow-page: %u\n", decodeInt32(x+nLocal));
    printf("overflow-page: %d\n", decodeInt32(x+nLocal));
  }
}


/*
** Decode a btree page
*/
733
734
735
736
737
738
739
740

741
742
743
744

745
746
747
748
749
750
751
752
753
754
755



756
757
758
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
788

789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808

809
810
811
812
813
814
815
725
726
727
728
729
730
731

732
733
734
735

736

737
738
739
740
741
742
743



744
745
746
747
748
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
778

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798

799
800
801
802
803
804
805
806







-
+



-
+
-







-
-
-
+
+
+










-
+













-
+







-
+



















-
+







  }
}

/*
** Decode a freelist trunk page.
*/
static void decode_trunk_page(
  u32 pgno,             /* The page number */
  int pgno,             /* The page number */
  int detail,           /* Show leaf pages if true */
  int recursive         /* Follow the trunk change if true */
){
  u32 i;
  int n, i;
  u32 n;
  unsigned char *a;
  while( pgno>0 ){
    a = fileRead((pgno-1)*g.pagesize, g.pagesize);
    printf("Decode of freelist trunk page %d:\n", pgno);
    print_decode_line(a, 0, 4, "Next freelist trunk page");
    print_decode_line(a, 4, 4, "Number of entries on this page");
    if( detail ){
      n = decodeInt32(&a[4]);
      for(i=0; i<n && i<g.pagesize/4; i++){
        u32 x = decodeInt32(&a[8+4*i]);
      n = (int)decodeInt32(&a[4]);
      for(i=0; i<n; i++){
        unsigned int x = decodeInt32(&a[8+4*i]);
        char zIdx[10];
        sprintf(zIdx, "[%d]", i);
        printf("  %5s %7u", zIdx, x);
        if( i%5==4 ) printf("\n");
      }
      if( i%5!=0 ) printf("\n");
    }
    if( !recursive ){
      pgno = 0;
    }else{
      pgno = decodeInt32(&a[0]);
      pgno = (int)decodeInt32(&a[0]);
    }
    sqlite3_free(a);
  }
}

/*
** A short text comment on the use of each page.
*/
static char **zPageUse;

/*
** Add a comment on the use of a page.
*/
static void page_usage_msg(u32 pgno, const char *zFormat, ...){
static void page_usage_msg(int pgno, const char *zFormat, ...){
  va_list ap;
  char *zMsg;

  va_start(ap, zFormat);
  zMsg = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
  if( pgno<=0 || pgno>g.mxPage ){
    printf("ERROR: page %d out of range 1..%u: %s\n",
    printf("ERROR: page %d out of range 1..%d: %s\n",
            pgno, g.mxPage, zMsg);
    sqlite3_free(zMsg);
    return;
  }
  if( zPageUse[pgno]!=0 ){
    printf("ERROR: page %d used multiple times:\n", pgno);
    printf("ERROR:    previous: %s\n", zPageUse[pgno]);
    printf("ERROR:    current:  %s\n", zMsg);
    sqlite3_free(zPageUse[pgno]);
  }
  zPageUse[pgno] = zMsg;
}

/*
** Find overflow pages of a cell and describe their usage.
*/
static void page_usage_cell(
  unsigned char cType,    /* Page type */
  unsigned char *a,       /* Cell content */
  u32 pgno,               /* page containing the cell */
  int pgno,               /* page containing the cell */
  int cellno              /* Index of the cell on the page */
){
  int i;
  int n = 0;
  i64 nPayload;
  i64 rowid;
  i64 nLocal;
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
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







-
-
+
+

-
+








-
-
-
-
-
-
-
+
-
-

-
+
-
-
-


-
-
+
+








-




-
-
-
-
-
-
-
-
-
-




-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-

-
+

+


-
+

-
+







  }
  if( cType==5 || cType==13 ){
    i = decodeVarint(a, &rowid);
    a += i;
    n += i;
  }
  if( nLocal<nPayload ){
    u32 ovfl = decodeInt32(a+nLocal);
    u32 cnt = 0;
    int ovfl = decodeInt32(a+nLocal);
    int cnt = 0;
    while( ovfl && (cnt++)<g.mxPage ){
      page_usage_msg(ovfl, "overflow %d from cell %d of page %u",
      page_usage_msg(ovfl, "overflow %d from cell %d of page %d",
                     cnt, cellno, pgno);
      a = fileRead((ovfl-1)*(sqlite3_int64)g.pagesize, 4);
      ovfl = decodeInt32(a);
      sqlite3_free(a);
    }
  }
}

/*
** True if the memory is all zeros
*/
static int allZero(unsigned char *a, int n){
  while( n && (a++)[0]==0 ){ n--; }
  return n==0;
}



/*
** Describe the usages of a b-tree page.
** Describe the usages of a b-tree page
**
** If parent==0, then this is the root of a btree.  If parent<0 then
** this is an orphan page.
*/
static void page_usage_btree(
  u32 pgno,             /* Page to describe */
  u32 parent,           /* Parent of this page.  0 for root pages */
  int pgno,             /* Page to describe */
  int parent,           /* Parent of this page.  0 for root pages */
  int idx,              /* Which child of the parent */
  const char *zName     /* Name of the table */
){
  unsigned char *a;
  const char *zType = "corrupt node";
  int nCell;
  int i;
  int hdr = pgno==1 ? 100 : 0;
  char zEntry[30];

  if( pgno<=0 || pgno>g.mxPage ) return;
  a = fileRead((pgno-1)*g.pagesize, g.pagesize);
  switch( a[hdr] ){
    case 0: {
      if( allZero(a, g.pagesize) ){
        zType = "zeroed page";
      }else if( parent<0 ){
        return;
      }else{
        zType = "corrupt node";
      }
      break;
    }
    case 2:  zType = "interior node of index";  break;
    case 5:  zType = "interior node of table";  break;
    case 10: zType = "leaf of index";           break;
    case 13: zType = "leaf of table";           break;
    default: {
      if( parent<0 ) return;
      zType = "corrupt node";
    }
  }
  }
  nCell = a[hdr+3]*256 + a[hdr+4];
  if( nCell==1 ){
    sqlite3_snprintf(sizeof(zEntry),zEntry,"1 row");
  }else{
    sqlite3_snprintf(sizeof(zEntry),zEntry,"%d rows", nCell);
  }
  if( parent>0 ){
    page_usage_msg(pgno, "%s [%s], child %d of page %d, %s",
                   zType, zName, idx, parent, zEntry);
  if( parent ){
    page_usage_msg(pgno, "%s [%s], child %d of page %d",
                   zType, zName, idx, parent);
  }else if( parent==0 ){
    page_usage_msg(pgno, "root %s [%s], %s", zType, zName, zEntry);
  }else{
    page_usage_msg(pgno, "orphaned %s, %s", zType, zEntry);
    page_usage_msg(pgno, "root %s [%s]", zType, zName);
  }
  nCell = a[hdr+3]*256 + a[hdr+4];
  if( a[hdr]==2 || a[hdr]==5 ){
    int cellstart = hdr+12;
    u32 child;
    unsigned int child;
    for(i=0; i<nCell; i++){
      u32 ofst;
      int ofst;

      ofst = cellstart + i*2;
      ofst = a[ofst]*256 + a[ofst+1];
      child = decodeInt32(a+ofst);
      page_usage_btree(child, pgno, i, zName);
    }
    child = decodeInt32(a+cellstart-4);
933
934
935
936
937
938
939
940

941
942
943
944
945
946
947
891
892
893
894
895
896
897

898
899
900
901
902
903
904
905







-
+







  }
  sqlite3_free(a);
}

/*
** Determine page usage by the freelist
*/
static void page_usage_freelist(u32 pgno){
static void page_usage_freelist(int pgno){
  unsigned char *a;
  int cnt = 0;
  int i;
  int n;
  int iNext;
  int parent = 1;

960
961
962
963
964
965
966
967
968


969
970

971
972
973

974
975
976
977
978
979
980
981
982
983
984

985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
918
919
920
921
922
923
924


925
926
927

928
929
930

931
932
933
934
935
936
937
938
939
940
941

942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959

960
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976
977

978
979
980
981
982
983
984
985
986
987
988
989
990


991
992
993
994
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
1009







-
-
+
+

-
+


-
+










-
+

















-
+








-
+








-
+












-
-
+










-
+







    pgno = iNext;
  }
}

/*
** Determine pages used as PTRMAP pages
*/
static void page_usage_ptrmap(u8 *a){
  if( decodeInt32(a+52) ){
static void page_usage_ptrmap(unsigned char *a){
  if( a[55] ){
    int usable = g.pagesize - a[20];
    u64 pgno = 2;
    int pgno = 2;
    int perPage = usable/5;
    while( pgno<=g.mxPage ){
      page_usage_msg((u32)pgno, "PTRMAP page covering %llu..%llu",
      page_usage_msg(pgno, "PTRMAP page covering %d..%d",
                           pgno+1, pgno+perPage);
      pgno += perPage + 1;
    }
  }
}

/*
** Try to figure out how every page in the database file is being used.
*/
static void page_usage_report(const char *zPrg, const char *zDbName){
  u32 i, j;
  int i, j;
  int rc;
  sqlite3 *db;
  sqlite3_stmt *pStmt;
  unsigned char *a;
  char zQuery[200];

  /* Avoid the pathological case */
  if( g.mxPage<1 ){
    printf("empty database\n");
    return;
  }

  /* Open the database file */
  db = openDatabase(zPrg, zDbName);

  /* Set up global variables zPageUse[] and g.mxPage to record page
  ** usages */
  zPageUse = sqlite3_malloc64( sizeof(zPageUse[0])*(g.mxPage+1) );
  zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(g.mxPage+1) );
  if( zPageUse==0 ) out_of_memory();
  memset(zPageUse, 0, sizeof(zPageUse[0])*(g.mxPage+1));

  /* Discover the usage of each page */
  a = fileRead(0, 100);
  page_usage_freelist(decodeInt32(a+32));
  page_usage_ptrmap(a);
  sqlite3_free(a);
  page_usage_btree(1, 0, 0, "sqlite_schema");
  page_usage_btree(1, 0, 0, "sqlite_master");
  sqlite3_exec(db, "PRAGMA writable_schema=ON", 0, 0, 0);
  for(j=0; j<2; j++){
    sqlite3_snprintf(sizeof(zQuery), zQuery,
             "SELECT type, name, rootpage FROM SQLITE_MASTER WHERE rootpage"
             " ORDER BY rowid %s", j?"DESC":"");
    rc = sqlite3_prepare_v2(db, zQuery, -1, &pStmt, 0);
    if( rc==SQLITE_OK ){
      while( sqlite3_step(pStmt)==SQLITE_ROW ){
        u32 pgno = (u32)sqlite3_column_int64(pStmt, 2);
        int pgno = sqlite3_column_int(pStmt, 2);
        page_usage_btree(pgno, 0, 0, (const char*)sqlite3_column_text(pStmt,1));
      }
    }else{
      printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db));
    }
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ) break;
  }
  sqlite3_close(db);

  /* Print the report and free memory used */
  for(i=1; i<=g.mxPage; i++){
    if( zPageUse[i]==0 ) page_usage_btree(i, -1, 0, 0);
    printf("%5u: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
    printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
    sqlite3_free(zPageUse[i]);
  }
  sqlite3_free(zPageUse);
  zPageUse = 0;
}

/*
** Try to figure out how every page in the database file is being used.
*/
static void ptrmap_coverage_report(const char *zDbName){
  u64 pgno;
  int pgno;
  unsigned char *aHdr;
  unsigned char *a;
  int usable;
  int perPage;
  int i;

  /* Avoid the pathological case */
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
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







-
+

-
+




-
+







-
+







  if( aHdr[55]==0 ){
    printf("database does not use PTRMAP pages\n");
    return;
  }
  usable = g.pagesize - aHdr[20];
  perPage = usable/5;
  sqlite3_free(aHdr);
  printf("%5d: root of sqlite_schema\n", 1);
  printf("%5d: root of sqlite_master\n", 1);
  for(pgno=2; pgno<=g.mxPage; pgno += perPage+1){
    printf("%5llu: PTRMAP page covering %llu..%llu\n", pgno,
    printf("%5d: PTRMAP page covering %d..%d\n", pgno,
           pgno+1, pgno+perPage);
    a = fileRead((pgno-1)*g.pagesize, usable);
    for(i=0; i+5<=usable && pgno+1+i/5<=g.mxPage; i+=5){
      const char *zType = "???";
      u32 iFrom = decodeInt32(&a[i+1]);
      unsigned int iFrom = decodeInt32(&a[i+1]);
      switch( a[i] ){
        case 1:  zType = "b-tree root page";        break;
        case 2:  zType = "freelist page";           break;
        case 3:  zType = "first page of overflow";  break;
        case 4:  zType = "later page of overflow";  break;
        case 5:  zType = "b-tree non-root page";    break;
      }
      printf("%5llu: %s, parent=%u\n", pgno+1+i/5, zType, iFrom);
      printf("%5d: %s, parent=%u\n", pgno+1+i/5, zType, iFrom);
    }
    sqlite3_free(a);
  }
}

/*
** Print a usage comment
1137
1138
1139
1140
1141
1142
1143
1144

1145
1146

1147
1148

1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160
1094
1095
1096
1097
1098
1099
1100

1101
1102

1103
1104

1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1117







-
+

-
+

-
+




-
+








  zPgSz = fileRead(16, 2);
  g.pagesize = zPgSz[0]*256 + zPgSz[1]*65536;
  if( g.pagesize==0 ) g.pagesize = 1024;
  sqlite3_free(zPgSz);

  printf("Pagesize: %d\n", g.pagesize);
  g.mxPage = (u32)((szFile+g.pagesize-1)/g.pagesize);
  g.mxPage = (int)((szFile+g.pagesize-1)/g.pagesize);

  printf("Available pages: 1..%u\n", g.mxPage);
  printf("Available pages: 1..%d\n", g.mxPage);
  if( nArg==2 ){
    u32 i;
    int i;
    for(i=1; i<=g.mxPage; i++) print_page(i);
  }else{
    int i;
    for(i=2; i<nArg; i++){
      u32 iStart, iEnd;
      int iStart, iEnd;
      char *zLeft;
      if( strcmp(azArg[i], "dbheader")==0 ){
        print_db_header();
        continue;
      }
      if( strcmp(azArg[i], "pgidx")==0 ){
        page_usage_report(zPrg, azArg[1]);
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182
1125
1126
1127
1128
1129
1130
1131

1132
1133
1134
1135
1136
1137
1138
1139







-
+







        usage(zPrg);
        continue;
      }
      if( !ISDIGIT(azArg[i][0]) ){
        fprintf(stderr, "%s: unknown option: [%s]\n", zPrg, azArg[i]);
        continue;
      }
      iStart = strtoul(azArg[i], &zLeft, 0);
      iStart = strtol(azArg[i], &zLeft, 0);
      if( zLeft && strcmp(zLeft,"..end")==0 ){
        iEnd = g.mxPage;
      }else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){
        iEnd = strtol(&zLeft[2], 0, 0);
      }else if( zLeft && zLeft[0]=='b' ){
        int ofst, nByte, hdrSize;
        unsigned char *a;

Changes to tool/showlocks.c.

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
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







-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
+
+
+
-
-
-
+
-
-







/*
** Print all locks on the inode of "fd" that occur in between
** lwr and upr, inclusive.
*/
static int showLocksInRange(int fd, off_t lwr, off_t upr){
  int cnt = 0;
  struct flock x;
  struct lockRange {
    off_t lwr;
    off_t upr;
  } *aPending = 0;
  int nAlloc = 1;
  int nPending = 0;
  int nDone = 0;

  nPending = 1;
  aPending = malloc( sizeof(aPending[0]) );
  if( aPending==0 ){
    fprintf(stderr, "out of memory\n");
    exit(1);
  }
  aPending[0].lwr = lwr;
  aPending[0].upr = upr;

  for(nDone=0; nDone<nPending; nDone++){
    lwr = aPending[nDone].lwr;
    upr = aPending[nDone].upr;
    if( lwr>=upr ) continue;
    x.l_type = F_WRLCK;
    x.l_whence = SEEK_SET;
    x.l_start = lwr;
    x.l_len = upr - lwr;
    fcntl(fd, F_GETLK, &x);
    if( x.l_type==F_UNLCK ) continue;
    printf("start: %-12d len: %-5d pid: %-5d type: %s\n",
         (int)x.l_start, (int)x.l_len,
         x.l_pid, x.l_type==F_WRLCK ? "WRLCK" : "RDLCK");
    cnt++;
  x.l_type = F_WRLCK;
  x.l_whence = SEEK_SET;
  x.l_start = lwr;
  x.l_len = upr-lwr;
  fcntl(fd, F_GETLK, &x);
  if( x.l_type==F_UNLCK ) return 0;
  printf("start: %-12d len: %-5d pid: %-5d type: %s\n",
       (int)x.l_start, (int)x.l_len,
       x.l_pid, x.l_type==F_WRLCK ? "WRLCK" : "RDLCK");
  cnt++;
    if( nPending+2 > nAlloc ){
      nAlloc = nAlloc*2 + 2;
      aPending = realloc(aPending, sizeof(aPending[0])*nAlloc );
    }
    if( aPending==0 ){
      fprintf(stderr, "unable to realloc for %d bytes\n",
                      (int)sizeof(aPending[0])*(nPending+2));
      exit(1);
    }
    if( lwr<x.l_start ){
  if( x.l_start>lwr ){
      aPending[nPending].lwr = lwr;
      aPending[nPending].upr = x.l_start;
    cnt += showLocksInRange(fd, lwr, x.l_start-1);
      nPending++;
    }
    if( x.l_start+x.l_len<=upr ){
      aPending[nPending].lwr = x.l_start + x.l_len;
  }
  if( x.l_start+x.l_len<upr ){
    cnt += showLocksInRange(fd, x.l_start+x.l_len+1, upr);
      aPending[nPending].upr = upr;
      nPending++;
    }
  }
  }
  free(aPending);
  return cnt;
}

int main(int argc, char **argv){
  int fd;
  int cnt;

Changes to tool/spaceanal.tcl.

12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26







-
+







# false otherwise.
#
proc is_without_rowid {tname} {
  set t [string map {' ''} $tname]
  db eval "PRAGMA index_list = '$t'" o {
    if {$o(origin) == "pk"} {
      set n $o(name)
      if {0==[db one { SELECT count(*) FROM sqlite_schema WHERE name=$n }]} {
      if {0==[db one { SELECT count(*) FROM sqlite_master WHERE name=$n }]} {
        return 1
      }
    }
  }
  return 0
}

156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
+







  puts "The SQLite database engine linked with this application\
        lacks required capabilities. Recompile using the\
        -DSQLITE_ENABLE_DBSTAT_VTAB compile-time option to fix\
        this problem."
  exit 1
}

db eval {SELECT count(*) FROM sqlite_schema}
db eval {SELECT count(*) FROM sqlite_master}
set pageSize [expr {wide([db one {PRAGMA page_size}])}]

if {$flags(-pageinfo)} {
  db eval {CREATE VIRTUAL TABLE temp.stat USING dbstat}
  db eval {SELECT name, path, pageno FROM temp.stat ORDER BY pageno} {
    puts "$pageno $name $path"
  }
241
242
243
244
245
246
247
248
249


250
251
252
253
254
255
256
241
242
243
244
245
246
247


248
249
250
251
252
253
254
255
256







-
-
+
+







db eval {CREATE TEMP TABLE dbstat AS SELECT * FROM temp.stat
         ORDER BY name, path}
db eval {DROP TABLE temp.stat}

set isCompressed 0
set compressOverhead 0
set depth 0
set sql { SELECT name, tbl_name FROM sqlite_schema WHERE rootpage>0 }
foreach {name tblname} [concat sqlite_schema sqlite_schema [db eval $sql]] {
set sql { SELECT name, tbl_name FROM sqlite_master WHERE rootpage>0 }
foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] {

  set is_index [expr {$name!=$tblname}]
  set is_without_rowid [is_without_rowid $name]
  db eval {
    SELECT 
      sum(ncell) AS nentry,
      sum((pagetype=='leaf')*ncell) AS leaf_entries,
556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570







-
+







# free_percent:  Percentage of file consumed by free pages (calculated).
# free_percent2: Percentage of file consumed by free pages (header).
# ntable:        Number of tables in the db.
# nindex:        Number of indices in the db.
# nautoindex:    Number of indices created automatically.
# nmanindex:     Number of indices created manually.
# user_payload:  Number of bytes of payload in table btrees 
#                (not including sqlite_schema)
#                (not including sqlite_master)
# user_percent:  $user_payload as a percentage of total file size.

### The following, setting $file_bytes based on the actual size of the file
### on disk, causes this tool to choke on zipvfs databases. So set it based
### on the return of [PRAGMA page_count] instead.
if 0 {
  set file_bytes  [file size $file_to_analyze]
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
583
584
585
586
587
588
589






590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605







-
-
-
-
-
-
+
+
+





-
+







set free_pgcnt    [expr {$file_pgcnt-$inuse_pgcnt-$av_pgcnt}]
set free_percent  [percent $free_pgcnt $file_pgcnt]
set free_pgcnt2   [db one {PRAGMA freelist_count}]
set free_percent2 [percent $free_pgcnt2 $file_pgcnt]

set file_pgcnt2 [expr {$inuse_pgcnt+$free_pgcnt2+$av_pgcnt}]

# Account for the lockbyte page
if {$file_pgcnt2*$pageSize>1073742335} {incr file_pgcnt2}

set ntable [db eval {SELECT count(*)+1 FROM sqlite_schema WHERE type='table'}]
set nindex [db eval {SELECT count(*) FROM sqlite_schema WHERE type='index'}]
set sql {SELECT count(*) FROM sqlite_schema WHERE name LIKE 'sqlite_autoindex%'}
set ntable [db eval {SELECT count(*)+1 FROM sqlite_master WHERE type='table'}]
set nindex [db eval {SELECT count(*) FROM sqlite_master WHERE type='index'}]
set sql {SELECT count(*) FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'}
set nautoindex [db eval $sql]
set nmanindex [expr {$nindex-$nautoindex}]

# set total_payload [mem eval "SELECT sum(payload) FROM space_used"]
set user_payload [mem one {SELECT int(sum(payload)) FROM space_used
     WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'}]
     WHERE NOT is_index AND name NOT LIKE 'sqlite_master'}]
set user_percent [percent $user_payload $file_bytes]

# Output the summary statistics calculated above.
#
puts "/** Disk-Space Utilization Report For $root_filename"
puts ""
statline {Page size in bytes} $pageSize

Changes to tool/speed-check.sh.

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
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







-
-
-
-
-
-
-
-
-





-
-
-
-










-
-
-







        ;;
    --without-rowid)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --nomemstat)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --multithread)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --singlethread)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --serialized)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --temp)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS --temp 6"
        ;;
    --legacy)
	doWal=0
        CC_OPTS="$CC_OPTS -DSPEEDTEST_OMIT_HASH"
        ;;
    --verify)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS --verify"
        ;;
    --wal)
        doWal=1
        ;;
    --size)
        shift; SIZE=$1
        ;;
    --cachesize)
        shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --cachesize $1"
        ;;
    --checkpoint)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS --checkpoint"
        ;;
    --explain)
        doExplain=1
        ;;
    --vdbeprofile)
        rm -f vdbe_profile.out
        CC_OPTS="$CC_OPTS -DVDBE_PROFILE"
        doCachegrind=0

Changes to tool/sqldiff.c.

412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426







-
+







  int nPk;                  /* Number of true primary key columns */
  int nCol;                 /* Number of data columns */
  int i;                    /* Loop counter */
  sqlite3_stmt *pStmt;      /* SQL statement */
  const char *zSep;         /* Separator string */
  Str ins;                  /* Beginning of the INSERT statement */

  pStmt = db_prepare("SELECT sql FROM aux.sqlite_schema WHERE name=%Q", zTab);
  pStmt = db_prepare("SELECT sql FROM aux.sqlite_master WHERE name=%Q", zTab);
  if( SQLITE_ROW==sqlite3_step(pStmt) ){
    fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
  }
  sqlite3_finalize(pStmt);
  if( !g.bSchemaOnly ){
    az = columnNames("aux", zTab, &nPk, 0);
    strInit(&ins);
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
462
463
464
465
466
467
468

469
470
471
472
473
474
475

476
477
478
479
480
481
482







-
+






-







        zSep = ",";
      }
      fprintf(out, ");\n");
    }
    sqlite3_finalize(pStmt);
    strFree(&ins);
  } /* endif !g.bSchemaOnly */
  pStmt = db_prepare("SELECT sql FROM aux.sqlite_schema"
  pStmt = db_prepare("SELECT sql FROM aux.sqlite_master"
                     " WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL",
                     zTab);
  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
  }
  sqlite3_finalize(pStmt);
  sqlite3_free(zId);
}


/*
** Compute all differences for a single table.
*/
static void diff_one_table(const char *zTab, FILE *out){
636
637
638
639
640
641
642
643

644
645
646

647
648
649
650
651
652
653
635
636
637
638
639
640
641

642
643
644

645
646
647
648
649
650
651
652







-
+


-
+







  if( g.fDebug & DEBUG_DIFF_SQL ){ 
    printf("SQL for %s:\n%s\n", zId, sql.z);
    goto end_diff_one_table;
  }

  /* Drop indexes that are missing in the destination */
  pStmt = db_prepare(
    "SELECT name FROM main.sqlite_schema"
    "SELECT name FROM main.sqlite_master"
    " WHERE type='index' AND tbl_name=%Q"
    "   AND sql IS NOT NULL"
    "   AND sql NOT IN (SELECT sql FROM aux.sqlite_schema"
    "   AND sql NOT IN (SELECT sql FROM aux.sqlite_master"
    "                    WHERE type='index' AND tbl_name=%Q"
    "                      AND sql IS NOT NULL)",
    zTab, zTab);
  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
    fprintf(out, "DROP INDEX %s;\n", z);
    sqlite3_free(z);
697
698
699
700
701
702
703
704

705
706
707

708
709
710
711
712
713
714
696
697
698
699
700
701
702

703
704
705

706
707
708
709
710
711
712
713







-
+


-
+







      }
    }
    sqlite3_finalize(pStmt);
  } /* endif !g.bSchemaOnly */

  /* Create indexes that are missing in the source */
  pStmt = db_prepare(
    "SELECT sql FROM aux.sqlite_schema"
    "SELECT sql FROM aux.sqlite_master"
    " WHERE type='index' AND tbl_name=%Q"
    "   AND sql IS NOT NULL"
    "   AND sql NOT IN (SELECT sql FROM main.sqlite_schema"
    "   AND sql NOT IN (SELECT sql FROM main.sqlite_master"
    "                    WHERE type='index' AND tbl_name=%Q"
    "                      AND sql IS NOT NULL)",
    zTab, zTab);
  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
  }
  sqlite3_finalize(pStmt);
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
724
725
726
727
728
729
730

731
732
733
734
735
736
737
738







-
+







** Check that table zTab exists and has the same schema in both the "main"
** and "aux" databases currently opened by the global db handle. If they
** do not, output an error message on stderr and exit(1). Otherwise, if
** the schemas do match, return control to the caller.
*/
static void checkSchemasMatch(const char *zTab){
  sqlite3_stmt *pStmt = db_prepare(
      "SELECT A.sql=B.sql FROM main.sqlite_schema A, aux.sqlite_schema B"
      "SELECT A.sql=B.sql FROM main.sqlite_master A, aux.sqlite_master B"
      " WHERE A.name=%Q AND B.name=%Q", zTab, zTab
  );
  if( SQLITE_ROW==sqlite3_step(pStmt) ){
    if( sqlite3_column_int(pStmt,0)==0 ){
      runtimeError("schema changes for table %s", safeId(zTab));
    }
  }else{
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553







-







  int nPk = 0;                  /* Number of PRIMARY KEY columns */
  Str sql;                      /* SQL for the diff query */
  int i, k;                     /* Loop counters */
  const char *zSep;             /* List separator */

  /* Check that the schemas of the two tables match. Exit early otherwise. */
  checkSchemasMatch(zTab);
  strInit(&sql);

  pStmt = db_prepare("PRAGMA main.table_info=%Q", zTab);
  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    nCol++;
    azCol = sqlite3_realloc(azCol, sizeof(char*)*nCol);
    if( azCol==0 ) runtimeError("out of memory");
    aiFlg = sqlite3_realloc(aiFlg, sizeof(int)*nCol);
1563
1564
1565
1566
1567
1568
1569

1570
1571
1572
1573
1574
1575
1576
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575







+







        if( aiPk==0 ) runtimeError("out of memory");
      }
      aiPk[i-1] = nCol-1;
    }
  }
  sqlite3_finalize(pStmt);
  if( nPk==0 ) goto end_changeset_one_table; 
  strInit(&sql);
  if( nCol>nPk ){
    strPrintf(&sql, "SELECT %d", SQLITE_UPDATE);
    for(i=0; i<nCol; i++){
      if( aiFlg[i] ){
        strPrintf(&sql, ",\n       A.%s", azCol[i]);
      }else{
        strPrintf(&sql, ",\n       A.%s IS NOT B.%s, A.%s, B.%s",
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729

1730
1731
1732
1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755

1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777
1778
1703
1704
1705
1706
1707
1708
1709










1710
1711
1712
1713
1714
1715
1716
1717

1718
1719
1720
1721
1722
1723
1724

1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743

1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765
1766
1767







-
-
-
-
-
-
-
-
-
-








-
+






-
+


















-
+















-
+







  sqlite3_finalize(pStmt);
  
end_changeset_one_table:
  while( nCol>0 ) sqlite3_free(azCol[--nCol]);
  sqlite3_free(azCol);
  sqlite3_free(aiPk);
  sqlite3_free(zId);
  sqlite3_free(aiFlg);
  strFree(&sql);
}

/*
** Return true if the ascii character passed as the only argument is a
** whitespace character. Otherwise return false.
*/
static int is_whitespace(char x){
  return (x==' ' || x=='\t' || x=='\n' || x=='\r');
}

/*
** Extract the next SQL keyword or quoted string from buffer zIn and copy it
** (or a prefix of it if it will not fit) into buffer zBuf, size nBuf bytes.
** Return a pointer to the character within zIn immediately following 
** the token or quoted string just extracted.
*/
static const char *gobble_token(const char *zIn, char *zBuf, int nBuf){
const char *gobble_token(const char *zIn, char *zBuf, int nBuf){
  const char *p = zIn;
  char *pOut = zBuf;
  char *pEnd = &pOut[nBuf-1];
  char q = 0;                     /* quote character, if any */

  if( p==0 ) return 0;
  while( is_whitespace(*p) ) p++;
  while( *p==' ' ) p++;
  switch( *p ){
    case '"': q = '"'; break;
    case '\'': q = '\''; break;
    case '`': q = '`'; break;
    case '[': q = ']'; break;
  }

  if( q ){
    p++;
    while( *p && pOut<pEnd ){
      if( *p==q ){
        p++;
        if( *p!=q ) break;
      }
      if( pOut<pEnd ) *pOut++ = *p;
      p++;
    }
  }else{
    while( *p && !is_whitespace(*p) && *p!='(' ){
    while( *p && *p!=' ' && *p!='(' ){
      if( pOut<pEnd ) *pOut++ = *p;
      p++;
    }
  }

  *pOut = '\0';
  return p;
}

/*
** This function is the implementation of SQL scalar function "module_name":
**
**   module_name(SQL)
**
** The only argument should be an SQL statement of the type that may appear
** in the sqlite_schema table. If the statement is a "CREATE VIRTUAL TABLE"
** in the sqlite_master table. If the statement is a "CREATE VIRTUAL TABLE"
** statement, then the value returned is the name of the module that it
** uses. Otherwise, if the statement is not a CVT, NULL is returned.
*/
static void module_name_func(
  sqlite3_context *pCtx, 
  int nVal, sqlite3_value **apVal
){
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
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







-
+





-
+



-
+





-
+





-
+


-
+







  
    rc = sqlite3_create_function(
        g.db, "module_name", 1, SQLITE_UTF8, 0, module_name_func, 0, 0
    );
    assert( rc==SQLITE_OK );
  
    return 
      "SELECT name FROM main.sqlite_schema\n"
      "SELECT name FROM main.sqlite_master\n"
      " WHERE type='table' AND (\n"
      "    module_name(sql) IS NULL OR \n"
      "    module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
      " ) AND name NOT IN (\n"
      "  SELECT a.name || b.postfix \n"
        "FROM main.sqlite_schema AS a, temp.tblmap AS b \n"
        "FROM main.sqlite_master AS a, temp.tblmap AS b \n"
        "WHERE module_name(a.sql) = b.module\n" 
      " )\n"
      "UNION \n"
      "SELECT name FROM aux.sqlite_schema\n"
      "SELECT name FROM aux.sqlite_master\n"
      " WHERE type='table' AND (\n"
      "    module_name(sql) IS NULL OR \n"
      "    module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
      " ) AND name NOT IN (\n"
      "  SELECT a.name || b.postfix \n"
        "FROM aux.sqlite_schema AS a, temp.tblmap AS b \n"
        "FROM aux.sqlite_master AS a, temp.tblmap AS b \n"
        "WHERE module_name(a.sql) = b.module\n" 
      " )\n"
      " ORDER BY name";
  }else{
    return
      "SELECT name FROM main.sqlite_schema\n"
      "SELECT name FROM main.sqlite_master\n"
      " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
      " UNION\n"
      "SELECT name FROM aux.sqlite_schema\n"
      "SELECT name FROM aux.sqlite_master\n"
      " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
      " ORDER BY name";
  }
}

/*
** Print sketchy documentation for this utility program
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
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







-
+















-
-



-
+







  if( zDb2==0 ){
    cmdlineError("two database arguments required");
  }
  rc = sqlite3_open(zDb1, &g.db);
  if( rc ){
    cmdlineError("cannot open database file \"%s\"", zDb1);
  }
  rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_schema", 0, 0, &zErrMsg);
  rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
  if( rc || zErrMsg ){
    cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
  }
#ifndef SQLITE_OMIT_LOAD_EXTENSION
  sqlite3_enable_load_extension(g.db, 1);
  for(i=0; i<nExt; i++){
    rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg);
    if( rc || zErrMsg ){
      cmdlineError("error loading %s: %s", azExt[i], zErrMsg);
    }
  }
  free(azExt);
#endif
  zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
  rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
  sqlite3_free(zSql);
  zSql = 0;
  if( rc || zErrMsg ){
    cmdlineError("cannot attach database \"%s\"", zDb2);
  }
  rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_schema", 0, 0, &zErrMsg);
  rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_master", 0, 0, &zErrMsg);
  if( rc || zErrMsg ){
    cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb2);
  }

  if( neverUseTransaction ) useTransaction = 0;
  if( useTransaction ) fprintf(out, "BEGIN TRANSACTION;\n");
  if( xDiff==rbudiff_one_table ){

Changes to vsixtest/App.xaml.cpp.