/ Check-in [54bec164]
Login

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

Overview
Comment:Import recent enhancements from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1:54bec164ebeaf62d783352b3c4d0de8845394091
User & Date: drh 2015-05-29 19:04:58
Context
2015-06-02
09:19
Modify the sessions module to ignore all operations on tables with no primary keys as documented. check-in: bdaf9575 user: dan tags: sessions
2015-05-29
19:04
Import recent enhancements from trunk. check-in: 54bec164 user: drh tags: sessions
18:42
Ensure that allocateBtreePage() always clears the MemPage pointer when it fails due to an I/O or memory allocation error. check-in: 09a38bf6 user: drh tags: trunk
2015-05-22
23:51
Merge bug fixes from trunk. check-in: 519054bb user: drh tags: sessions
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.in.

525
526
527
528
529
530
531






532
533
534
535
536
537
538
...
554
555
556
557
558
559
560
561
562
563
564



565
566
567
568
569
570
571
...
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
....
1130
1131
1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
#
TESTPROGS = \
  testfixture$(TEXE) \
  sqlite3$(TEXE) \
  sqlite3_analyzer$(TEXE) \
  sqldiff$(TEXE)








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

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

sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h
	$(LTLINK) $(READLINE_FLAGS) \
		-o $@ $(TOP)/src/shell.c libsqlite3.la \
		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"

sqldiff$(TEXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
	$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c	sqlite3.c $(TLIBS)

fuzzershell$(TEXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
	$(LTLINK) -o $@ $(TOP)/tool/fuzzershell.c	sqlite3.c $(TLIBS)




mptester$(TEXE):	sqlite3.c $(TOP)/mptest/mptest.c
	$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
		$(TLIBS) -rpath "$(libdir)"

MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
................................................................................
		-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)

# A very detailed test running most or all test cases
fulltest:	$(TESTPROGS) fuzztest
	./testfixture$(TEXE) $(TOP)/test/all.test

# Really really long testing
soaktest:	$(TESTPROGS) fuzzoomtest
	./testfixture$(TEXE) $(TOP)/test/all.test -soak=1

# Do extra testing but not everything.
fulltestonly:	$(TESTPROGS)
	./testfixture$(TEXE) $(TOP)/test/full.test

# Fuzz testing
fuzztest:	fuzzershell$(TEXE)
	./fuzzershell$(TEXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt

fuzzoomtest:	fuzzershell$(TEXE)
	./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt --oom

# This is the common case.  Run many tests but not those that take
# a really long time.
#
test:	$(TESTPROGS) fuzztest
	./testfixture$(TEXE) $(TOP)/test/veryquick.test

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

# 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) fuzzershell$(TEXE)
	./testfixture$(TEXE) $(TOP)/test/main.test

sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
	echo "#define TCLSH 2" > $@
	echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
	cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
	echo "static const char *tclsh_main_loop(void){" >> $@
................................................................................
	rm -f sqlite3.c
	rm -f sqlite3rc.h
	rm -f shell.c sqlite3ext.h
	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
	rm -f sqlite-*-output.vsix
	rm -f mptester mptester.exe
	rm -f fuzzershell fuzzershell.exe

	rm -f sqldiff sqldiff.exe

distclean:	clean
	rm -f config.log config.status libtool Makefile sqlite3.pc

#
# Windows section







>
>
>
>
>
>







 







|


|
>
>
>







 







|







|
|
<
<
<










|
|






|







 







>







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
...
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
....
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
#
TESTPROGS = \
  testfixture$(TEXE) \
  sqlite3$(TEXE) \
  sqlite3_analyzer$(TEXE) \
  sqldiff$(TEXE)

# Databases containing fuzzer test cases
#
FUZZDATA = \
  $(TOP)/test/fuzzdata1.db \
  $(TOP)/test/fuzzdata2.db \
  $(TOP)/test/fuzzdata3.db

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

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

sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h
	$(LTLINK) $(READLINE_FLAGS) \
		-o $@ $(TOP)/src/shell.c libsqlite3.la \
		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"

sqldiff$(TEXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
	$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)

fuzzershell$(TEXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
	$(LTLINK) -o $@ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)

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

mptester$(TEXE):	sqlite3.c $(TOP)/mptest/mptest.c
	$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
		$(TLIBS) -rpath "$(libdir)"

MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
................................................................................
		-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)

# A very detailed test running most or all test cases
fulltest:	$(TESTPROGS) fuzztest
	./testfixture$(TEXE) $(TOP)/test/all.test

# Really really long testing
soaktest:	$(TESTPROGS)
	./testfixture$(TEXE) $(TOP)/test/all.test -soak=1

# Do extra testing but not everything.
fulltestonly:	$(TESTPROGS)
	./testfixture$(TEXE) $(TOP)/test/full.test

# Fuzz testing
fuzztest:	fuzzcheck$(TEXE)
	./fuzzcheck$(TEXE) $(FUZZDATA)




# This is the common case.  Run many tests but not those that take
# a really long time.
#
test:	$(TESTPROGS) fuzztest
	./testfixture$(TEXE) $(TOP)/test/veryquick.test

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

# 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

sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
	echo "#define TCLSH 2" > $@
	echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
	cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
	echo "static const char *tclsh_main_loop(void){" >> $@
................................................................................
	rm -f sqlite3.c
	rm -f sqlite3rc.h
	rm -f shell.c sqlite3ext.h
	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
	rm -f sqlite-*-output.vsix
	rm -f mptester mptester.exe
	rm -f fuzzershell fuzzershell.exe
	rm -f fuzzcheck fuzzcheck.exe
	rm -f sqldiff sqldiff.exe

distclean:	clean
	rm -f config.log config.status libtool Makefile sqlite3.pc

#
# Windows section

Changes to Makefile.msc.

1210
1211
1212
1213
1214
1215
1216







1217
1218
1219
1220
1221
1222
1223
....
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238



1239
1240
1241
1242
1243
1244
1245
1246
1247
....
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
....
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
#
TESTPROGS = \
  testfixture.exe \
  sqlite3.exe \
  sqlite3_analyzer.exe \
  sqldiff.exe









# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	dll libsqlite3.lib sqlite3.exe libtclsqlite3.lib

libsqlite3.lib:	$(LIBOBJ)
................................................................................
	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)

sqlite3.exe:	$(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \
		/link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)

sqldiff.exe:	$(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
	$(LTLINK) $(TOP)\tool\sqldiff.c sqlite3.c

fuzzershell.exe:	$(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
	$(LTLINK) $(TOP)\tool\fuzzershell.c sqlite3.c




mptester.exe:	$(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
	$(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
		/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)

MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20

mptest:	mptester.exe
	del /Q mptest.db 2>NUL
................................................................................

extensiontest: testfixture.exe testloadext.dll
	.\testfixture.exe $(TOP)\test\loadext.test

fulltest:	$(TESTPROGS) fuzztest
	.\testfixture.exe $(TOP)\test\all.test

soaktest:	$(TESTPROGS) fuzzoomtest
	.\testfixture.exe $(TOP)\test\all.test -soak=1

fulltestonly:	$(TESTPROGS) fuzztest
	.\testfixture.exe $(TOP)\test\full.test

queryplantest:	testfixture.exe sqlite3.exe
	.\testfixture.exe $(TOP)\test\permutations.test queryplanner

fuzztest:	fuzzershell.exe
	.\fuzzershell.exe $(TOP)\test\fuzzdata1.txt $(TOP)\test\fuzzdata2.txt

fuzzoomtest:	fuzzershell.exe
	.\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt --oom

test:	$(TESTPROGS) fuzztest
	.\testfixture.exe $(TOP)\test\veryquick.test

smoketest:	$(TESTPROGS) fuzzershell.exe
	.\testfixture.exe $(TOP)\test\main.test

sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
	echo #define TCLSH 2 > $@
	echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
	echo static const char *tclsh_main_loop(void){ >> $@
................................................................................
	del /Q mptester.exe wordcount.exe 2>NUL
	del /Q sqlite3.exe sqlite3.dll sqlite3.def 2>NUL
	del /Q sqlite3.c sqlite3-*.c 2>NUL
	del /Q sqlite3rc.h 2>NUL
	del /Q shell.c sqlite3ext.h 2>NUL
	del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
	del /Q sqlite-*-output.vsix 2>NUL
	del /Q fuzzershell.exe sqldiff.exe 2>NUL

# Dynamic link library section.
#
dll: sqlite3.dll

sqlite3.def: libsqlite3.lib
	echo EXPORTS > sqlite3.def
	dumpbin /all libsqlite3.lib \
		| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
		| sort >> sqlite3.def

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







>
>
>
>
>
>
>







 







|


|

>
>
>

|







 







|








|
|
<
<
<




|







 







|













1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
....
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
....
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
....
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
#
TESTPROGS = \
  testfixture.exe \
  sqlite3.exe \
  sqlite3_analyzer.exe \
  sqldiff.exe

# Databases containing fuzzer test cases
#
FUZZDATA = \
  $(TOP)\test\fuzzdata1.db \
  $(TOP)\test\fuzzdata2.db \
  $(TOP)\test\fuzzdata3.db


# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	dll libsqlite3.lib sqlite3.exe libtclsqlite3.lib

libsqlite3.lib:	$(LIBOBJ)
................................................................................
	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)

sqlite3.exe:	$(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \
		/link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)

sqldiff.exe:	$(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
	$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c

fuzzershell.exe:	$(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
	$(LTLINK) $(NO_WARN) $(TOP)\tool\fuzzershell.c sqlite3.c

fuzzcheck.exe:	$(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h
	$(LTLINK) $(NO_WARN) $(TOP)\test\fuzzcheck.c sqlite3.c

mptester.exe:	$(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
	$(LTLINK) $(NO_WARN) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
		/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)

MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20

mptest:	mptester.exe
	del /Q mptest.db 2>NUL
................................................................................

extensiontest: testfixture.exe testloadext.dll
	.\testfixture.exe $(TOP)\test\loadext.test

fulltest:	$(TESTPROGS) fuzztest
	.\testfixture.exe $(TOP)\test\all.test

soaktest:	$(TESTPROGS)
	.\testfixture.exe $(TOP)\test\all.test -soak=1

fulltestonly:	$(TESTPROGS) fuzztest
	.\testfixture.exe $(TOP)\test\full.test

queryplantest:	testfixture.exe sqlite3.exe
	.\testfixture.exe $(TOP)\test\permutations.test queryplanner

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




test:	$(TESTPROGS) fuzztest
	.\testfixture.exe $(TOP)\test\veryquick.test

smoketest:	$(TESTPROGS)
	.\testfixture.exe $(TOP)\test\main.test

sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
	echo #define TCLSH 2 > $@
	echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
	echo static const char *tclsh_main_loop(void){ >> $@
................................................................................
	del /Q mptester.exe wordcount.exe 2>NUL
	del /Q sqlite3.exe sqlite3.dll sqlite3.def 2>NUL
	del /Q sqlite3.c sqlite3-*.c 2>NUL
	del /Q sqlite3rc.h 2>NUL
	del /Q shell.c sqlite3ext.h 2>NUL
	del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
	del /Q sqlite-*-output.vsix 2>NUL
	del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL

# Dynamic link library section.
#
dll: sqlite3.dll

sqlite3.def: libsqlite3.lib
	echo EXPORTS > sqlite3.def
	dumpbin /all libsqlite3.lib \
		| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
		| sort >> sqlite3.def

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

Changes to ext/fts3/fts3.c.

5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
....
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
....
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
....
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
....
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
....
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
**      is advanced to the next row that contains an instance of "A * C", 
**      where "*" may match any single token. The position list in this case
**      is populated as for "A * C" before returning.
**
**   2. NEAR is treated as AND. If the expression is "x NEAR y", it is 
**      advanced to point to the next row that matches "x AND y".
** 
** See fts3EvalTestDeferredAndNear() for details on testing if a row is
** really a match, taking into account deferred tokens and NEAR operators.
*/
static void fts3EvalNextRow(
  Fts3Cursor *pCsr,               /* FTS Cursor handle */
  Fts3Expr *pExpr,                /* Expr. to advance to next matching row */
  int *pRc                        /* IN/OUT: Error code */
){
................................................................................
    }
  }

  return res;
}

/*
** This function is a helper function for fts3EvalTestDeferredAndNear().
** Assuming no error occurs or has occurred, It returns non-zero if the
** expression passed as the second argument matches the row that pCsr 
** currently points to, or zero if it does not.
**
** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
** If an error occurs during execution of this function, *pRc is set to 
** the appropriate SQLite error code. In this case the returned value is 
................................................................................
**
**   2. After scanning the current FTS table row for the deferred tokens,
**      it is determined that the row does *not* match the query.
**
** Or, if no error occurs and it seems the current row does match the FTS
** query, return 0.
*/
static int fts3EvalTestDeferredAndNear(Fts3Cursor *pCsr, int *pRc){
  int rc = *pRc;
  int bMiss = 0;
  if( rc==SQLITE_OK ){

    /* If there are one or more deferred tokens, load the current row into
    ** memory and scan it to determine the position list for each deferred
    ** token. Then, see if this row is really a match, considering deferred
................................................................................
      }
      assert( sqlite3_data_count(pCsr->pStmt)==0 );
      fts3EvalNextRow(pCsr, pExpr, &rc);
      pCsr->isEof = pExpr->bEof;
      pCsr->isRequireSeek = 1;
      pCsr->isMatchinfoNeeded = 1;
      pCsr->iPrevId = pExpr->iDocid;
    }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) );
  }

  /* Check if the cursor is past the end of the docid range specified
  ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag.  */
  if( rc==SQLITE_OK && (
        (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid)
     || (pCsr->bDesc!=0 && pCsr->iPrevId<pCsr->iMinDocid)
................................................................................
        fts3EvalNextRow(pCsr, pRoot, &rc);
        pCsr->isEof = pRoot->bEof;
        pCsr->isRequireSeek = 1;
        pCsr->isMatchinfoNeeded = 1;
        pCsr->iPrevId = pRoot->iDocid;
      }while( pCsr->isEof==0 
           && pRoot->eType==FTSQUERY_NEAR 
           && fts3EvalTestDeferredAndNear(pCsr, &rc) 
      );

      if( rc==SQLITE_OK && pCsr->isEof==0 ){
        fts3EvalUpdateCounts(pRoot);
      }
    }

................................................................................
      **   do {...} while( pRoot->iDocid<iDocid && rc==SQLITE_OK );
      */
      fts3EvalRestart(pCsr, pRoot, &rc);
      do {
        fts3EvalNextRow(pCsr, pRoot, &rc);
        assert( pRoot->bEof==0 );
      }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );
      fts3EvalTestDeferredAndNear(pCsr, &rc);
    }
  }
  return rc;
}

/*
** This function is used by the matchinfo() module to query a phrase 







|







 







|







 







|







 







|







 







|







 







<







5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
....
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
....
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
....
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
....
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
....
5644
5645
5646
5647
5648
5649
5650

5651
5652
5653
5654
5655
5656
5657
**      is advanced to the next row that contains an instance of "A * C", 
**      where "*" may match any single token. The position list in this case
**      is populated as for "A * C" before returning.
**
**   2. NEAR is treated as AND. If the expression is "x NEAR y", it is 
**      advanced to point to the next row that matches "x AND y".
** 
** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is
** really a match, taking into account deferred tokens and NEAR operators.
*/
static void fts3EvalNextRow(
  Fts3Cursor *pCsr,               /* FTS Cursor handle */
  Fts3Expr *pExpr,                /* Expr. to advance to next matching row */
  int *pRc                        /* IN/OUT: Error code */
){
................................................................................
    }
  }

  return res;
}

/*
** This function is a helper function for sqlite3Fts3EvalTestDeferred().
** Assuming no error occurs or has occurred, It returns non-zero if the
** expression passed as the second argument matches the row that pCsr 
** currently points to, or zero if it does not.
**
** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
** If an error occurs during execution of this function, *pRc is set to 
** the appropriate SQLite error code. In this case the returned value is 
................................................................................
**
**   2. After scanning the current FTS table row for the deferred tokens,
**      it is determined that the row does *not* match the query.
**
** Or, if no error occurs and it seems the current row does match the FTS
** query, return 0.
*/
int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){
  int rc = *pRc;
  int bMiss = 0;
  if( rc==SQLITE_OK ){

    /* If there are one or more deferred tokens, load the current row into
    ** memory and scan it to determine the position list for each deferred
    ** token. Then, see if this row is really a match, considering deferred
................................................................................
      }
      assert( sqlite3_data_count(pCsr->pStmt)==0 );
      fts3EvalNextRow(pCsr, pExpr, &rc);
      pCsr->isEof = pExpr->bEof;
      pCsr->isRequireSeek = 1;
      pCsr->isMatchinfoNeeded = 1;
      pCsr->iPrevId = pExpr->iDocid;
    }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) );
  }

  /* Check if the cursor is past the end of the docid range specified
  ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag.  */
  if( rc==SQLITE_OK && (
        (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid)
     || (pCsr->bDesc!=0 && pCsr->iPrevId<pCsr->iMinDocid)
................................................................................
        fts3EvalNextRow(pCsr, pRoot, &rc);
        pCsr->isEof = pRoot->bEof;
        pCsr->isRequireSeek = 1;
        pCsr->isMatchinfoNeeded = 1;
        pCsr->iPrevId = pRoot->iDocid;
      }while( pCsr->isEof==0 
           && pRoot->eType==FTSQUERY_NEAR 
           && sqlite3Fts3EvalTestDeferred(pCsr, &rc) 
      );

      if( rc==SQLITE_OK && pCsr->isEof==0 ){
        fts3EvalUpdateCounts(pRoot);
      }
    }

................................................................................
      **   do {...} while( pRoot->iDocid<iDocid && rc==SQLITE_OK );
      */
      fts3EvalRestart(pCsr, pRoot, &rc);
      do {
        fts3EvalNextRow(pCsr, pRoot, &rc);
        assert( pRoot->bEof==0 );
      }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );

    }
  }
  return rc;
}

/*
** This function is used by the matchinfo() module to query a phrase 

Changes to ext/fts3/fts3Int.h.

547
548
549
550
551
552
553

554
555
556
557
558
559
560
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*);


/* fts3_tokenizer.c */
const char *sqlite3Fts3NextToken(const char *, int *);
int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, 
    sqlite3_tokenizer **, char **
);







>







547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
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);

/* 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_snippet.c.

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
....
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
** for details.
*/
struct MatchinfoBuffer {
  u8 aRef[3];
  int nElem;
  int bGlobal;                    /* Set if global data is loaded */
  char *zMatchinfo;
  u32 aMatchinfo[0];
};


/*
** The snippet() and offsets() functions both return text values. An instance
** of the following structure is used to accumulate those values while the
** functions are running. See fts3StringAppend() for details.
................................................................................
*/

/*
** Allocate a two-slot MatchinfoBuffer object.
*/
static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
  MatchinfoBuffer *pRet;
  int nByte = sizeof(u32) * (2*nElem + 2) + sizeof(MatchinfoBuffer);
  int nStr = (int)strlen(zMatchinfo);

  pRet = sqlite3_malloc(nByte + nStr+1);
  if( pRet ){
    memset(pRet, 0, nByte);
    pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
    pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
................................................................................
        if( rc!=SQLITE_OK ) break;
        if( bGlobal ){
          if( pCsr->pDeferred ){
            rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0);
            if( rc!=SQLITE_OK ) break;
          }
          rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);

          if( rc!=SQLITE_OK ) break;
        }
        (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
        break;
      }
    }








|







 







|







 







>







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
....
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
** for details.
*/
struct MatchinfoBuffer {
  u8 aRef[3];
  int nElem;
  int bGlobal;                    /* Set if global data is loaded */
  char *zMatchinfo;
  u32 aMatchinfo[1];
};


/*
** The snippet() and offsets() functions both return text values. An instance
** of the following structure is used to accumulate those values while the
** functions are running. See fts3StringAppend() for details.
................................................................................
*/

/*
** Allocate a two-slot MatchinfoBuffer object.
*/
static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
  MatchinfoBuffer *pRet;
  int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
  int nStr = (int)strlen(zMatchinfo);

  pRet = sqlite3_malloc(nByte + nStr+1);
  if( pRet ){
    memset(pRet, 0, nByte);
    pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
    pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
................................................................................
        if( rc!=SQLITE_OK ) break;
        if( bGlobal ){
          if( pCsr->pDeferred ){
            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);
        break;
      }
    }

Changes to main.mk.

406
407
408
409
410
411
412







413
414
415
416
417
418
419
...
423
424
425
426
427
428
429
430
431
432
433




434
435
436
437
438
439
440
441
...
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
...
810
811
812
813
814
815
816

817
# executables needed for testing
#
TESTPROGS = \
  testfixture$(EXE) \
  sqlite3$(EXE) \
  sqlite3_analyzer$(EXE) \
  sqldiff$(EXE)








# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	sqlite3.h libsqlite3.a sqlite3$(EXE)

libsqlite3.a:	$(LIBOBJ)
................................................................................
sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h
	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE)                  \
		$(TOP)/src/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)

fuzzershell$(EXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
	$(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION\




		$(TOP)/tool/fuzzershell.c	sqlite3.c $(TLIBS) $(THREADLIB)

mptester$(EXE):	sqlite3.c $(TOP)/mptest/mptest.c
	$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
		$(TLIBS) $(THREADLIB)

MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
................................................................................
	-DSQLITE_ENABLE_FTS3=1                                               \
		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c       \
		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)

fulltest:	$(TESTPROGS) fuzztest
	./testfixture$(EXE) $(TOP)/test/all.test

soaktest:	$(TESTPROGS) fuzzoomtest
	./testfixture$(EXE) $(TOP)/test/all.test -soak=1

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

queryplantest:	testfixture$(EXE) sqlite3$(EXE)
	./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner

fuzztest:	fuzzershell$(EXE)
	./fuzzershell$(EXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt

fuzzoomtest:	fuzzershell$(EXE)
	./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt --oom

test:	$(TESTPROGS) fuzztest
	./testfixture$(EXE) $(TOP)/test/veryquick.test

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

# 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) fuzzershell$(EXE)
	./testfixture$(EXE) $(TOP)/test/main.test

# 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    \
................................................................................
	rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c
	rm -f sqlite3rc.h
	rm -f shell.c sqlite3ext.h
	rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
	rm -f sqlite-*-output.vsix
	rm -f mptester mptester.exe
	rm -f fuzzershell fuzzershell.exe

	rm -f sqldiff sqldiff.exe







>
>
>
>
>
>
>







 







|



>
>
>
>
|







 







|








|
|
<
<
<







|
|






|







 







>

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
...
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
...
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
...
818
819
820
821
822
823
824
825
826
# executables needed for testing
#
TESTPROGS = \
  testfixture$(EXE) \
  sqlite3$(EXE) \
  sqlite3_analyzer$(EXE) \
  sqldiff$(EXE)

# Databases containing fuzzer test cases
#
FUZZDATA = \
  $(TOP)/test/fuzzdata1.db \
  $(TOP)/test/fuzzdata2.db \
  $(TOP)/test/fuzzdata3.db

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	sqlite3.h libsqlite3.a sqlite3$(EXE)

libsqlite3.a:	$(LIBOBJ)
................................................................................
sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h
	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE)                  \
		$(TOP)/src/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)

fuzzershell$(EXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
	$(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION\
		$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) $(THREADLIB)

fuzzcheck$(EXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
	$(TCCX) -o fuzzcheck$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION\
		$(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS) $(THREADLIB)

mptester$(EXE):	sqlite3.c $(TOP)/mptest/mptest.c
	$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
		$(TLIBS) $(THREADLIB)

MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
................................................................................
	-DSQLITE_ENABLE_FTS3=1                                               \
		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c       \
		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)

fulltest:	$(TESTPROGS) fuzztest
	./testfixture$(EXE) $(TOP)/test/all.test

soaktest:	$(TESTPROGS)
	./testfixture$(EXE) $(TOP)/test/all.test -soak=1

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

queryplantest:	testfixture$(EXE) sqlite3$(EXE)
	./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner

fuzztest:	fuzzcheck$(EXE) $(FUZZDATA)
	./fuzzcheck$(EXE) $(FUZZDATA)




test:	$(TESTPROGS) fuzztest
	./testfixture$(EXE) $(TOP)/test/veryquick.test

# Run a test using valgrind.  This can take a really long time
# because valgrind is so much slower than a native machine.
#
valgrindtest:	$(TESTPROGS) fuzzcheck$(EXE) $(FUZZDATA)
	valgrind -v ./fuzzcheck$(EXE) --cell-size-check --quiet $(FUZZDATA)
	OMIT_MISUSE=1 valgrind -v ./testfixture$(EXE) $(TOP)/test/permutations.test valgrind

# 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

# 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    \
................................................................................
	rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c
	rm -f sqlite3rc.h
	rm -f shell.c sqlite3ext.h
	rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
	rm -f sqlite-*-output.vsix
	rm -f mptester mptester.exe
	rm -f fuzzershell fuzzershell.exe
	rm -f fuzzcheck fuzzcheck.exe
	rm -f sqldiff sqldiff.exe

Changes to src/btree.c.

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
....
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
....
1339
1340
1341
1342
1343
1344
1345



1346

1347
1348
1349
1350
1351
1352
1353
....
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
....
1552
1553
1554
1555
1556
1557
1558

1559
1560
1561
1562
1563
1564
1565
....
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
....
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
....
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
....
1832
1833
1834
1835
1836
1837
1838






























1839
1840
1841
1842
1843
1844
1845
....
3080
3081
3082
3083
3084
3085
3086

3087
3088

3089
3090
3091
3092
3093
3094
3095
....
3882
3883
3884
3885
3886
3887
3888



3889
3890
3891

3892
3893
3894
3895
3896
3897
3898
....
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
....
4941
4942
4943
4944
4945
4946
4947
4948





4949
4950
4951
4952








4953
4954
4955
4956
4957
4958
4959
4960
....
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
....
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
....
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
....
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490

5491
5492
5493
5494
5495
5496
5497
....
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
....
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599

5600
5601
5602
5603
5604
5605
5606
....
5744
5745
5746
5747
5748
5749
5750
5751


5752
5753
5754
5755
5756
5757
5758
....
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
....
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
....
6841
6842
6843
6844
6845
6846
6847








6848
6849
6850
6851
6852
6853
6854
....
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
....
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
....
7765
7766
7767
7768
7769
7770
7771

7772
7773
7774
7775
7776
7777
7778
  iCellLast = usableSize - 4;
  for(i=0; i<nCell; i++){
    u8 *pAddr;     /* The i-th cell pointer */
    pAddr = &data[cellOffset + i*2];
    pc = get2byte(pAddr);
    testcase( pc==iCellFirst );
    testcase( pc==iCellLast );
#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    /* These conditions have already been verified in btreeInitPage()
    ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined 

    */
    if( pc<iCellFirst || pc>iCellLast ){
      return SQLITE_CORRUPT_BKPT;
    }
#endif
    assert( pc>=iCellFirst && pc<=iCellLast );
    size = cellSizePtr(pPage, &src[pc]);
    cbrk -= size;
#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    if( cbrk<iCellFirst ){
      return SQLITE_CORRUPT_BKPT;
    }
#else
    if( cbrk<iCellFirst || pc+size>usableSize ){
      return SQLITE_CORRUPT_BKPT;
    }
#endif
    assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
    testcase( cbrk+size==usableSize );
    testcase( pc+size==usableSize );
    put2byte(pAddr, cbrk);
    if( temp==0 ){
      int x;
      if( cbrk==pc ) continue;
................................................................................
          if( pbDefrag ) *pbDefrag = 1;
          return 0;
        }
        /* Remove the slot from the free-list. Update the number of
        ** fragmented bytes within the page. */
        memcpy(&aData[iAddr], &aData[pc], 2);
        aData[hdr+7] += (u8)x;
      }else if( size+pc > usableSize ){
        *pRc = SQLITE_CORRUPT_BKPT;
        return 0;
      }else{
        /* The slot remains on the free-list. Reduce its size to account
         ** for the portion used by the new allocation. */
        put2byte(&aData[pc+2], x);
      }
................................................................................
  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 = get2byteNotZero(&data[hdr+5]);



  if( gap>top ) return SQLITE_CORRUPT_BKPT;


  /* If there is enough space between gap and top for one more cell pointer
  ** array entry offset, and if the freelist is not empty, then search the
  ** freelist looking for a free slot big enough to satisfy the request.
  */
  testcase( gap+2==top );
  testcase( gap+1==top );
................................................................................
  u16 iOrigSize = iSize;                /* Original value of iSize */
  u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
  u32 iEnd = iStart + iSize;            /* First byte past the iStart buffer */
  unsigned char *data = pPage->aData;   /* Page content */

  assert( pPage->pBt!=0 );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
  assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( iSize>=4 );   /* Minimum cell size is 4 */
  assert( iStart<=iLast );

  /* Overwrite deleted information with zeros when the secure_delete
  ** option is enabled */
................................................................................
** SQLITE_CORRUPT.  Note that a return of SQLITE_OK does not
** guarantee that the page is well-formed.  It only shows that
** we failed to detect any corruption.
*/
static int btreeInitPage(MemPage *pPage){

  assert( pPage->pBt!=0 );

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

  if( !pPage->isInit ){
    u16 pc;            /* Address of a freeblock within pPage->aData[] */
................................................................................
    **
    ** The following block of code checks early to see if a cell extends
    ** past the end of a page boundary and causes SQLITE_CORRUPT to be 
    ** returned if it does.
    */
    iCellFirst = cellOffset + 2*pPage->nCell;
    iCellLast = usableSize - 4;
#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    {
      int i;            /* Index into the cell pointer array */
      int sz;           /* Size of a cell */

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

    /* Compute the total free space on the page
    ** 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 */
................................................................................
  pPage->pgno = pgno;
  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
  return pPage; 
}

/*
** Get a page from the pager.  Initialize the MemPage.pBt and
** MemPage.aData elements if needed.
**
** If the noContent flag is set, it means that we do not care about
** the content of the page at this time.  So do not go to the disk
** to fetch the content.  Just fill in the content with zeros for now.
** If in the future we call sqlite3PagerWrite() on this page, that
** means we have started to be concerned about content and the disk
** read should occur at that point.
*/
static int btreeGetPage(
  BtShared *pBt,       /* The btree */
................................................................................
    assert( pPage->pDbPage!=0 );
    assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
    assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
    assert( sqlite3_mutex_held(pPage->pBt->mutex) );
    sqlite3PagerUnrefNotNull(pPage->pDbPage);
  }
}































/*
** During a rollback, when the pager reloads information into the cache
** so that the cache is restored to its original state at the start of
** the transaction, for each page restored this routine is called.
**
** This routine needs to reset the extra data section at the end of the
................................................................................
      return SQLITE_CORRUPT_BKPT;
    }
    put4byte(pPage->aData, iTo);
  }else{
    u8 isInitOrig = pPage->isInit;
    int i;
    int nCell;


    btreeInitPage(pPage);

    nCell = pPage->nCell;

    for(i=0; i<nCell; i++){
      u8 *pCell = findCell(pPage, i);
      if( eType==PTRMAP_OVERFLOW1 ){
        CellInfo info;
        btreeParseCellPtr(pPage, pCell, &info);
................................................................................
  Btree *p,                                   /* The btree */
  int iTable,                                 /* Root page of table to open */
  int wrFlag,                                 /* 1 to write. 0 read-only */
  struct KeyInfo *pKeyInfo,                   /* First arg to xCompare() */
  BtCursor *pCur                              /* Write new cursor here */
){
  int rc;



  sqlite3BtreeEnter(p);
  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
................................................................................
          }
        }
        assert( lwr+upr>=0 );
        idx = (lwr+upr)>>1;  /* idx = (lwr+upr)/2; */
      }
    }else{
      for(;;){
        int nCell;
        pCell = findCell(pPage, idx) + pPage->childPtrSize;

        /* The maximum supported page-size is 65536 bytes. This means that
        ** the maximum number of record bytes stored on an index B-Tree
        ** page is less than 16384 bytes and may be stored as a 2-byte
        ** varint. This information is used to attempt to avoid parsing 
        ** the entire cell by checking for the cases where the record is 
................................................................................
          ** fits entirely on the main b-tree page.  */
          testcase( pCell+nCell+2==pPage->aDataEnd );
          c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
        }else{
          /* The record flows over onto one or more overflow pages. In
          ** this case the whole cell needs to be parsed, a buffer allocated
          ** and accessPayload() used to retrieve the record into the
          ** buffer before VdbeRecordCompare() can be called. */





          void *pCellKey;
          u8 * const pCellBody = pCell - pPage->childPtrSize;
          btreeParseCellPtr(pPage, pCellBody, &pCur->info);
          nCell = (int)pCur->info.nKey;








          pCellKey = sqlite3Malloc( nCell );
          if( pCellKey==0 ){
            rc = SQLITE_NOMEM;
            goto moveto_finish;
          }
          pCur->aiIdx[pCur->iPage] = (u16)idx;
          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2);
          if( rc ){
................................................................................
**
** The new page is marked as dirty.  (In other words, sqlite3PagerWrite()
** has already been called on the new page.)  The new page has also
** been referenced and the calling routine is responsible for calling
** sqlite3PagerUnref() on the new page when it is done.
**
** SQLITE_OK is returned on success.  Any other return value indicates
** an error.  *ppPage and *pPgno are undefined in the event of an error.
** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
**
** If the "nearby" parameter is not 0, then an effort is made to 
** locate a page close to the page number "nearby".  This can be used in an
** attempt to keep related pages close to each other in the database file,
** which in turn can make database access faster.
**
** If the eMode parameter is BTALLOC_EXACT and the nearby page exists
................................................................................
        ** the freelist is empty. */
        iTrunk = get4byte(&pPage1->aData[32]);
      }
      testcase( iTrunk==mxPage );
      if( iTrunk>mxPage ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }
      assert( pTrunk!=0 );
      assert( pTrunk->aData!=0 );
................................................................................
          MemPage *pNewTrunk;
          Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
          if( iNewTrunk>mxPage ){ 
            rc = SQLITE_CORRUPT_BKPT;
            goto end_allocate_page;
          }
          testcase( iNewTrunk==mxPage );
          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
          if( rc!=SQLITE_OK ){
            goto end_allocate_page;
          }
          rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
          if( rc!=SQLITE_OK ){
            releasePage(pNewTrunk);
            goto end_allocate_page;
................................................................................
          rc = sqlite3PagerWrite(pTrunk->pDbPage);
          if( rc ) goto end_allocate_page;
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);

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

    assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
    rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
    if( rc ) return rc;
    rc = sqlite3PagerWrite((*ppPage)->pDbPage);
    if( rc!=SQLITE_OK ){
      releasePage(*ppPage);

    }
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
  }

  assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );

end_allocate_page:
  releasePage(pTrunk);
  releasePage(pPrevTrunk);
  if( rc==SQLITE_OK ){
    if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
      releasePage(*ppPage);
      *ppPage = 0;
      return SQLITE_CORRUPT_BKPT;
    }
    (*ppPage)->isInit = 0;
  }else{
    *ppPage = 0;
  }
  assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) );
  return rc;
}

/*
** This function is used to add page iPage to the database file free-list. 
** It is assumed that the page is not already a part of the free-list.
**
................................................................................
  Pgno iTrunk = 0;                    /* Page number of free-list trunk page */ 
  MemPage *pPage1 = pBt->pPage1;      /* Local reference to page 1 */
  MemPage *pPage;                     /* Page being freed. May be NULL. */
  int rc;                             /* Return Code */
  int nFree;                          /* Initial number of pages on free-list */

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( iPage>1 );
  assert( !pMemPage || pMemPage->pgno==iPage );


  if( pMemPage ){
    pPage = pMemPage;
    sqlite3PagerRef(pPage->pDbPage);
  }else{
    pPage = btreePageLookup(pBt, iPage);
  }

................................................................................
  if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  assert( pBt->usableSize > 4 );
  ovflPageSize = pBt->usableSize - 4;
  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
  assert( ovflPgno==0 || nOvfl>0 );


  while( nOvfl-- ){
    Pgno iNext = 0;
    MemPage *pOvfl = 0;
    if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
      /* 0 is not a legal page number and page 1 cannot be an 
      ** overflow page. Therefore if ovflPgno<2 or past the end of the 
      ** file the database must be corrupt. */
................................................................................
  u8 *ptr;        /* Used to move bytes around within data[] */
  int rc;         /* The return code */
  int hdr;        /* Beginning of the header.  0 most pages.  100 page 1 */

  if( *pRC ) return;

  assert( idx>=0 && idx<pPage->nCell );
  assert( sz==cellSize(pPage, idx) );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  data = pPage->aData;
  ptr = &pPage->aCellIdx[2*idx];
  pc = get2byte(ptr);
  hdr = pPage->hdrOffset;
  testcase( pc==get2byte(&data[hdr+5]) );
................................................................................
      pCell = &pTmp[pCell - aData];
    }
    pData -= szCell[i];
    memcpy(pData, pCell, szCell[i]);
    put2byte(pCellptr, (pData - aData));
    pCellptr += 2;
    assert( szCell[i]==cellSizePtr(pPg, pCell) || CORRUPT_DB );
    testcase( szCell[i]!=cellSizePtr(pPg,pCell) );
  }

  /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
  pPg->nCell = nCell;
  pPg->nOverflow = 0;

  put2byte(&aData[hdr+1], 0);
................................................................................
  **       leafData:  1 if pPage holds key+data and pParent holds only keys.
  */
  leafCorrection = apOld[0]->leaf*4;
  leafData = apOld[0]->intKeyLeaf;
  for(i=0; i<nOld; i++){
    int limit;
    MemPage *pOld = apOld[i];









    limit = pOld->nCell+pOld->nOverflow;
    if( pOld->nOverflow>0 ){
      for(j=0; j<limit; j++){
        assert( nCell<nMaxCells );
        apCell[nCell] = findOverflowCell(pOld, j);
        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
................................................................................
        assert( leafCorrection==0 );
        assert( pOld->hdrOffset==0 );
        /* The right pointer of the child page pOld becomes the left
        ** pointer of the divider cell */
        memcpy(apCell[nCell], &pOld->aData[8], 4);
      }else{
        assert( leafCorrection==4 );
        if( szCell[nCell]<4 ){
          /* Do not allow any cells smaller than 4 bytes. If a smaller cell
          ** does exist, pad it with 0x00 bytes. */
          assert( szCell[nCell]==3 );
          assert( apCell[nCell]==&aSpace1[iSpace1-3] );
          aSpace1[iSpace1++] = 0x00;
          szCell[nCell] = 4;
        }
      }
      nCell++;
    }
  }

  /*
................................................................................
    nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0,
    nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0
  ));

  /*
  ** Allocate k new pages.  Reuse old pages where possible.
  */
  if( apOld[0]->pgno<=1 ){
    rc = SQLITE_CORRUPT_BKPT;
    goto balance_cleanup;
  }
  pageFlags = apOld[0]->aData[0];
  for(i=0; i<k; i++){
    MemPage *pNew;
    if( i<nOld ){
      pNew = apNew[i] = apOld[i];
      apOld[i] = 0;
      rc = sqlite3PagerWrite(pNew->pDbPage);
................................................................................
  if( !pPage->leaf ){
    MemPage *pLeaf = pCur->apPage[pCur->iPage];
    int nCell;
    Pgno n = pCur->apPage[iCellDepth+1]->pgno;
    unsigned char *pTmp;

    pCell = findCell(pLeaf, pLeaf->nCell-1);

    nCell = cellSizePtr(pLeaf, pCell);
    assert( MX_CELL_SIZE(pBt) >= nCell );
    pTmp = pBt->pTmpSpace;
    assert( pTmp!=0 );
    rc = sqlite3PagerWrite(pLeaf->pDbPage);
    insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
    dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);







<

<
>




<



<
<
<
<
<



<







 







|







 







>
>
>
|
>







 







|







 







>







 







|
<







 







<







 







|

|
|







 







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







 







>

|
>







 







>
>
>
|
|
|
>







 







|







 







|
>
>
>
>
>




>
>
>
>
>
>
>
>
|







 







|
<







 







|







 







|







 







|




>







 







|













|




>









<
|
<
<
<
<
|
<
<
<
<







 







|


>







 







|
>
>







 







|







 







|







 







>
>
>
>
>
>
>
>







 







|


|
|

|







 







<
<
<
<







 







>







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
....
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
....
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
....
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
....
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
....
1607
1608
1609
1610
1611
1612
1613
1614

1615
1616
1617
1618
1619
1620
1621
....
1627
1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
....
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
....
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
....
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
....
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
....
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
....
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
....
5283
5284
5285
5286
5287
5288
5289
5290

5291
5292
5293
5294
5295
5296
5297
....
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
....
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
....
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
....
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
....
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
....
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
....
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
....
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
....
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
....
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
....
7027
7028
7029
7030
7031
7032
7033




7034
7035
7036
7037
7038
7039
7040
....
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
  iCellLast = usableSize - 4;
  for(i=0; i<nCell; i++){
    u8 *pAddr;     /* The i-th cell pointer */
    pAddr = &data[cellOffset + i*2];
    pc = get2byte(pAddr);
    testcase( pc==iCellFirst );
    testcase( pc==iCellLast );

    /* These conditions have already been verified in btreeInitPage()

    ** if PRAGMA cell_size_check=ON.
    */
    if( pc<iCellFirst || pc>iCellLast ){
      return SQLITE_CORRUPT_BKPT;
    }

    assert( pc>=iCellFirst && pc<=iCellLast );
    size = cellSizePtr(pPage, &src[pc]);
    cbrk -= size;





    if( cbrk<iCellFirst || pc+size>usableSize ){
      return SQLITE_CORRUPT_BKPT;
    }

    assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
    testcase( cbrk+size==usableSize );
    testcase( pc+size==usableSize );
    put2byte(pAddr, cbrk);
    if( temp==0 ){
      int x;
      if( cbrk==pc ) continue;
................................................................................
          if( pbDefrag ) *pbDefrag = 1;
          return 0;
        }
        /* Remove the slot from the free-list. Update the number of
        ** fragmented bytes within the page. */
        memcpy(&aData[iAddr], &aData[pc], 2);
        aData[hdr+7] += (u8)x;
      }else if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){
        *pRc = SQLITE_CORRUPT_BKPT;
        return 0;
      }else{
        /* The slot remains on the free-list. Reduce its size to account
         ** for the portion used by the new allocation. */
        put2byte(&aData[pc+2], x);
      }
................................................................................
  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 = get2byteNotZero(&data[hdr+5]);
  if( gap>top || NEVER((u32)top>pPage->pBt->usableSize) ){
    /* The NEVER() is because a oversize "top" value will be blocked from
    ** reaching this point by btreeInitPage() or btreeGetUnusedPage() */
    return SQLITE_CORRUPT_BKPT;
  }

  /* If there is enough space between gap and top for one more cell pointer
  ** array entry offset, and if the freelist is not empty, then search the
  ** freelist looking for a free slot big enough to satisfy the request.
  */
  testcase( gap+2==top );
  testcase( gap+1==top );
................................................................................
  u16 iOrigSize = iSize;                /* Original value of iSize */
  u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
  u32 iEnd = iStart + iSize;            /* First byte past the iStart buffer */
  unsigned char *data = pPage->aData;   /* Page content */

  assert( pPage->pBt!=0 );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
  assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( iSize>=4 );   /* Minimum cell size is 4 */
  assert( iStart<=iLast );

  /* Overwrite deleted information with zeros when the secure_delete
  ** option is enabled */
................................................................................
** SQLITE_CORRUPT.  Note that a return of SQLITE_OK does not
** guarantee that the page is well-formed.  It only shows that
** we failed to detect any corruption.
*/
static int btreeInitPage(MemPage *pPage){

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

  if( !pPage->isInit ){
    u16 pc;            /* Address of a freeblock within pPage->aData[] */
................................................................................
    **
    ** The following block of code checks early to see if a cell extends
    ** past the end of a page boundary and causes SQLITE_CORRUPT to be 
    ** returned if it does.
    */
    iCellFirst = cellOffset + 2*pPage->nCell;
    iCellLast = usableSize - 4;
    if( pBt->db->flags & SQLITE_CellSizeCk ){

      int i;            /* Index into the cell pointer array */
      int sz;           /* Size of a cell */

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


    /* Compute the total free space on the page
    ** 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 */
................................................................................
  pPage->pgno = pgno;
  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
  return pPage; 
}

/*
** Get a page from the pager.  Initialize the MemPage.pBt and
** MemPage.aData elements if needed.  See also: btreeGetUnusedPage().
**
** If the PAGER_GET_NOCONTENT flag is set, it means that we do not care
** about the content of the page at this time.  So do not go to the disk
** to fetch the content.  Just fill in the content with zeros for now.
** If in the future we call sqlite3PagerWrite() on this page, that
** means we have started to be concerned about content and the disk
** read should occur at that point.
*/
static int btreeGetPage(
  BtShared *pBt,       /* The btree */
................................................................................
    assert( pPage->pDbPage!=0 );
    assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
    assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
    assert( sqlite3_mutex_held(pPage->pBt->mutex) );
    sqlite3PagerUnrefNotNull(pPage->pDbPage);
  }
}

/*
** Get an unused page.
**
** This works just like btreeGetPage() with the addition:
**
**   *  If the page is already in use for some other purpose, immediately
**      release it and return an SQLITE_CURRUPT error.
**   *  Make sure the isInit flag is clear
*/
static int btreeGetUnusedPage(
  BtShared *pBt,       /* The btree */
  Pgno pgno,           /* Number of the page to fetch */
  MemPage **ppPage,    /* Return the page in this parameter */
  int flags            /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
){
  int rc = btreeGetPage(pBt, pgno, ppPage, flags);
  if( rc==SQLITE_OK ){
    if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
      releasePage(*ppPage);
      *ppPage = 0;
      return SQLITE_CORRUPT_BKPT;
    }
    (*ppPage)->isInit = 0;
  }else{
    *ppPage = 0;
  }
  return rc;
}


/*
** During a rollback, when the pager reloads information into the cache
** so that the cache is restored to its original state at the start of
** the transaction, for each page restored this routine is called.
**
** This routine needs to reset the extra data section at the end of the
................................................................................
      return SQLITE_CORRUPT_BKPT;
    }
    put4byte(pPage->aData, iTo);
  }else{
    u8 isInitOrig = pPage->isInit;
    int i;
    int nCell;
    int rc;

    rc = btreeInitPage(pPage);
    if( rc ) return rc;
    nCell = pPage->nCell;

    for(i=0; i<nCell; i++){
      u8 *pCell = findCell(pPage, i);
      if( eType==PTRMAP_OVERFLOW1 ){
        CellInfo info;
        btreeParseCellPtr(pPage, pCell, &info);
................................................................................
  Btree *p,                                   /* The btree */
  int iTable,                                 /* Root page of table to open */
  int wrFlag,                                 /* 1 to write. 0 read-only */
  struct KeyInfo *pKeyInfo,                   /* First arg to xCompare() */
  BtCursor *pCur                              /* Write new cursor here */
){
  int rc;
  if( iTable<1 ){
    rc = SQLITE_CORRUPT_BKPT;
  }else{
    sqlite3BtreeEnter(p);
    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
................................................................................
          }
        }
        assert( lwr+upr>=0 );
        idx = (lwr+upr)>>1;  /* idx = (lwr+upr)/2; */
      }
    }else{
      for(;;){
        int nCell;  /* Size of the pCell cell in bytes */
        pCell = findCell(pPage, idx) + pPage->childPtrSize;

        /* The maximum supported page-size is 65536 bytes. This means that
        ** the maximum number of record bytes stored on an index B-Tree
        ** page is less than 16384 bytes and may be stored as a 2-byte
        ** varint. This information is used to attempt to avoid parsing 
        ** the entire cell by checking for the cases where the record is 
................................................................................
          ** fits entirely on the main b-tree page.  */
          testcase( pCell+nCell+2==pPage->aDataEnd );
          c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
        }else{
          /* The record flows over onto one or more overflow pages. In
          ** this case the whole cell needs to be parsed, a buffer allocated
          ** and accessPayload() used to retrieve the record into the
          ** buffer before VdbeRecordCompare() can be called. 
          **
          ** 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;
          btreeParseCellPtr(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 ){
            rc = SQLITE_CORRUPT_BKPT;
            goto moveto_finish;
          }
          pCellKey = sqlite3Malloc( nCell+18 );
          if( pCellKey==0 ){
            rc = SQLITE_NOMEM;
            goto moveto_finish;
          }
          pCur->aiIdx[pCur->iPage] = (u16)idx;
          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2);
          if( rc ){
................................................................................
**
** The new page is marked as dirty.  (In other words, sqlite3PagerWrite()
** has already been called on the new page.)  The new page has also
** been referenced and the calling routine is responsible for calling
** sqlite3PagerUnref() on the new page when it is done.
**
** SQLITE_OK is returned on success.  Any other return value indicates
** an error.  *ppPage is set to NULL in the event of an error.

**
** If the "nearby" parameter is not 0, then an effort is made to 
** locate a page close to the page number "nearby".  This can be used in an
** attempt to keep related pages close to each other in the database file,
** which in turn can make database access faster.
**
** If the eMode parameter is BTALLOC_EXACT and the nearby page exists
................................................................................
        ** the freelist is empty. */
        iTrunk = get4byte(&pPage1->aData[32]);
      }
      testcase( iTrunk==mxPage );
      if( iTrunk>mxPage ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }
      assert( pTrunk!=0 );
      assert( pTrunk->aData!=0 );
................................................................................
          MemPage *pNewTrunk;
          Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
          if( iNewTrunk>mxPage ){ 
            rc = SQLITE_CORRUPT_BKPT;
            goto end_allocate_page;
          }
          testcase( iNewTrunk==mxPage );
          rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0);
          if( rc!=SQLITE_OK ){
            goto end_allocate_page;
          }
          rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
          if( rc!=SQLITE_OK ){
            releasePage(pNewTrunk);
            goto end_allocate_page;
................................................................................
          rc = sqlite3PagerWrite(pTrunk->pDbPage);
          if( rc ) goto end_allocate_page;
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
          rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, noContent);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
              *ppPage = 0;
            }
          }
          searchList = 0;
        }
      }
      releasePage(pPrevTrunk);
      pPrevTrunk = 0;
................................................................................
      /* If *pPgno refers to a pointer-map page, allocate two new pages
      ** at the end of the file instead of one. The first allocated page
      ** becomes a new pointer-map page, the second is used by the caller.
      */
      MemPage *pPg = 0;
      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
      assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
      rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent);
      if( rc==SQLITE_OK ){
        rc = sqlite3PagerWrite(pPg->pDbPage);
        releasePage(pPg);
      }
      if( rc ) return rc;
      pBt->nPage++;
      if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; }
    }
#endif
    put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
    *pPgno = pBt->nPage;

    assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
    rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent);
    if( rc ) return rc;
    rc = sqlite3PagerWrite((*ppPage)->pDbPage);
    if( rc!=SQLITE_OK ){
      releasePage(*ppPage);
      *ppPage = 0;
    }
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
  }

  assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );

end_allocate_page:
  releasePage(pTrunk);
  releasePage(pPrevTrunk);

  assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 );




  assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 );




  return rc;
}

/*
** This function is used to add page iPage to the database file free-list. 
** It is assumed that the page is not already a part of the free-list.
**
................................................................................
  Pgno iTrunk = 0;                    /* Page number of free-list trunk page */ 
  MemPage *pPage1 = pBt->pPage1;      /* Local reference to page 1 */
  MemPage *pPage;                     /* Page being freed. May be NULL. */
  int rc;                             /* Return Code */
  int nFree;                          /* Initial number of pages on free-list */

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( CORRUPT_DB || iPage>1 );
  assert( !pMemPage || pMemPage->pgno==iPage );

  if( iPage<2 ) return SQLITE_CORRUPT_BKPT;
  if( pMemPage ){
    pPage = pMemPage;
    sqlite3PagerRef(pPage->pDbPage);
  }else{
    pPage = btreePageLookup(pBt, iPage);
  }

................................................................................
  if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  assert( pBt->usableSize > 4 );
  ovflPageSize = pBt->usableSize - 4;
  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
  assert( nOvfl>0 || 
    (CORRUPT_DB && (info.nPayload + ovflPageSize)<ovflPageSize)
  );
  while( nOvfl-- ){
    Pgno iNext = 0;
    MemPage *pOvfl = 0;
    if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
      /* 0 is not a legal page number and page 1 cannot be an 
      ** overflow page. Therefore if ovflPgno<2 or past the end of the 
      ** file the database must be corrupt. */
................................................................................
  u8 *ptr;        /* Used to move bytes around within data[] */
  int rc;         /* The return code */
  int hdr;        /* Beginning of the header.  0 most pages.  100 page 1 */

  if( *pRC ) return;

  assert( idx>=0 && idx<pPage->nCell );
  assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  data = pPage->aData;
  ptr = &pPage->aCellIdx[2*idx];
  pc = get2byte(ptr);
  hdr = pPage->hdrOffset;
  testcase( pc==get2byte(&data[hdr+5]) );
................................................................................
      pCell = &pTmp[pCell - aData];
    }
    pData -= szCell[i];
    memcpy(pData, pCell, szCell[i]);
    put2byte(pCellptr, (pData - aData));
    pCellptr += 2;
    assert( szCell[i]==cellSizePtr(pPg, pCell) || CORRUPT_DB );
    testcase( szCell[i]==cellSizePtr(pPg,pCell) );
  }

  /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
  pPg->nCell = nCell;
  pPg->nOverflow = 0;

  put2byte(&aData[hdr+1], 0);
................................................................................
  **       leafData:  1 if pPage holds key+data and pParent holds only keys.
  */
  leafCorrection = apOld[0]->leaf*4;
  leafData = apOld[0]->intKeyLeaf;
  for(i=0; i<nOld; i++){
    int limit;
    MemPage *pOld = apOld[i];

    /* 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;
    }

    limit = pOld->nCell+pOld->nOverflow;
    if( pOld->nOverflow>0 ){
      for(j=0; j<limit; j++){
        assert( nCell<nMaxCells );
        apCell[nCell] = findOverflowCell(pOld, j);
        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
................................................................................
        assert( leafCorrection==0 );
        assert( pOld->hdrOffset==0 );
        /* The right pointer of the child page pOld becomes the left
        ** pointer of the divider cell */
        memcpy(apCell[nCell], &pOld->aData[8], 4);
      }else{
        assert( leafCorrection==4 );
        while( szCell[nCell]<4 ){
          /* Do not allow any cells smaller than 4 bytes. If a smaller cell
          ** does exist, pad it with 0x00 bytes. */
          assert( szCell[nCell]==3 || CORRUPT_DB );
          assert( apCell[nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB );
          aSpace1[iSpace1++] = 0x00;
          szCell[nCell]++;
        }
      }
      nCell++;
    }
  }

  /*
................................................................................
    nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0,
    nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0
  ));

  /*
  ** Allocate k new pages.  Reuse old pages where possible.
  */




  pageFlags = apOld[0]->aData[0];
  for(i=0; i<k; i++){
    MemPage *pNew;
    if( i<nOld ){
      pNew = apNew[i] = apOld[i];
      apOld[i] = 0;
      rc = sqlite3PagerWrite(pNew->pDbPage);
................................................................................
  if( !pPage->leaf ){
    MemPage *pLeaf = pCur->apPage[pCur->iPage];
    int nCell;
    Pgno n = pCur->apPage[iCellDepth+1]->pgno;
    unsigned char *pTmp;

    pCell = findCell(pLeaf, pLeaf->nCell-1);
    if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
    nCell = cellSizePtr(pLeaf, pCell);
    assert( MX_CELL_SIZE(pBt) >= nCell );
    pTmp = pBt->pTmpSpace;
    assert( pTmp!=0 );
    rc = sqlite3PagerWrite(pLeaf->pDbPage);
    insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
    dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);

Changes to src/build.c.

1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
....
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
....
1706
1707
1708
1709
1710
1711
1712










1713
1714
1715
1716
1717
1718
1719
....
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
....
3246
3247
3248
3249
3250
3251
3252

3253
3254
3255
3256





3257
3258
3259
3260
3261
3262
3263
....
3289
3290
3291
3292
3293
3294
3295


3296
3297
3298
3299
3300
3301
3302
    if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{
    Vdbe *v = pParse->pVdbe;
    Index *p;
    if( v ) pParse->addrSkipPK = sqlite3VdbeAddOp0(v, OP_Noop);
    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
                           0, sortOrder, 0);
    if( p ){
      p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
      if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK);
    }
    pList = 0;
  }

primary_key_exit:
  sqlite3ExprListDelete(pParse->db, pList);
  return;
................................................................................
  ** created will become the PRIMARY KEY index.
  */
  if( pParse->addrCrTab ){
    assert( v );
    sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
  }

  /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
  ** table entry.
  */
  if( pParse->addrSkipPK ){
    assert( v );
    sqlite3VdbeGetOp(v, pParse->addrSkipPK)->opcode = OP_Goto;
  }

  /* 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;
    pList = sqlite3ExprListAppend(pParse, 0, 0);
    if( pList==0 ) return;
................................................................................
    assert( pParse->pNewTable==pTab );
    pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
    if( pPk==0 ) return;
    pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
    pTab->iPKey = -1;
  }else{
    pPk = sqlite3PrimaryKeyIndex(pTab);










    /*
    ** 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( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
................................................................................
      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);
    }else{
      p->tabFlags |= TF_WithoutRowid;
      convertToWithoutRowidTable(pParse, p);
    }
  }

  iDb = sqlite3SchemaToIndex(db, p->pSchema);

#ifndef SQLITE_OMIT_CHECK
................................................................................
    Vdbe *v;
    char *zStmt;
    int iMem = ++pParse->nMem;

    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto exit_create_index;



    /* Create the rootpage for the index
    */
    sqlite3BeginWriteOperation(pParse, 1, iDb);





    sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);

    /* Gather the complete text of the CREATE INDEX statement into
    ** the zStmt variable
    */
    if( pStart ){
      int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
................................................................................
    if( pTblName ){
      sqlite3RefillIndex(pParse, pIndex, iMem);
      sqlite3ChangeCookie(pParse, iDb);
      sqlite3VdbeAddParseSchemaOp(v, iDb,
         sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
      sqlite3VdbeAddOp1(v, OP_Expire, 0);
    }


  }

  /* 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.  







<

<




<







 







<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>







 







|







 







>

|
<
|
>
>
>
>
>







 







>
>







1321
1322
1323
1324
1325
1326
1327

1328

1329
1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
....
1678
1679
1680
1681
1682
1683
1684








1685
1686
1687
1688
1689
1690
1691
....
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
....
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
....
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254

3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
....
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
    if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{

    Index *p;

    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
                           0, sortOrder, 0);
    if( p ){
      p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;

    }
    pList = 0;
  }

primary_key_exit:
  sqlite3ExprListDelete(pParse->db, pList);
  return;
................................................................................
  ** created will become the PRIMARY KEY index.
  */
  if( pParse->addrCrTab ){
    assert( v );
    sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
  }









  /* 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;
    pList = sqlite3ExprListAppend(pParse, 0, 0);
    if( pList==0 ) return;
................................................................................
    assert( pParse->pNewTable==pTab );
    pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
    if( pPk==0 ) return;
    pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
    pTab->iPKey = -1;
  }else{
    pPk = sqlite3PrimaryKeyIndex(pTab);

    /* 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 ){
      assert( db->init.busy==0 );
      sqlite3VdbeGetOp(v, pPk->tnum)->opcode = OP_Goto;
    }

    /*
    ** 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( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
................................................................................
      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);
    }else{
      p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
      convertToWithoutRowidTable(pParse, p);
    }
  }

  iDb = sqlite3SchemaToIndex(db, p->pSchema);

#ifndef SQLITE_OMIT_CHECK
................................................................................
    Vdbe *v;
    char *zStmt;
    int iMem = ++pParse->nMem;

    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto exit_create_index;

    sqlite3BeginWriteOperation(pParse, 1, iDb);

    /* 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 = sqlite3VdbeAddOp0(v, OP_Noop);
    sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);

    /* Gather the complete text of the CREATE INDEX statement into
    ** the zStmt variable
    */
    if( pStart ){
      int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
................................................................................
    if( pTblName ){
      sqlite3RefillIndex(pParse, pIndex, iMem);
      sqlite3ChangeCookie(pParse, iDb);
      sqlite3VdbeAddParseSchemaOp(v, iDb,
         sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
      sqlite3VdbeAddOp1(v, OP_Expire, 0);
    }

    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.  

Changes to src/main.c.

2775
2776
2777
2778
2779
2780
2781



2782
2783
2784
2785
2786
2787
2788
                 | SQLITE_RecTriggers
#endif
#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
                 | SQLITE_ForeignKeys
#endif
#if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
                 | SQLITE_ReverseOrder



#endif
      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif








>
>
>







2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
                 | SQLITE_RecTriggers
#endif
#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
                 | SQLITE_ForeignKeys
#endif
#if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
                 | SQLITE_ReverseOrder
#endif
#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
                 | SQLITE_CellSizeCk
#endif
      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif

Changes to src/os_win.c.

3010
3011
3012
3013
3014
3015
3016






3017
3018
3019
3020
3021
3022
3023
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( pFile->locktype>=locktype ){
    OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
    return SQLITE_OK;
  }







  /* Make sure the locking sequence is correct
  */
  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );








>
>
>
>
>
>







3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( pFile->locktype>=locktype ){
    OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
    return SQLITE_OK;
  }

  /* Do not allow any kind of write-lock on a read-only database
  */
  if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){
    return SQLITE_IOERR_LOCK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );

Changes to src/pager.c.

3145
3146
3147
3148
3149
3150
3151
3152
3153

3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
  ** available from the WAL sub-system if the log file is empty or
  ** contains no valid committed transactions.
  */
  assert( pPager->eState==PAGER_OPEN );
  assert( pPager->eLock>=SHARED_LOCK );
  nPage = sqlite3WalDbsize(pPager->pWal);

  /* If the database size was not available from the WAL sub-system,
  ** determine it based on the size of the database file. If the size

  ** of the database file is not an integer multiple of the page-size,
  ** round down to the nearest page. Except, any file larger than 0
  ** bytes in size is considered to contain at least one page.
  */
  if( nPage==0 ){
    i64 n = 0;                    /* Size of db file in bytes */
    assert( isOpen(pPager->fd) || pPager->tempFile );
    if( isOpen(pPager->fd) ){
      int rc = sqlite3OsFileSize(pPager->fd, &n);
      if( rc!=SQLITE_OK ){







|
|
>
|
<
<







3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155


3156
3157
3158
3159
3160
3161
3162
  ** available from the WAL sub-system if the log file is empty or
  ** contains no valid committed transactions.
  */
  assert( pPager->eState==PAGER_OPEN );
  assert( pPager->eLock>=SHARED_LOCK );
  nPage = sqlite3WalDbsize(pPager->pWal);

  /* If the number of pages in the database is not available from the
  ** WAL sub-system, determine the page counte based on the size of
  ** the database file.  If the size of the database file is not an
  ** integer multiple of the page-size, round up the result.


  */
  if( nPage==0 ){
    i64 n = 0;                    /* Size of db file in bytes */
    assert( isOpen(pPager->fd) || pPager->tempFile );
    if( isOpen(pPager->fd) ){
      int rc = sqlite3OsFileSize(pPager->fd, &n);
      if( rc!=SQLITE_OK ){

Changes to src/parse.y.

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
...
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
  sqlite3EndTable(pParse,0,0,0,S);
  sqlite3SelectDelete(pParse->db, S);
}
%type table_options {u8}
table_options(A) ::= .    {A = 0;}
table_options(A) ::= WITHOUT nm(X). {
  if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){
    A = TF_WithoutRowid;
  }else{
    A = 0;
    sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
  }
}
columnlist ::= columnlist COMMA column.
columnlist ::= column.
................................................................................
}

// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
// present and false (0) if it is not.
//
%type distinct {u16}
distinct(A) ::= DISTINCT.   {A = SF_Distinct;}
distinct(A) ::= ALL.        {A = 0;}
distinct(A) ::= .           {A = 0;}

// selcollist is a list of expressions that are to become the return
// values of the SELECT statement.  The "*" in statements like
// "SELECT * FROM ..." is encoded as a special expression with an
// opcode of TK_ALL.
//
................................................................................
%endif  SQLITE_OMIT_CAST
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). {
  if( Y && Y->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
    sqlite3ErrorMsg(pParse, "too many arguments on function %T", &X);
  }
  A.pExpr = sqlite3ExprFunction(pParse, Y, &X);
  spanSet(&A,&X,&E);
  if( D && A.pExpr ){
    A.pExpr->flags |= EP_Distinct;
  }
}
expr(A) ::= id(X) LP STAR RP(E). {
  A.pExpr = sqlite3ExprFunction(pParse, 0, &X);
  spanSet(&A,&X,&E);
}







|







 







|







 







|







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
...
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
  sqlite3EndTable(pParse,0,0,0,S);
  sqlite3SelectDelete(pParse->db, S);
}
%type table_options {u8}
table_options(A) ::= .    {A = 0;}
table_options(A) ::= WITHOUT nm(X). {
  if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){
    A = TF_WithoutRowid | TF_NoVisibleRowid;
  }else{
    A = 0;
    sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
  }
}
columnlist ::= columnlist COMMA column.
columnlist ::= column.
................................................................................
}

// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
// present and false (0) if it is not.
//
%type distinct {u16}
distinct(A) ::= DISTINCT.   {A = SF_Distinct;}
distinct(A) ::= ALL.        {A = SF_All;}
distinct(A) ::= .           {A = 0;}

// selcollist is a list of expressions that are to become the return
// values of the SELECT statement.  The "*" in statements like
// "SELECT * FROM ..." is encoded as a special expression with an
// opcode of TK_ALL.
//
................................................................................
%endif  SQLITE_OMIT_CAST
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). {
  if( Y && Y->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
    sqlite3ErrorMsg(pParse, "too many arguments on function %T", &X);
  }
  A.pExpr = sqlite3ExprFunction(pParse, Y, &X);
  spanSet(&A,&X,&E);
  if( D==SF_Distinct && A.pExpr ){
    A.pExpr->flags |= EP_Distinct;
  }
}
expr(A) ::= id(X) LP STAR RP(E). {
  A.pExpr = sqlite3ExprFunction(pParse, 0, &X);
  spanSet(&A,&X,&E);
}

Changes to src/pragma.h.

95
96
97
98
99
100
101




102
103
104
105
106
107
108
...
452
453
454
455
456
457
458
459
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_CacheSpill },
#endif
  { /* zName:     */ "case_sensitive_like",
    /* ePragTyp:  */ PragTyp_CASE_SENSITIVE_LIKE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },




#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  { /* zName:     */ "checkpoint_fullfsync",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_CkptFullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
................................................................................
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  { /* zName:     */ "writable_schema",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
/* Number of pragmas: 59 on by default, 72 total. */







>
>
>
>







 







|
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
456
457
458
459
460
461
462
463
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_CacheSpill },
#endif
  { /* zName:     */ "case_sensitive_like",
    /* ePragTyp:  */ PragTyp_CASE_SENSITIVE_LIKE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },
  { /* zName:     */ "cell_size_check",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_CellSizeCk },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  { /* zName:     */ "checkpoint_fullfsync",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_CkptFullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
................................................................................
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  { /* zName:     */ "writable_schema",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
/* Number of pragmas: 60 on by default, 73 total. */

Changes to src/resolve.c.

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            if( iCol==pTab->iPKey ){
              iCol = -1;
            }
            break;
          }
        }
        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
          /* IMP: R-51414-32910 */
          /* IMP: R-44911-55124 */
          iCol = -1;
        }
        if( iCol<pTab->nCol ){
          cnt++;
          if( iCol<0 ){
................................................................................
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */

    /*
    ** Perhaps the name is a reference to the ROWID
    */
    if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
     && HasRowid(pMatch->pTab) ){
      cnt = 1;
      pExpr->iColumn = -1;     /* IMP: R-44911-55124 */
      pExpr->affinity = SQLITE_AFF_INTEGER;
    }

    /*
    ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z







|







 







|







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
          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 */
          /* IMP: R-44911-55124 */
          iCol = -1;
        }
        if( iCol<pTab->nCol ){
          cnt++;
          if( iCol<0 ){
................................................................................
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */

    /*
    ** Perhaps the name is a reference to the ROWID
    */
    if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
     && VisibleRowid(pMatch->pTab) ){
      cnt = 1;
      pExpr->iColumn = -1;     /* IMP: R-44911-55124 */
      pExpr->affinity = SQLITE_AFF_INTEGER;
    }

    /*
    ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z

Changes to src/select.c.

3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
....
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
....
4820
4821
4822
4823
4824
4825
4826

4827
4828
4829
4830
4831
4832
4833
    assert( pFrom->pTab==0 );
    pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ) return WRC_Abort;
    pTab->nRef = 1;
    pTab->zName = sqlite3DbStrDup(db, pCte->zName);
    pTab->iPKey = -1;
    pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
    pTab->tabFlags |= TF_Ephemeral;
    pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
    if( db->mallocFailed ) return SQLITE_NOMEM;
    assert( pFrom->pSelect );

    /* Check if this is a recursive CTE. */
    pSel = pFrom->pSelect;
    bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
................................................................................
    */
    struct ExprList_item *a = pEList->a;
    ExprList *pNew = 0;
    int flags = pParse->db->flags;
    int longNames = (flags & SQLITE_FullColNames)!=0
                      && (flags & SQLITE_ShortColNames)==0;

    /* When processing FROM-clause subqueries, it is always the case
    ** that full_column_names=OFF and short_column_names=ON.  The
    ** sqlite3ResultSetOfSelect() routine makes it so. */
    assert( (p->selFlags & SF_NestedFrom)==0
          || ((flags & SQLITE_FullColNames)==0 &&
              (flags & SQLITE_ShortColNames)!=0) );

    for(k=0; k<pEList->nExpr; k++){
      pE = a[k].pExpr;
      pRight = pE->pRight;
      assert( pE->op!=TK_DOT || pRight!=0 );
      if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
        /* This particular expression does not need to be expanded.
        */
................................................................................
      /* This subquery can be absorbed into its parent. */
      if( isAggSub ){
        isAgg = 1;
        p->selFlags |= SF_Aggregate;
      }
      i = -1;
    }else if( pTabList->nSrc==1

           && OptimizationEnabled(db, SQLITE_SubqCoroutine)
    ){
      /* 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;







|







 







<
<
<
<
<
<
<







 







>







3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
....
4232
4233
4234
4235
4236
4237
4238







4239
4240
4241
4242
4243
4244
4245
....
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
    assert( pFrom->pTab==0 );
    pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ) return WRC_Abort;
    pTab->nRef = 1;
    pTab->zName = sqlite3DbStrDup(db, pCte->zName);
    pTab->iPKey = -1;
    pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
    pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
    pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
    if( db->mallocFailed ) return SQLITE_NOMEM;
    assert( pFrom->pSelect );

    /* Check if this is a recursive CTE. */
    pSel = pFrom->pSelect;
    bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
................................................................................
    */
    struct ExprList_item *a = pEList->a;
    ExprList *pNew = 0;
    int flags = pParse->db->flags;
    int longNames = (flags & SQLITE_FullColNames)!=0
                      && (flags & SQLITE_ShortColNames)==0;








    for(k=0; k<pEList->nExpr; k++){
      pE = a[k].pExpr;
      pRight = pE->pRight;
      assert( pE->op!=TK_DOT || pRight!=0 );
      if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
        /* This particular expression does not need to be expanded.
        */
................................................................................
      /* This subquery can be absorbed into its parent. */
      if( isAggSub ){
        isAgg = 1;
        p->selFlags |= SF_Aggregate;
      }
      i = -1;
    }else if( pTabList->nSrc==1
           && (p->selFlags & SF_All)==0
           && OptimizationEnabled(db, SQLITE_SubqCoroutine)
    ){
      /* 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;

Changes to src/sqlite.h.in.

3396
3397
3398
3399
3400
3401
3402
3403


3404
3405
3406
3407
3408
3409
3410
....
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
....
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
** for the values it stores.  ^Values stored in sqlite3_value objects
** can be integers, floating point values, strings, BLOBs, or NULL.
**
** An sqlite3_value object may be either "protected" or "unprotected".
** Some interfaces require a protected sqlite3_value.  Other interfaces
** will accept either a protected or an unprotected sqlite3_value.
** Every interface that accepts sqlite3_value arguments specifies
** whether or not it requires a protected sqlite3_value.


**
** The terms "protected" and "unprotected" refer to whether or not
** a mutex is held.  An internal mutex is held for a protected
** sqlite3_value object but no mutex is held for an unprotected
** sqlite3_value object.  If SQLite is compiled to be single-threaded
** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
** or if SQLite is run in one of reduced mutex modes 
................................................................................
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
** object D and returns a pointer to that copy.  ^The [sqlite3_value] returned
** is a [protected sqlite3_value] object even if the input is not.
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
** memory allocation fails.
**
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
** previously obtained from [sqlite_value_dup()].  ^If V is a NULL pointer
** then sqlite3_value_free(V) is a harmless no-op.
*/
SQLITE_EXPERIMENTAL sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
SQLITE_EXPERIMENTAL void sqlite3_value_free(sqlite3_value*);

/*
** CAPI3REF: Obtain Aggregate Function Context
................................................................................
** when it has finished using that result.
** ^If the 4th parameter to the sqlite3_result_text* interfaces
** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
** then SQLite makes a copy of the result into space obtained from
** from [sqlite3_malloc()] before it returns.
**
** ^The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy the
** [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
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.







|
>
>







 







|







 







|







3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
....
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
....
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
** for the values it stores.  ^Values stored in sqlite3_value objects
** can be integers, floating point values, strings, BLOBs, or NULL.
**
** An sqlite3_value object may be either "protected" or "unprotected".
** Some interfaces require a protected sqlite3_value.  Other interfaces
** will accept either a protected or an unprotected sqlite3_value.
** Every interface that accepts sqlite3_value arguments specifies
** whether or not it requires a protected sqlite3_value.  The
** [sqlite3_value_dup()] interface can be used to construct a new 
** protected sqlite3_value from an unprotected sqlite3_value.
**
** The terms "protected" and "unprotected" refer to whether or not
** a mutex is held.  An internal mutex is held for a protected
** sqlite3_value object but no mutex is held for an unprotected
** sqlite3_value object.  If SQLite is compiled to be single-threaded
** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
** or if SQLite is run in one of reduced mutex modes 
................................................................................
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
** object D and returns a pointer to that copy.  ^The [sqlite3_value] returned
** is a [protected sqlite3_value] object even if the input is not.
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
** memory allocation fails.
**
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
** previously obtained from [sqlite3_value_dup()].  ^If V is a NULL pointer
** then sqlite3_value_free(V) is a harmless no-op.
*/
SQLITE_EXPERIMENTAL sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
SQLITE_EXPERIMENTAL void sqlite3_value_free(sqlite3_value*);

/*
** CAPI3REF: Obtain Aggregate Function Context
................................................................................
** when it has finished using that result.
** ^If the 4th parameter to the sqlite3_result_text* interfaces
** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
** then SQLite makes a copy of the result into space obtained from
** from [sqlite3_malloc()] before it returns.
**
** ^The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy 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
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.

Changes to src/sqliteInt.h.

1257
1258
1259
1260
1261
1262
1263

1264
1265
1266
1267
1268
1269
1270
....
1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652
1653
....
1657
1658
1659
1660
1661
1662
1663

1664
1665
1666
1667
1668
1669
1670
....
1815
1816
1817
1818
1819
1820
1821








1822
1823
1824
1825
1826
1827
1828
....
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
....
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
#define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
#define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
#define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_Vacuum         0x08000000  /* Currently in a VACUUM */



/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
................................................................................
** special handling during INSERT processing.
*/
#define TF_Readonly        0x01    /* Read-only system table */
#define TF_Ephemeral       0x02    /* An ephemeral table */
#define TF_HasPrimaryKey   0x04    /* Table has a primary key */
#define TF_Autoincrement   0x08    /* Integer primary key is autoincrement */
#define TF_Virtual         0x10    /* Is a virtual table */
#define TF_WithoutRowid    0x20    /* No rowid used. PRIMARY KEY is the key */

#define TF_OOOHidden       0x40    /* Out-of-Order hidden columns */


/*
** 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.
*/
................................................................................
#else
#  define IsVirtual(X)      0
#  define IsHiddenColumn(X) 0
#endif

/* Does the table have a rowid */
#define HasRowid(X)     (((X)->tabFlags & TF_WithoutRowid)==0)


/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
** key.  The "to" table is the table that is named in the REFERENCES clause.
................................................................................
**
** The Index.onError field determines whether or not the indexed columns
** 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.








*/
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 */
................................................................................
};

/*
** Allowed values for Select.selFlags.  The "SF" prefix stands for
** "Select Flag".
*/
#define SF_Distinct        0x0001  /* Output should be DISTINCT */

#define SF_Resolved        0x0002  /* Identifiers have been resolved */
#define SF_Aggregate       0x0004  /* Contains aggregate functions */
#define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
#define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
#define SF_Compound        0x0040  /* Part of a compound query */
#define SF_Values          0x0080  /* Synthesized from VALUES clause */
#define SF_MultiValue      0x0100  /* Single VALUES term with multiple rows */
#define SF_NestedFrom      0x0200  /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert    0x0400  /* Need convertCompoundSelectToSubquery() */
#define SF_Recursive       0x0800  /* The recursive part of a recursive CTE */
#define SF_MinMaxAgg       0x1000  /* Aggregate containing min() or max() */

#define SF_Converted       0x2000  /* By convertCompoundSelectToSubquery() */


/*
** 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".
**
................................................................................
#endif
  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */

  /* Information used while coding trigger programs. */
  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  int addrCrTab;       /* Address of OP_CreateTable opcode on CREATE TABLE */
  int addrSkipPK;      /* Address of instruction to skip PRIMARY KEY index */
  u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
  u32 oldmask;         /* Mask of old.* columns referenced */
  u32 newmask;         /* Mask of new.* columns referenced */
  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
  u8 disableTriggers;  /* True to disable triggers */








>







 







|
>
|







 







>







 







>
>
>
>
>
>
>
>







 







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

>
|







 







<







1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
....
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
....
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
....
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
....
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
....
2655
2656
2657
2658
2659
2660
2661

2662
2663
2664
2665
2666
2667
2668
#define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
#define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
#define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_Vacuum         0x08000000  /* Currently in a VACUUM */
#define SQLITE_CellSizeCk     0x10000000  /* Check btree cell sizes on load */


/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
................................................................................
** special handling during INSERT processing.
*/
#define TF_Readonly        0x01    /* Read-only system table */
#define TF_Ephemeral       0x02    /* An ephemeral table */
#define TF_HasPrimaryKey   0x04    /* Table has a primary key */
#define TF_Autoincrement   0x08    /* Integer primary key is autoincrement */
#define TF_Virtual         0x10    /* Is a virtual table */
#define TF_WithoutRowid    0x20    /* No rowid.  PRIMARY KEY is the key */
#define TF_NoVisibleRowid  0x40    /* No user-visible "rowid" column */
#define TF_OOOHidden       0x80    /* Out-of-Order hidden columns */


/*
** 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.
*/
................................................................................
#else
#  define IsVirtual(X)      0
#  define IsHiddenColumn(X) 0
#endif

/* Does the table have a rowid */
#define HasRowid(X)     (((X)->tabFlags & TF_WithoutRowid)==0)
#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)

/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
** key.  The "to" table is the table that is named in the REFERENCES clause.
................................................................................
**
** The Index.onError field determines whether or not the indexed columns
** 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_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 */
................................................................................
};

/*
** Allowed values for Select.selFlags.  The "SF" prefix stands for
** "Select Flag".
*/
#define SF_Distinct        0x0001  /* Output should be DISTINCT */
#define SF_All             0x0002  /* Includes the ALL keyword */
#define SF_Resolved        0x0004  /* Identifiers have been resolved */
#define SF_Aggregate       0x0008  /* Contains aggregate functions */
#define SF_UsesEphemeral   0x0010  /* Uses the OpenEphemeral opcode */
#define SF_Expanded        0x0020  /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo     0x0040  /* FROM subqueries have Table metadata */
#define SF_Compound        0x0080  /* Part of a compound query */
#define SF_Values          0x0100  /* Synthesized from VALUES clause */
#define SF_MultiValue      0x0200  /* Single VALUES term with multiple rows */
#define SF_NestedFrom      0x0400  /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert    0x0800  /* Need convertCompoundSelectToSubquery() */

#define SF_MinMaxAgg       0x1000  /* Aggregate containing min() or max() */
#define SF_Recursive       0x2000  /* The recursive part of a recursive CTE */
#define SF_Converted       0x4000  /* By convertCompoundSelectToSubquery() */


/*
** 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".
**
................................................................................
#endif
  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */

  /* Information used while coding trigger programs. */
  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  int addrCrTab;       /* Address of OP_CreateTable opcode on CREATE TABLE */

  u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
  u32 oldmask;         /* Mask of old.* columns referenced */
  u32 newmask;         /* Mask of new.* columns referenced */
  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
  u8 disableTriggers;  /* True to disable triggers */

Changes to src/tokenize.c.

446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
        }
        break;
      }
    }
  }
abort_parse:
  assert( nErr==0 );
  if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){

    if( lastTokenParsed!=TK_SEMI ){
      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
      pParse->zTail = &zSql[i];
    }
    if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
      sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
    }







|
>







446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
        }
        break;
      }
    }
  }
abort_parse:
  assert( nErr==0 );
  if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
    assert( zSql[i]==0 );
    if( lastTokenParsed!=TK_SEMI ){
      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
      pParse->zTail = &zSql[i];
    }
    if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
      sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
    }

Changes to src/vdbeaux.c.

3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
....
3675
3676
3677
3678
3679
3680
3681
3682




3683
3684
3685
3686
3687
3688
3689
  do{
    u32 serial_type;

    /* RHS is an integer */
    if( pRhs->flags & MEM_Int ){
      serial_type = aKey1[idx1];
      testcase( serial_type==12 );
      if( serial_type>=12 ){
        rc = +1;
      }else if( serial_type==0 ){
        rc = -1;
      }else if( serial_type==7 ){
        double rhs = (double)pRhs->u.i;
        sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
        if( mem1.u.r<rhs ){
................................................................................
        }
      }
    }

    /* RHS is real */
    else if( pRhs->flags & MEM_Real ){
      serial_type = aKey1[idx1];
      if( serial_type>=12 ){




        rc = +1;
      }else if( serial_type==0 ){
        rc = -1;
      }else{
        double rhs = pRhs->u.r;
        double lhs;
        sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);







|







 







|
>
>
>
>







3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
....
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
  do{
    u32 serial_type;

    /* RHS is an integer */
    if( pRhs->flags & MEM_Int ){
      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 ){
        double rhs = (double)pRhs->u.i;
        sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
        if( mem1.u.r<rhs ){
................................................................................
        }
      }
    }

    /* RHS is real */
    else if( pRhs->flags & MEM_Real ){
      serial_type = aKey1[idx1];
      if( serial_type>=10 ){
        /* Serial types 12 or greater are strings and blobs (greater than
        ** numbers). Types 10 and 11 are currently "reserved for future 
        ** use", so it doesn't really matter what the results of comparing
        ** them to numberic values are.  */
        rc = +1;
      }else if( serial_type==0 ){
        rc = -1;
      }else{
        double rhs = pRhs->u.r;
        double lhs;
        sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);

Changes to src/where.c.

1655
1656
1657
1658
1659
1660
1661






























1662
1663
1664
1665
1666
1667
1668
....
1758
1759
1760
1761
1762
1763
1764

1765
1766
1767
1768
1769
1770
1771
....
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
....
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
....
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

/*
** Estimate the logarithm of the input value to base 2.
*/
static LogEst estLog(LogEst N){
  return N<=10 ? 0 : sqlite3LogEst(N) - 33;
}































/*
** 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.
*/
................................................................................
  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 */


  /* 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 );
  addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);

................................................................................
  pLevel->iIdxCur = pParse->nTab++;
  sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
  sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  VdbeComment((v, "for %s", pTable->zName));

  /* Fill the automatic index with content */
  sqlite3ExprCachePush(pParse);








  addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);

  if( pPartial ){
    iContinue = sqlite3VdbeMakeLabel(v);
    sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
    pLoop->wsFlags |= WHERE_PARTIALIDX;
  }
  regRecord = sqlite3GetTempReg(pParse);
  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);





  sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);

  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3ExprCachePop(pParse);
  
  /* Jump here when skipping the initialization */
  sqlite3VdbeJumpHere(v, addrInit);
................................................................................
    pProbe = &sPk;
  }
  rSize = pTab->nRowLogEst;
  rLogSize = estLog(rSize);

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet
   && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && pSrc->pIndex==0
   && !pSrc->viaCoroutine
   && !pSrc->notIndexed
   && HasRowid(pTab)
   && !pSrc->isCorrelated
   && !pSrc->isRecursive
  ){
    /* Generate auto-index WhereLoops */
    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
................................................................................
    Index *pIdx = 0;
    struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    pLoop = pLevel->pWLoop;

    /* For a co-routine, change all OP_Column references to the table of
    ** the co-routine into OP_SCopy of result contained in a register.
    ** OP_Rowid becomes OP_Null.
    */
    if( pTabItem->viaCoroutine && !db->mallocFailed ){
      last = sqlite3VdbeCurrentAddr(v);
      k = pLevel->addrBody;
      pOp = sqlite3VdbeGetOp(v, k);
      for(; k<last; k++, pOp++){
        if( pOp->p1!=pLevel->iTabCur ) continue;
        if( pOp->opcode==OP_Column ){
          pOp->opcode = OP_Copy;
          pOp->p1 = pOp->p2 + pTabItem->regResult;
          pOp->p2 = pOp->p3;
          pOp->p3 = 0;
        }else if( pOp->opcode==OP_Rowid ){
          pOp->opcode = OP_Null;
          pOp->p1 = 0;
          pOp->p3 = 0;
        }
      }
      continue;
    }

    /* Close all of the cursors that were opened by sqlite3WhereBegin.
    ** Except, do not close cursors that will be reused by the OR optimization
    ** (WHERE_OMIT_OPEN_CLOSE).  And do not close the OP_OpenWrite cursors
    ** created for the ONEPASS optimization.







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







 







>







 







>
>
>
>
>
>
>
>
|
>










>
>
>
>
>
|
>







 







|


|
<
|
|
|
|







 







|



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







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
....
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
....
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
....
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226

5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
....
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068

7069





7070








7071
7072
7073
7074
7075
7076
7077

/*
** Estimate the logarithm of the input value to base 2.
*/
static LogEst estLog(LogEst N){
  return N<=10 ? 0 : sqlite3LogEst(N) - 33;
}

/*
** 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, and OP_Rowid into OP_Null, when the table is being
** accessed via co-routine instead of via table lookup.
*/
static void translateColumnToCopy(
  Vdbe *v,            /* The VDBE containing code to translate */
  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 */
){
  VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
  int iEnd = sqlite3VdbeCurrentAddr(v);
  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 ){
      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.
*/
................................................................................
  WhereLoop *pLoop;           /* The Loop object */
  char *zNotUsed;             /* Extra space on the end of pIdx */
  Bitmask idxCols;            /* Bitmap of columns used for indexing */
  Bitmask extraCols;          /* Bitmap of additional columns */
  u8 sentWarning = 0;         /* True if a warnning has been issued */
  Expr *pPartial = 0;         /* Partial Index Expression */
  int iContinue = 0;          /* Jump here to skip excluded rows */
  struct SrcList_item *pTabItem;  /* FROM clause term being indexed */

  /* 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 );
  addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);

................................................................................
  pLevel->iIdxCur = pParse->nTab++;
  sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
  sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  VdbeComment((v, "for %s", pTable->zName));

  /* Fill the automatic index with content */
  sqlite3ExprCachePush(pParse);
  pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
  if( pTabItem->viaCoroutine ){
    int regYield = pTabItem->regReturn;
    sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
    addrTop =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
    VdbeCoverage(v);
    VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
  }else{
    addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
  }
  if( pPartial ){
    iContinue = sqlite3VdbeMakeLabel(v);
    sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
    pLoop->wsFlags |= WHERE_PARTIALIDX;
  }
  regRecord = sqlite3GetTempReg(pParse);
  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
  if( pTabItem->viaCoroutine ){
    translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
    pTabItem->viaCoroutine = 0;
  }else{
    sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
  }
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3ExprCachePop(pParse);
  
  /* Jump here when skipping the initialization */
  sqlite3VdbeJumpHere(v, addrInit);
................................................................................
    pProbe = &sPk;
  }
  rSize = pTab->nRowLogEst;
  rLogSize = estLog(rSize);

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet   /* Not part of an OR optimization */
   && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && pSrc->pIndex==0     /* Has no INDEXED BY clause */

   && !pSrc->notIndexed   /* Has no NOT INDEXED clause */
   && HasRowid(pTab)      /* Is not a WITHOUT ROWID table. (FIXME: Why not?) */
   && !pSrc->isCorrelated /* Not a correlated subquery */
   && !pSrc->isRecursive  /* Not a recursive common table expression. */
  ){
    /* Generate auto-index WhereLoops */
    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
................................................................................
    Index *pIdx = 0;
    struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    pLoop = pLevel->pWLoop;

    /* For a co-routine, change all OP_Column references to the table of
    ** the co-routine into OP_Copy of result contained in a register.
    ** OP_Rowid becomes OP_Null.
    */
    if( pTabItem->viaCoroutine && !db->mallocFailed ){

      translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,





                            pTabItem->regResult);








      continue;
    }

    /* Close all of the cursors that were opened by sqlite3WhereBegin.
    ** Except, do not close cursors that will be reused by the OR optimization
    ** (WHERE_OMIT_OPEN_CLOSE).  And do not close the OP_OpenWrite cursors
    ** created for the ONEPASS optimization.

Added test/autoindex5.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
# 2014-10-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 automatic index creation logic,
# and specifically ensuring that automatic indexes can be used with
# co-routine subqueries.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Schema is from the Debian security database
#
do_execsql_test autoindex5-1.0 {
  CREATE TABLE source_package_status
          (bug_name TEXT NOT NULL,
           package INTEGER NOT NULL,
           vulnerable INTEGER NOT NULL,
           urgency TEXT NOT NULL,
           PRIMARY KEY (bug_name, package));
  CREATE INDEX source_package_status_package
              ON source_package_status(package);
  
  CREATE TABLE source_packages
              (name TEXT NOT NULL,
              release TEXT NOT NULL,
              subrelease TEXT NOT NULL,
              archive TEXT NOT NULL,
              version TEXT NOT NULL,
              version_id INTEGER NOT NULL DEFAULT 0,
              PRIMARY KEY (name, release, subrelease, archive));
  
  CREATE TABLE bugs
          (name TEXT NOT NULL PRIMARY KEY,
           cve_status TEXT NOT NULL
               CHECK (cve_status IN
                      ('', 'CANDIDATE', 'ASSIGNED', 'RESERVED', 'REJECTED')),
           not_for_us INTEGER NOT NULL CHECK (not_for_us IN (0, 1)),
           description TEXT NOT NULL,
           release_date TEXT NOT NULL,
           source_file TEXT NOT NULL,
           source_line INTEGER NOT NULL);
  
  CREATE TABLE package_notes
          (id INTEGER NOT NULL PRIMARY KEY,
           bug_name TEXT NOT NULL,
           package TEXT NOT NULL,
           fixed_version TEXT
               CHECK (fixed_version IS NULL OR fixed_version <> ''),
           fixed_version_id INTEGER NOT NULL DEFAULT 0,
           release TEXT NOT NULL,
           package_kind TEXT NOT NULL DEFAULT 'unknown',
           urgency TEXT NOT NULL,
           bug_origin TEXT NOT NULL DEFAULT '');
  CREATE INDEX package_notes_package
              ON package_notes(package);
  CREATE UNIQUE INDEX package_notes_bug
              ON package_notes(bug_name, package, release);
  
  CREATE TABLE debian_bugs
          (bug INTEGER NOT NULL,
           note INTEGER NOT NULL,
           PRIMARY KEY (bug, note));
  
  
  CREATE VIEW debian_cve AS
              SELECT DISTINCT debian_bugs.bug, st.bug_name
              FROM package_notes, debian_bugs, source_package_status AS st
              WHERE package_notes.bug_name = st.bug_name
              AND debian_bugs.note = package_notes.id
              ORDER BY debian_bugs.bug;
} {}

# The following query should use an automatic index for the view
# in FROM clause of the subquery of the second result column.
#
do_execsql_test autoindex5-1.1 {
  EXPLAIN QUERY PLAN
  SELECT
    st.bug_name,
    (SELECT ALL debian_cve.bug FROM debian_cve
      WHERE debian_cve.bug_name = st.bug_name
      ORDER BY debian_cve.bug),
    sp.release
  FROM
     source_package_status AS st,
     source_packages AS sp,
     bugs
  WHERE
     sp.rowid = st.package
     AND st.bug_name = bugs.name
     AND ( st.bug_name LIKE 'CVE-%' OR st.bug_name LIKE 'TEMP-%' )
     AND ( sp.release = 'sid' OR sp.release = 'stretch' OR sp.release = 'jessie'
            OR sp.release = 'wheezy' OR sp.release = 'squeeze' )
  ORDER BY sp.name, st.bug_name, sp.release, sp.subrelease;
} {/SEARCH SUBQUERY 2 USING AUTOMATIC COVERING INDEX .bug_name=/}
    

finish_test

Changes to test/corruptI.test.

101
102
103
104
105
106
107



























































































































































108
   
   db close
   sqlite3 db test.db
   do_catchsql_test 3.3 {
     INSERT INTO t1 VALUES(9, 'klmnopqrst');
   } {1 {database disk image is malformed}}
} ;# end-if !defined(ENABLE_OVERSIZE_CELL_CHECK)



























































































































































finish_test







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

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
   
   db close
   sqlite3 db test.db
   do_catchsql_test 3.3 {
     INSERT INTO t1 VALUES(9, 'klmnopqrst');
   } {1 {database disk image is malformed}}
} ;# end-if !defined(ENABLE_OVERSIZE_CELL_CHECK)


#-------------------------------------------------------------------------
# Test that an assert() failure discovered by AFL corrupt database file
# testing has been fixed.
#
reset_db
do_execsql_test 4.0 {
  PRAGMA page_size = 65536;
  PRAGMA autovacuum = 0;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  INSERT INTO t1 VALUES(-1, 'abcdefghij');
  INSERT INTO t1 VALUES(0, 'abcdefghij');
}

set root [db one {SELECT rootpage FROM sqlite_master}]
set offset [expr ($root-1) * 65536]

ifcapable oversize_cell_check {
  set res {1 {database disk image is malformed}}
} else {
  set res {0 {}}
}
do_test 4.1 {
  db close
  hexio_write test.db [expr $offset + 8 + 2] 0000
  hexio_write test.db [expr $offset + 5] 0000
  sqlite3 db test.db
  catchsql { DELETE FROM t1 WHERE a=0 }
} $res


#-------------------------------------------------------------------------
# Database properties:
#
#   * Incremental vacuum mode.
#   * Database root table has a single leaf page.
#   * Free list consists of a single trunk page.
#
# The db is then corrupted by adding the root table leaf page as a free-list
# leaf page (so that it is referenced twice).
#
# Then, a new table is created. The new root page is the current free-list
# trunk. This means that the root table leaf page is made into the new
# free list trunk, which corrupts its header. Then, when the new entry is
# inserted into the root table, things would get chaotic.
#
reset_db
do_test 5.0 {
  execsql {
    PRAGMA page_size = 512;
    PRAGMA auto_vacuum = 2;
  }
  for {set i 3} {1} {incr i} {
    execsql "CREATE TABLE t${i}(x)"
    if {[db one {PRAGMA page_count}]>$i} break
  }
  set nPage [db one {PRAGMA page_count}]
  execsql {
    CREATE TABLE t100(x);
    DROP TABLE t100;
  }
} {}

do_execsql_test 5.1 { 
  PRAGMA page_count 
} [expr $nPage+1]

do_test 5.2 { 
  # The last page of the db is now the only leaf of the sqlite_master table.
  # Corrupt the db by adding it to the free-list as well (the second last
  # page of the db is the free-list trunk).
  db close
  hexio_write test.db [expr 512*($nPage-1)] [
    format "%.8X%.8X%.8X" 0 1 [expr $nPage+1]
  ]
} {12}

do_test 5.3 {
  sqlite3 db test.db
  catchsql { CREATE TABLE tx(x); }
} {1 {database disk image is malformed}}


#-------------------------------------------------------------------------
# Set the payload size of a cell to just less than 2^32 bytes (not
# possible in an uncorrupted db). Then try to delete the cell. At one
# point this led to an integer overflow that caused an assert() to fail.
#
reset_db
do_execsql_test 6.0 {
  PRAGMA page_size = 512;
  PRAGMA auto_vacuum=0;
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(zeroblob(300));
  INSERT INTO t1 VALUES(zeroblob(600));
} {}
do_test 6.1 {
  db close
  hexio_write test.db 616 EAFFFFFF0202
  sqlite3 db test.db
  breakpoint
  execsql { DELETE FROM t1 WHERE rowid=2 }
} {}

#-------------------------------------------------------------------------
# See what happens if the sqlite_master entry associated with a PRIMARY
# KEY or UNIQUE index is removed. 
#
reset_db
do_execsql_test 7.0 {
  PRAGMA auto_vacuum=0;
  CREATE TABLE t1(x PRIMARY KEY, y);
  INSERT INTO t1 VALUES('a', 'A');
  INSERT INTO t1 VALUES('b', 'A');
  INSERT INTO t1 VALUES('c', 'A');
  SELECT name FROM sqlite_master;
} {t1 sqlite_autoindex_t1_1}
do_execsql_test 7.1 {
  PRAGMA writable_schema = 1;
  DELETE FROM sqlite_master WHERE name = 'sqlite_autoindex_t1_1';
}
do_test 7.2 {
  db close
  sqlite3 db test.db
  catchsql { UPDATE t1 SET x='d' AND y='D' WHERE rowid = 2 }
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
# At one point an assert() would fail if attempt was made to free page 1.
#
reset_db
do_execsql_test 8.0 {
  PRAGMA auto_vacuum=0;
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(zeroblob(300));
  INSERT INTO t1 VALUES(zeroblob(300));
  INSERT INTO t1 VALUES(zeroblob(300));
  INSERT INTO t1 VALUES(zeroblob(300));
} {}

do_test 8.1 {
  db close
  hexio_write test.db [expr 1024 + 8] 00000001
  sqlite3 db test.db
  catchsql { DELETE FROM t1 }
} {1 {database disk image is malformed}}

do_test 8.2 {
  db close
  sqlite3 db test.db
  execsql { PRAGMA integrity_check }
} {/.*in database main.*/}


finish_test

Changes to test/fts3defer2.test.

117
118
119
120
121
122
123






124
125
126
127
128
129
130
  do_execsql_test 2.2.$tn.3 {
    SELECT mit(matchinfo(t2, 'x')) FROM t2 WHERE t2 MATCH 'g OR (g z)';
  } [list                                       \
    [list 1 2 2  1 2 2   1 54 54]               \
    [list 1 2 2  1 2 2   0 54 54]               \
  ]
  set sqlite_fts3_enable_parentheses 0






}

do_execsql_test 2.3.1 {
  CREATE VIRTUAL TABLE t3 USING fts4;
  INSERT INTO t3 VALUES('a b c d e f');
  INSERT INTO t3 VALUES('x b c d e f');
  INSERT INTO t3 VALUES('d e f a b c');







>
>
>
>
>
>







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  do_execsql_test 2.2.$tn.3 {
    SELECT mit(matchinfo(t2, 'x')) FROM t2 WHERE t2 MATCH 'g OR (g z)';
  } [list                                       \
    [list 1 2 2  1 2 2   1 54 54]               \
    [list 1 2 2  1 2 2   0 54 54]               \
  ]
  set sqlite_fts3_enable_parentheses 0

  do_execsql_test 2.2.$tn.4 {
    SELECT mit(matchinfo(t2, 'x')) FROM t2 WHERE t2 MATCH 'e "g z"';
  } [list                                       \
    [list 1 2 2  1 2 2]                         \
  ]
}

do_execsql_test 2.3.1 {
  CREATE VIRTUAL TABLE t3 USING fts4;
  INSERT INTO t3 VALUES('a b c d e f');
  INSERT INTO t3 VALUES('x b c d e f');
  INSERT INTO t3 VALUES('d e f a b c');

Added test/fuzzcheck.c.

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
/*
** 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 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
**     );
**     CREATE TABLE xsql(
**       sqlid INTEGER PRIMARY KEY,   -- SQL script id
**       sqltext TEXT                 -- Text of SQL statements to run
**     );
**
** For each database file in the DB table, the SQL text in the XSQL table
** is run against that database.  This program is looking for crashes,
** assertion faults, and/or memory leaks.  No attempt is made to verify
** the output.  The assumption is that either all of the database files
** or all of the SQL statements are malformed inputs, generated by a fuzzer,
** that need to be checked to make sure they do not present a security risk.
**
** This program also includes some command-line options to help with 
** creation and maintenance of the source content database.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include "sqlite3.h"

/*
** Files in the virtual file system.
*/
typedef struct VFile VFile;
struct VFile {
  char *zFilename;        /* Filename.  NULL for delete-on-close. From malloc() */
  int sz;                 /* Size of the file in bytes */
  int nRef;               /* Number of references to this file */
  unsigned char *a;       /* Content of the file.  From malloc() */
};
typedef struct VHandle VHandle;
struct VHandle {
  sqlite3_file base;      /* Base class.  Must be first */
  VFile *pVFile;          /* The underlying file */
};

/*
** The value of a database file template, or of an SQL script
*/
typedef struct Blob Blob;
struct Blob {
  Blob *pNext;            /* Next in a list */
  int id;                 /* Id of this Blob */
  int seq;                /* Sequence number */
  int sz;                 /* Size of this Blob in bytes */
  unsigned char a[1];     /* Blob content.  Extra space allocated as needed. */
};

/*
** Maximum number of files in the in-memory virtual filesystem.
*/
#define MX_FILE  10

/*
** Maximum allowed file size
*/
#define MX_FILE_SZ 10000000

/*
** All global variables are gathered into the "g" singleton.
*/
static struct GlobalVars {
  const char *zArgv0;              /* Name of program */
  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 */
  char zTestName[100];             /* Name of current test */
} g;

/*
** Print an error message and quit.
*/
static void fatalError(const char *zFormat, ...){
  va_list ap;
  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);
}

/*
** Reallocate memory.  Show and error and quit if unable.
*/
static void *safe_realloc(void *pOld, int szNew){
  void *pNew = realloc(pOld, szNew);
  if( pNew==0 ) fatalError("unable to realloc for %d bytes", szNew);
  return pNew;
}

/*
** Initialize the virtual file system.
*/
static void formatVfs(void){
  int i;
  for(i=0; i<MX_FILE; i++){
    g.aFile[i].sz = -1;
    g.aFile[i].zFilename = 0;
    g.aFile[i].a = 0;
    g.aFile[i].nRef = 0;
  }
}


/*
** Erase all information in the virtual file system.
*/
static void reformatVfs(void){
  int i;
  for(i=0; i<MX_FILE; i++){
    if( g.aFile[i].sz<0 ) continue;
    if( g.aFile[i].zFilename ){
      free(g.aFile[i].zFilename);
      g.aFile[i].zFilename = 0;
    }
    if( g.aFile[i].nRef>0 ){
      fatalError("file %d still open.  nRef=%d", i, g.aFile[i].nRef);
    }
    g.aFile[i].sz = -1;
    free(g.aFile[i].a);
    g.aFile[i].a = 0;
    g.aFile[i].nRef = 0;
  }
}

/*
** Find a VFile by name
*/
static VFile *findVFile(const char *zName){
  int i;
  if( zName==0 ) return 0;
  for(i=0; i<MX_FILE; i++){
    if( g.aFile[i].zFilename==0 ) continue;   
    if( strcmp(g.aFile[i].zFilename, zName)==0 ) return &g.aFile[i];
  }
  return 0;
}

/*
** Find a VFile by name.  Create it if it does not already exist and
** initialize it to the size and content given.
**
** Return NULL only if the filesystem is full.
*/
static VFile *createVFile(const char *zName, int sz, unsigned char *pData){
  VFile *pNew = findVFile(zName);
  int i;
  if( pNew ) return pNew;
  for(i=0; i<MX_FILE && g.aFile[i].sz>=0; i++){}
  if( i>=MX_FILE ) return 0;
  pNew = &g.aFile[i];
  if( zName ){
    pNew->zFilename = safe_realloc(0, strlen(zName)+1);
    memcpy(pNew->zFilename, zName, strlen(zName)+1);
  }else{
    pNew->zFilename = 0;
  }
  pNew->nRef = 0;
  pNew->sz = sz;
  pNew->a = safe_realloc(0, sz);
  if( sz>0 ) memcpy(pNew->a, pData, sz);
  return pNew;
}


/*
** Implementation of the "readfile(X)" SQL function.  The entire content
** of the file named X is read and returned as a BLOB.  NULL is returned
** if the file does not exist or is unreadable.
*/
static void readfileFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zName;
  FILE *in;
  long nIn;
  void *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 );
  if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
    sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
  }else{
    sqlite3_free(pBuf);
  }
  fclose(in);
}

/*
** Load a list of Blob objects from the database
*/
static void blobListLoadFromDb(
  sqlite3 *db,             /* Read from this database */
  const char *zSql,        /* Query used to extract the blobs */
  int onlyId,              /* Only load where id is this value */
  int *pN,                 /* OUT: Write number of blobs loaded here */
  Blob **ppList            /* OUT: Write the head of the blob list here */
){
  Blob head;
  Blob *p;
  sqlite3_stmt *pStmt;
  int n = 0;
  int rc;
  char *z2;

  if( onlyId>0 ){
    z2 = sqlite3_mprintf("%s WHERE rowid=%d", zSql, onlyId);
  }else{
    z2 = sqlite3_mprintf("%s", zSql);
  }
  rc = sqlite3_prepare_v2(db, z2, -1, &pStmt, 0);
  sqlite3_free(z2);
  if( rc ) fatalError("%s", sqlite3_errmsg(db));
  head.pNext = 0;
  p = &head;
  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    int sz = sqlite3_column_bytes(pStmt, 1);
    Blob *pNew = safe_realloc(0, sizeof(*pNew)+sz );
    pNew->id = sqlite3_column_int(pStmt, 0);
    pNew->sz = sz;
    pNew->seq = n++;
    pNew->pNext = 0;
    memcpy(pNew->a, sqlite3_column_blob(pStmt,1), sz);
    pNew->a[sz] = 0;
    p->pNext = pNew;
    p = pNew;
  }
  sqlite3_finalize(pStmt);
  *pN = n;
  *ppList = head.pNext;
}

/*
** Free a list of Blob objects
*/
static void blobListFree(Blob *p){
  Blob *pNext;
  while( p ){
    pNext = p->pNext;
    free(p);
    p = pNext;
  }
}


/* Return the current wall-clock time */
static sqlite3_int64 timeOfDay(void){
  static sqlite3_vfs *clockVfs = 0;
  sqlite3_int64 t;
  if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
  if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
    clockVfs->xCurrentTimeInt64(clockVfs, &t);
  }else{
    double r;
    clockVfs->xCurrentTime(clockVfs, &r);
    t = (sqlite3_int64)(r*86400000.0);
  }
  return t;
}

/* Methods for the VHandle object
*/
static int inmemClose(sqlite3_file *pFile){
  VHandle *p = (VHandle*)pFile;
  VFile *pVFile = p->pVFile;
  pVFile->nRef--;
  if( pVFile->nRef==0 && pVFile->zFilename==0 ){
    pVFile->sz = -1;
    free(pVFile->a);
    pVFile->a = 0;
  }
  return SQLITE_OK;
}
static int inmemRead(
  sqlite3_file *pFile,   /* Read from this open file */
  void *pData,           /* Store content in this buffer */
  int iAmt,              /* Bytes of content */
  sqlite3_int64 iOfst    /* Start reading here */
){
  VHandle *pHandle = (VHandle*)pFile;
  VFile *pVFile = pHandle->pVFile;
  if( iOfst<0 || iOfst>=pVFile->sz ){
    memset(pData, 0, iAmt);
    return SQLITE_IOERR_SHORT_READ;
  }
  if( iOfst+iAmt>pVFile->sz ){
    memset(pData, 0, iAmt);
    iAmt = (int)(pVFile->sz - iOfst);
    memcpy(pData, pVFile->a, iAmt);
    return SQLITE_IOERR_SHORT_READ;
  }
  memcpy(pData, pVFile->a + iOfst, iAmt);
  return SQLITE_OK;
}
static int inmemWrite(
  sqlite3_file *pFile,   /* Write to this file */
  const void *pData,     /* Content to write */
  int iAmt,              /* bytes to write */
  sqlite3_int64 iOfst    /* Start writing here */
){
  VHandle *pHandle = (VHandle*)pFile;
  VFile *pVFile = pHandle->pVFile;
  if( iOfst+iAmt > pVFile->sz ){
    if( iOfst+iAmt >= MX_FILE_SZ ){
      return SQLITE_FULL;
    }
    pVFile->a = safe_realloc(pVFile->a, (int)(iOfst+iAmt));
    if( iOfst > pVFile->sz ){
      memset(pVFile->a + pVFile->sz, 0, (int)(iOfst - pVFile->sz));
    }
    pVFile->sz = (int)(iOfst + iAmt);
  }
  memcpy(pVFile->a + iOfst, pData, iAmt);
  return SQLITE_OK;
}
static int inmemTruncate(sqlite3_file *pFile, sqlite3_int64 iSize){
  VHandle *pHandle = (VHandle*)pFile;
  VFile *pVFile = pHandle->pVFile;
  if( pVFile->sz>iSize && iSize>=0 ) pVFile->sz = (int)iSize;
  return SQLITE_OK;
}
static int inmemSync(sqlite3_file *pFile, int flags){
  return SQLITE_OK;
}
static int inmemFileSize(sqlite3_file *pFile, sqlite3_int64 *pSize){
  *pSize = ((VHandle*)pFile)->pVFile->sz;
  return SQLITE_OK;
}
static int inmemLock(sqlite3_file *pFile, int type){
  return SQLITE_OK;
}
static int inmemUnlock(sqlite3_file *pFile, int type){
  return SQLITE_OK;
}
static int inmemCheckReservedLock(sqlite3_file *pFile, int *pOut){
  *pOut = 0;
  return SQLITE_OK;
}
static int inmemFileControl(sqlite3_file *pFile, int op, void *pArg){
  return SQLITE_NOTFOUND;
}
static int inmemSectorSize(sqlite3_file *pFile){
  return 512;
}
static int inmemDeviceCharacteristics(sqlite3_file *pFile){
  return
      SQLITE_IOCAP_SAFE_APPEND |
      SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
      SQLITE_IOCAP_POWERSAFE_OVERWRITE;
}


/* Method table for VHandle
*/
static sqlite3_io_methods VHandleMethods = {
  /* iVersion  */    1,
  /* xClose    */    inmemClose,
  /* xRead     */    inmemRead,
  /* xWrite    */    inmemWrite,
  /* xTruncate */    inmemTruncate,
  /* xSync     */    inmemSync,
  /* xFileSize */    inmemFileSize,
  /* xLock     */    inmemLock,
  /* xUnlock   */    inmemUnlock,
  /* xCheck... */    inmemCheckReservedLock,
  /* xFileCtrl */    inmemFileControl,
  /* xSectorSz */    inmemSectorSize,
  /* xDevchar  */    inmemDeviceCharacteristics,
  /* xShmMap   */    0,
  /* xShmLock  */    0,
  /* xShmBarrier */  0,
  /* xShmUnmap */    0,
  /* xFetch    */    0,
  /* xUnfetch  */    0
};

/*
** Open a new file in the inmem VFS.  All files are anonymous and are
** delete-on-close.
*/
static int inmemOpen(
  sqlite3_vfs *pVfs,
  const char *zFilename,
  sqlite3_file *pFile,
  int openFlags,
  int *pOutFlags
){
  VFile *pVFile = createVFile(zFilename, 0, (unsigned char*)"");
  VHandle *pHandle = (VHandle*)pFile;
  if( pVFile==0 ){
    return SQLITE_FULL;
  }
  pHandle->pVFile = pVFile;
  pVFile->nRef++;
  pFile->pMethods = &VHandleMethods;
  if( pOutFlags ) *pOutFlags = openFlags;
  return SQLITE_OK;
}

/*
** Delete a file by name
*/
static int inmemDelete(
  sqlite3_vfs *pVfs,
  const char *zFilename,
  int syncdir
){
  VFile *pVFile = findVFile(zFilename);
  if( pVFile==0 ) return SQLITE_OK;
  if( pVFile->nRef==0 ){
    free(pVFile->zFilename);
    pVFile->zFilename = 0;
    pVFile->sz = -1;
    free(pVFile->a);
    pVFile->a = 0;
    return SQLITE_OK;
  }
  return SQLITE_IOERR_DELETE;
}

/* Check for the existance of a file
*/
static int inmemAccess(
  sqlite3_vfs *pVfs,
  const char *zFilename,
  int flags,
  int *pResOut
){
  VFile *pVFile = findVFile(zFilename);
  *pResOut =  pVFile!=0;
  return SQLITE_OK;
}

/* Get the canonical pathname for a file
*/
static int inmemFullPathname(
  sqlite3_vfs *pVfs,
  const char *zFilename,
  int nOut,
  char *zOut
){
  sqlite3_snprintf(nOut, zOut, "%s", zFilename);
  return SQLITE_OK;
}

/* GetLastError() is never used */
static int inmemGetLastError(sqlite3_vfs *pVfs, int n, char *z){
  return SQLITE_OK;
}

/*
** Register the VFS that reads from the g.aFile[] set of files.
*/
static void inmemVfsRegister(void){
  static sqlite3_vfs inmemVfs;
  sqlite3_vfs *pDefault = sqlite3_vfs_find(0);
  inmemVfs.iVersion = 1;
  inmemVfs.szOsFile = sizeof(VHandle);
  inmemVfs.mxPathname = 200;
  inmemVfs.zName = "inmem";
  inmemVfs.xOpen = inmemOpen;
  inmemVfs.xDelete = inmemDelete;
  inmemVfs.xAccess = inmemAccess;
  inmemVfs.xFullPathname = inmemFullPathname;
  inmemVfs.xRandomness = pDefault->xRandomness;
  inmemVfs.xSleep = pDefault->xSleep;
  inmemVfs.xCurrentTime = pDefault->xCurrentTime;
  inmemVfs.xGetLastError = inmemGetLastError;
  sqlite3_vfs_register(&inmemVfs, 0);
};

/*
** Allowed values for the runFlags parameter to runSql()
*/
#define SQL_TRACE  0x0001     /* Print each SQL statement as it is prepared */
#define SQL_OUTPUT 0x0002     /* Show the SQL output */

/*
** Run multiple commands of SQL.  Similar to sqlite3_exec(), but does not
** stop if an error is encountered.
*/
static void runSql(sqlite3 *db, const char *zSql, unsigned  runFlags){
  const char *zMore;
  sqlite3_stmt *pStmt;

  while( zSql && zSql[0] ){
    zMore = 0;
    pStmt = 0;
    sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zMore);
    if( zMore==zSql ) break;
    if( runFlags & SQL_TRACE ){
      const char *z = zSql;
      int n;
      while( z<zMore && isspace(z[0]) ) z++;
      n = (int)(zMore - z);
      while( n>0 && isspace(z[n-1]) ) n--;
      if( n==0 ) break;
      if( pStmt==0 ){
        printf("TRACE: %.*s (error: %s)\n", n, z, sqlite3_errmsg(db));
      }else{
        printf("TRACE: %.*s\n", n, z);
      }
    }
    zSql = zMore;
    if( pStmt ){
      if( (runFlags & SQL_OUTPUT)==0 ){
        while( SQLITE_ROW==sqlite3_step(pStmt) ){}
      }else{
        int nCol = -1;
        while( SQLITE_ROW==sqlite3_step(pStmt) ){
          int i;
          if( nCol<0 ){
            nCol = sqlite3_column_count(pStmt);
          }else if( nCol>0 ){
            printf("--------------------------------------------\n");
          }
          for(i=0; i<nCol; i++){
            int eType = sqlite3_column_type(pStmt,i);
            printf("%s = ", sqlite3_column_name(pStmt,i));
            switch( eType ){
              case SQLITE_NULL: {
                printf("NULL\n");
                break;
              }
              case SQLITE_INTEGER: {
                printf("INT %s\n", sqlite3_column_text(pStmt,i));
                break;
              }
              case SQLITE_FLOAT: {
                printf("FLOAT %s\n", sqlite3_column_text(pStmt,i));
                break;
              }
              case SQLITE_TEXT: {
                printf("TEXT [%s]\n", sqlite3_column_text(pStmt,i));
                break;
              }
              case SQLITE_BLOB: {
                printf("BLOB (%d bytes)\n", sqlite3_column_bytes(pStmt,i));
                break;
              }
            }
          }
        }
      }         
      sqlite3_finalize(pStmt);
    }
  }
}

/*
** Print sketchy documentation for this utility program
*/
static void showHelp(void){
  printf("Usage: %s [options] SOURCE-DB ?ARGS...?\n", g.zArgv0);
  printf(
"Read databases and SQL scripts from SOURCE-DB and execute each script against\n"
"each database, checking for crashes and memory leaks.\n"
"Options:\n"
"  --cell-size-check     Set the PRAGMA cell_size_check=ON\n"
"  --dbid N              Use only the database where dbid=N\n"
"  --help                Show this help text\n"    
"  -q                    Reduced output\n"
"  --quiet               Reduced output\n"
"  --load-sql ARGS...    Load SQL scripts fro files into SOURCE-DB\n"
"  --load-db ARGS...     Load template databases from files into SOURCE_DB\n"
"  -m TEXT               Add a description to the database\n"
"  --native-vfs          Use the native VFS for initially empty database files\n"
"  --result-trace        Show the results of each SQL command\n"
"  --sqlid N             Use only SQL where sqlid=N\n"
"  -v                    Increased output\n"
"  --verbose             Increased output\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 */
  char *zInsSql = 0;           /* SQL statement for --load-db or --load-sql */
  int iFirstInsArg = 0;        /* First argv[] to use for --load-db or --load-sql */
  sqlite3 *db = 0;             /* The open database connection */
  sqlite3_stmt *pStmt;         /* A prepared statement */
  int rc;                      /* Result code from SQLite interface calls */
  Blob *pSql;                  /* For looping over SQL scripts */
  Blob *pDb;                   /* For looping over template databases */
  int i;                       /* Loop index for the argv[] loop */
  int onlySqlid = -1;          /* --sqlid */
  int onlyDbid = -1;           /* --dbid */
  int nativeFlag = 0;          /* --native-vfs */
  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 environment variable */
  int cellSzCkFlag = 0;        /* --cell-size-check */

  iBegin = timeOfDay();
  g.zArgv0 = argv[0];
  zFailCode = getenv("TEST_FAILURE");
  for(i=1; i<argc; i++){
    const char *z = argv[i];
    if( z[0]=='-' ){
      z++;
      if( z[0]=='-' ) z++;
      if( strcmp(z,"cell-size-check")==0 ){
        cellSzCkFlag = 1;
      }else
      if( strcmp(z,"dbid")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        onlyDbid = atoi(argv[++i]);
      }else
      if( strcmp(z,"help")==0 ){
        showHelp();
        return 0;
      }else
      if( strcmp(z,"load-sql")==0 ){
        zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))";
        iFirstInsArg = i+1;
        break;
      }else
      if( strcmp(z,"load-db")==0 ){
        zInsSql = "INSERT INTO db(dbcontent) VALUES(readfile(?1))";
        iFirstInsArg = i+1;
        break;
      }else
      if( strcmp(z,"m")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        zMsg = argv[++i];
      }else
      if( strcmp(z,"native-vfs")==0 ){
        nativeFlag = 1;
      }else
      if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
        quietFlag = 1;
        verboseFlag = 0;
      }else
      if( strcmp(z,"result-trace")==0 ){
        runFlags |= SQL_OUTPUT;
      }else
      if( strcmp(z,"sqlid")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        onlySqlid = atoi(argv[++i]);
      }else
      if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
        quietFlag = 0;
        verboseFlag = 1;
        runFlags |= SQL_TRACE;
      }else
      {
        fatalError("unknown option: %s", argv[i]);
      }
    }else{
      nSrcDb++;
      azSrcDb = safe_realloc(azSrcDb, nSrcDb*sizeof(azSrcDb[0]));
      azSrcDb[nSrcDb-1] = argv[i];
    }
  }
  if( nSrcDb==0 ) fatalError("no source database specified");
  if( nSrcDb>1 ){
    if( zMsg ){
      fatalError("cannot change the description of more than one database");
    }
    if( zInsSql ){
      fatalError("cannot import into more than one database");
    }
  }

  /* Process each source database separately */
  for(iSrcDb=0; iSrcDb<nSrcDb; iSrcDb++){
    rc = sqlite3_open(azSrcDb[iSrcDb], &db);
    if( rc ){
      fatalError("cannot open source database %s - %s",
      azSrcDb[iSrcDb], sqlite3_errmsg(db));
    }
    rc = sqlite3_exec(db, 
       "CREATE TABLE IF NOT EXISTS db(\n"
       "  dbid INTEGER PRIMARY KEY, -- database id\n"
       "  dbcontent BLOB            -- database disk file image\n"
       ");\n"
       "CREATE TABLE IF NOT EXISTS xsql(\n"
       "  sqlid INTEGER PRIMARY KEY,   -- SQL script id\n"
       "  sqltext TEXT                 -- Text of SQL statements to run\n"
       ");"
       "CREATE TABLE IF NOT EXISTS readme(\n"
       "  msg TEXT -- Human-readable description of this file\n"
       ");", 0, 0, 0);
    if( rc ) fatalError("cannot create schema: %s", sqlite3_errmsg(db));
    if( zMsg ){
      char *zSql;
      zSql = sqlite3_mprintf(
               "DELETE FROM readme; INSERT INTO readme(msg) VALUES(%Q)", zMsg);
      rc = sqlite3_exec(db, zSql, 0, 0, 0);
      sqlite3_free(zSql);
      if( rc ) fatalError("cannot change description: %s", sqlite3_errmsg(db));
    }
    if( zInsSql ){
      sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
                              readfileFunc, 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");
      for(i=iFirstInsArg; i<argc; i++){
        sqlite3_bind_text(pStmt, 1, argv[i], -1, SQLITE_STATIC);
        sqlite3_step(pStmt);
        rc = sqlite3_reset(pStmt);
        if( rc ) fatalError("insert failed for %s", argv[i]);
      }
      sqlite3_finalize(pStmt);
      rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
      if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db));
      sqlite3_close(db);
      return 0;
    }
  
    /* Load all SQL script content and all initial database images from the
    ** source db
    */
    blobListLoadFromDb(db, "SELECT sqlid, sqltext FROM xsql", onlySqlid,
                           &g.nSql, &g.pFirstSql);
    if( g.nSql==0 ) fatalError("need at least one SQL script");
    blobListLoadFromDb(db, "SELECT dbid, dbcontent FROM db", onlyDbid,
                       &g.nDb, &g.pFirstDb);
    if( g.nDb==0 ){
      g.pFirstDb = safe_realloc(0, sizeof(Blob));
      memset(g.pFirstDb, 0, sizeof(Blob));
      g.pFirstDb->id = 1;
      g.pFirstDb->seq = 0;
      g.nDb = 1;
    }
  
    /* Print the description, if there is one */
    if( !quietFlag ){
      int i;
      zDbName = azSrcDb[iSrcDb];
      i = strlen(zDbName) - 1;
      while( i>0 && zDbName[i-1]!='/' && zDbName[i-1]!='\\' ){ i--; }
      zDbName += i;
      sqlite3_prepare_v2(db, "SELECT msg FROM readme", -1, &pStmt, 0);
      if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
        printf("%s: %s\n", zDbName, sqlite3_column_text(pStmt,0));
      }
      sqlite3_finalize(pStmt);
    }
  
    /* Close the source database.  Verify that no SQLite memory allocations are
    ** outstanding.
    */
    sqlite3_close(db);
    if( sqlite3_memory_used()>0 ){
      fatalError("SQLite has memory in use before the start of testing");
    }
  
    /* Register the in-memory virtual filesystem
    */
    formatVfs();
    inmemVfsRegister();
    
    /* Run a test using each SQL script against each database.
    */
    if( !verboseFlag && !quietFlag ) printf("%s:", zDbName);
    for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
      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( 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;
          }
        }
        createVFile("main.db", pDb->sz, pDb->a);
        openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE;
        if( nativeFlag && pDb->sz==0 ){
          openFlags |= SQLITE_OPEN_MEMORY;
          zVfs = 0;
        }
        rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
        if( rc ) fatalError("cannot open inmem database");
        if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
        runSql(db, (char*)pSql->a, runFlags);
        sqlite3_close(db);
        if( sqlite3_memory_used()>0 ) fatalError("memory leak");
        reformatVfs();
        nTest++;
        g.zTestName[0] = 0;

        /* Simulate an error if the TEST_FAILURE environment variable is "5".
        ** This is used to verify that automated test script really do spot
        ** errors that occur in this test program.
        */
        if( zFailCode ){
          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( !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);
    blobListFree(g.pFirstDb);
    reformatVfs();
 
  } /* End loop over all source databases */

  if( !quietFlag ){
    sqlite3_int64 iElapse = timeOfDay() - iBegin;
    printf("fuzzcheck: 0 errors out of %d tests in %d.%03d seconds\n"
           "SQLite %s %s\n",
           nTest, (int)(iElapse/1000), (int)(iElapse%1000),
           sqlite3_libversion(), sqlite3_sourceid());
  }
  free(azSrcDb);
  return 0;
}

Added test/fuzzdata1.db.

cannot compute difference between binary files

Deleted test/fuzzdata1.txt.

cannot compute difference between binary files

Added test/fuzzdata2.db.

cannot compute difference between binary files

Deleted test/fuzzdata2.txt.

cannot compute difference between binary files

Added test/fuzzdata3.db.

cannot compute difference between binary files

Changes to test/misc1.test.

689
690
691
692
693
694
695








696
  UPDATE sqlite_master SET sql='CREATE table y(a TEXT, a TEXT)';
  BEGIN;
  CREATE TABLE t2(y);
  ROLLBACK;
  DROP TABLE IF EXISTS t;
} {0 {}}









finish_test







>
>
>
>
>
>
>
>

689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
  UPDATE sqlite_master SET sql='CREATE table y(a TEXT, a TEXT)';
  BEGIN;
  CREATE TABLE t2(y);
  ROLLBACK;
  DROP TABLE IF EXISTS t;
} {0 {}}


# At one point, running this would read one byte passed the end of a 
# buffer, upsetting valgrind.
#
do_test misc1-24.0 {
  list [catch { sqlite3_prepare_v2 db ! -1 dummy } msg] $msg
} {1 {(1) unrecognized token: "!}}

finish_test

Deleted test/mkfuzzdata1.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
#!/usr/bin/tclsh
#
# Run this script in order to rebuild the fuzzdata1.txt file containing
# fuzzer data for the fuzzershell utility that is create by afl-fuzz.
#
# This script gathers all of the test cases identified by afl-fuzz and
# runs afl-cmin and afl-tmin over them all to try to generate a mimimum
# set of tests that cover all observed behavior.
# 
# Options:
#
#    --afl-bin DIR1             DIR1 contains the AFL binaries
#    --fuzzershell PATH         Full pathname of instrumented fuzzershell
#    --afl-data DIR3            DIR3 is the "-o" directory from afl-fuzz
#    -o FILE                    Write results into FILE
#
set AFLBIN {}
set FUZZERSHELL {}
set AFLDATA {}
set OUTFILE {}

proc usage {} {
  puts stderr "Usage: $::argv0 --afl-bin DIR --fuzzershell PATH\
                  --afl-data DIR -o FILE"
  exit 1
}
proc cmdlineerr {msg} {
  puts stderr $msg
  usage
}

for {set i 0} {$i<[llength $argv]} {incr i} {
  set x [lindex $argv $i]
  if {[string index $x 0]!="-"} {cmdlineerr "illegal argument: $x"}
  set x [string trimleft $x -]
  incr i
  if {$i>=[llength $argv]} {cmdlineerr "no argument on --$x"}
  set a [lindex $argv $i]
  switch -- $x {
     afl-bin {set AFLBIN $a}
     afl-data {set AFLDATA $a}
     fuzzershell {set FUZZERSHELL $a}
     o {set OUTFILE $a}
     default {cmdlineerr "unknown option: --$x"}
  }
}
proc checkarg {varname option} {
  set val [set ::$varname]
  if {$val==""} {cmdlineerr "required option missing: --$option"}
}
checkarg AFLBIN afl-bin
checkarg AFLDATA afl-data
checkarg FUZZERSHELL fuzzershell
checkarg OUTFILE o
proc checkexec {x} {
  if {![file exec $x]} {cmdlineerr "cannot find $x"}
}
checkexec $AFLBIN/afl-cmin
checkexec $AFLBIN/afl-tmin
checkexec $FUZZERSHELL
proc checkdir {x} {
  if {![file isdir $x]} {cmdlineerr "no such directory: $x"}
}
checkdir $AFLDATA/queue

proc progress {msg} {
  puts "******** $msg"
  flush stdout
}
progress "mkdir tmp1 tmp2"
file mkdir tmp1 tmp2
progress "copying test cases from $AFLDATA into tmp1..."
set n 0
foreach file [glob -nocomplain $AFLDATA/queue/id:*] {
  incr n
  file copy $file tmp1/$n
}
foreach file [glob -nocomplain $AFLDATA/crash*/id:*] {
  incr n
  file copy $file tmp1/$n
}
progress "total $n files copied."
progress "running: $AFLBIN/afl-cmin -i tmp1 -o tmp2 $FUZZERSHELL"
exec $AFLBIN/afl-cmin -i tmp1 -o tmp2 $FUZZERSHELL >&@ stdout
progress "afl-cmin complete."
#
# Experiments show that running afl-tmin is too slow for this application.
# And it doesn't really make the test cases that much smaller.  So let's
# just skip it.
#
# foreach file [glob tmp2/*] {
#   progress "$AFLBIN/afl-tmin -i $file -o tmp3/[file tail $file] $FUZZERSHELL"
#   exec $AFLBIN/afl-tmin -i $file -o tmp3/[file tail $file] \
#       $FUZZERSHELL >&@ stdout
# }
progress "generating final output into $OUTFILE"
set out [open $OUTFILE wb]
puts $out "# Test data for use with fuzzershell.  Automatically
# generated using $argv0.  This file contains binary data
#"
set n 0
foreach file [glob tmp2/*] {
  incr n
  puts -nonewline $out "/****<$n>****/"
  set in [open $file rb]
  puts -nonewline $out [read $in]
  close $in
}
close $out
progress "done.  $n test cases written to $OUTFILE"
progress "clean-up..."
file delete -force tmp1
progress "culled test cases left in the tmp2 directory"
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































Changes to test/permutations.test.

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

  # Exclude stmt.test, which expects sub-journals to use temporary files.
  stmt.test

  zerodamage.test

  # WAL mode is different.
  wal* tkt-2d1a5c67d.test backcompat.test e_wal*
}]

ifcapable mem3 {
  test_suite "memsys3" -description {
    Run tests using the allocator in mem3.c.
  } -files [test_set $::allquicktests -exclude {
    autovacuum.test           delete3.test              manydb.test







|







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

  # Exclude stmt.test, which expects sub-journals to use temporary files.
  stmt.test

  zerodamage.test

  # WAL mode is different.
  wal* tkt-2d1a5c67d.test backcompat.test e_wal* rowallock.test
}]

ifcapable mem3 {
  test_suite "memsys3" -description {
    Run tests using the allocator in mem3.c.
  } -files [test_set $::allquicktests -exclude {
    autovacuum.test           delete3.test              manydb.test

Changes to test/releasetest.tcl.

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
    "Update-Delete-Limit"     test
    "Extra-Robustness"        test
    "Device-Two"              test
    "No-lookaside"            test
    "Devkit"                  test
    "Sanitize"                {QUICKTEST_OMIT=func4.test,nan.test test}
    "Fast-One"                fuzzoomtest
    "Valgrind"                valgrindtest
    "Default"                 "threadtest fulltest"
    "Device-One"              fulltest
  }
  Linux-i686 {
    "Devkit"                  test
    "Have-Not"                test







|







221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
    "Update-Delete-Limit"     test
    "Extra-Robustness"        test
    "Device-Two"              test
    "No-lookaside"            test
    "Devkit"                  test
    "Sanitize"                {QUICKTEST_OMIT=func4.test,nan.test test}
    "Fast-One"                fuzztest
    "Valgrind"                valgrindtest
    "Default"                 "threadtest fulltest"
    "Device-One"              fulltest
  }
  Linux-i686 {
    "Devkit"                  test
    "Have-Not"                test

Added test/rowallock.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

# 2015-05-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 testing locks on read-only WAL-mode databases.

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set testprefix rowallock

do_multiclient_test tn {
  code2 { db2 close }
  code3 { db3 close }
  
  do_execsql_test 1.$tn.1 {
    PRAGMA page_size = 4096;
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(a, b);
    INSERT INTO t1 VALUES(1, 2), (3, 4);
    PRAGMA journal_mode = wal;
  } {wal}

  code1 { 
    db close 
    sqlite3 db test.db -readonly 1
  }

  do_execsql_test 1.$tn.2 {
    PRAGMA mmap_size = 1000000;
  } {1000000}
  do_execsql_test 1.$tn.2.1 {
    SELECT * FROM t1;
  } {1 2 3 4}

  do_catchsql_test 1.$tn.3 {
    INSERT INTO t1 VALUES(5, 6);
  } {1 {attempt to write a readonly database}}

  do_test 1.$tn.4 {
    code2 { sqlite3 db2 test.db }
    sql2 { INSERT INTO t1 VALUES(5, 6); }
    code2 { db2 close }
    file exists test.db-wal
  } {1}

  do_test 1.$tn.5 {
    sql1 { SELECT * FROM t2 }
    code1 { db close }
    file exists test.db-wal
  } {1}
}

finish_test

Changes to test/with1.test.

844
845
846
847
848
849
850
851









852
} {1 {table c has 1 values for 2 columns}}

# 2015-04-12
#
do_execsql_test 14.1 {
  WITH x AS (SELECT * FROM t) SELECT 0 EXCEPT SELECT 0 ORDER BY 1 COLLATE binary;
} {}










finish_test








>
>
>
>
>
>
>
>
>

844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
} {1 {table c has 1 values for 2 columns}}

# 2015-04-12
#
do_execsql_test 14.1 {
  WITH x AS (SELECT * FROM t) SELECT 0 EXCEPT SELECT 0 ORDER BY 1 COLLATE binary;
} {}

# 2015-05-27:  Do not allow rowid usage within a CTE
#
do_catchsql_test 15.1 {
  WITH RECURSIVE
    d(x) AS (VALUES(1) UNION ALL SELECT rowid+1 FROM d WHERE rowid<10)
  SELECT x FROM d;
} {1 {no such column: rowid}}


finish_test

Changes to test/without_rowid1.test.

272
273
274
275
276
277
278
279


280

















































281
  CREATE INDEX i46 ON t46(c);
}

foreach {tn cnt where eqp} $queries {
  do_execsql_test 5.7.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt
  do_eqp_test 5.7.$tn.2  "SELECT count(*) FROM t46 WHERE $where" $eqp
}



  

















































finish_test








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

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
  CREATE INDEX i46 ON t46(c);
}

foreach {tn cnt where eqp} $queries {
  do_execsql_test 5.7.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt
  do_eqp_test 5.7.$tn.2  "SELECT count(*) FROM t46 WHERE $where" $eqp
}

#-------------------------------------------------------------------------
# Check that redundant UNIQUE constraints do not cause a problem.
#
do_execsql_test 6.0 {
  CREATE TABLE t47(a, b UNIQUE PRIMARY KEY) WITHOUT ROWID;
  CREATE INDEX i47 ON t47(a);
  INSERT INTO t47 VALUES(1, 2);
  INSERT INTO t47 VALUES(2, 4);
  INSERT INTO t47 VALUES(3, 6);
  INSERT INTO t47 VALUES(4, 8);

  VACUUM;
  PRAGMA integrity_check;
  SELECT name FROM sqlite_master WHERE tbl_name = 't47';
} {ok t47 i47}

do_execsql_test 6.1 {
  CREATE TABLE t48(
    a UNIQUE UNIQUE, 
    b UNIQUE, 
    PRIMARY KEY(a), 
    UNIQUE(a)
  ) WITHOUT ROWID;
  INSERT INTO t48 VALUES('a', 'b'), ('c', 'd'), ('e', 'f');
  VACUUM;
  PRAGMA integrity_check;
  SELECT name FROM sqlite_master WHERE tbl_name = 't48';
} {
  ok  t48   sqlite_autoindex_t48_2
}

# 2015-05-28: CHECK constraints can refer to the rowid in a
# rowid table, but not in a WITHOUT ROWID table.
#
do_execsql_test 7.1 {
  CREATE TABLE t70a(
     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: 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}}

  
finish_test

Changes to tool/mkpragmatab.tcl.

132
133
134
135
136
137
138




139
140
141
142
143
144
145

  NAME: defer_foreign_keys
  TYPE: FLAG
  ARG:  SQLITE_DeferFKs
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)





  NAME: default_cache_size
  FLAG: NeedSchema
  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)

  NAME: page_size
  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)








>
>
>
>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

  NAME: defer_foreign_keys
  TYPE: FLAG
  ARG:  SQLITE_DeferFKs
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)

  NAME: cell_size_check
  TYPE: FLAG
  ARG:  SQLITE_CellSizeCk

  NAME: default_cache_size
  FLAG: NeedSchema
  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)

  NAME: page_size
  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)